From 5b9700b482eb81f77faa7fb6afc21c4259c16d80 Mon Sep 17 00:00:00 2001 From: Dominikus Nold Date: Sun, 8 Feb 2026 23:09:28 +0100 Subject: [PATCH] docs: add openspec change arch-06 manifest security --- .../.openspec.yaml | 2 + .../CHANGE_VALIDATION.md | 74 ++++++++++++ .../design.md | 99 ++++++++++++++++ .../proposal.md | 54 +++++++++ .../specs/module-lifecycle-management/spec.md | 28 +++++ .../specs/module-packages/spec.md | 35 ++++++ .../specs/module-security/spec.md | 51 +++++++++ .../tasks.md | 108 ++++++++++++++++++ 8 files changed, 451 insertions(+) create mode 100644 openspec/changes/arch-06-enhanced-manifest-security/.openspec.yaml create mode 100644 openspec/changes/arch-06-enhanced-manifest-security/CHANGE_VALIDATION.md create mode 100644 openspec/changes/arch-06-enhanced-manifest-security/design.md create mode 100644 openspec/changes/arch-06-enhanced-manifest-security/proposal.md create mode 100644 openspec/changes/arch-06-enhanced-manifest-security/specs/module-lifecycle-management/spec.md create mode 100644 openspec/changes/arch-06-enhanced-manifest-security/specs/module-packages/spec.md create mode 100644 openspec/changes/arch-06-enhanced-manifest-security/specs/module-security/spec.md create mode 100644 openspec/changes/arch-06-enhanced-manifest-security/tasks.md diff --git a/openspec/changes/arch-06-enhanced-manifest-security/.openspec.yaml b/openspec/changes/arch-06-enhanced-manifest-security/.openspec.yaml new file mode 100644 index 00000000..565fad56 --- /dev/null +++ b/openspec/changes/arch-06-enhanced-manifest-security/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-02-08 diff --git a/openspec/changes/arch-06-enhanced-manifest-security/CHANGE_VALIDATION.md b/openspec/changes/arch-06-enhanced-manifest-security/CHANGE_VALIDATION.md new file mode 100644 index 00000000..f8d49c20 --- /dev/null +++ b/openspec/changes/arch-06-enhanced-manifest-security/CHANGE_VALIDATION.md @@ -0,0 +1,74 @@ +# Change Validation Report: arch-06-enhanced-manifest-security + +**Validation Date**: 2026-02-08 +**Change Proposal**: [proposal.md](./proposal.md) +**Validation Method**: Dry-run dependency analysis and strict OpenSpec validation + +## Executive Summary + +- **Breaking Changes**: 0 detected (proposal is additive and policy-gated) +- **Primary Impact Areas**: module manifest parsing, module registration lifecycle, module install flow +- **Risk Level**: Medium (security controls affect module enable/install behavior) +- **Validation Result**: Pass + +## Interface/Contract Impact + +## New/extended interfaces + +- `ModulePackageMetadata` extensions for publisher/integrity/versioned dependencies +- New `crypto_validator` helper interface for checksum/signature checks +- Registration/install policy gate for unsigned modules + +## Compatibility assessment + +- Existing manifests remain compatible if new metadata fields are optional. +- Unsigned module behavior remains backward compatible when strict trust mode is not forced. +- No required signature changes to existing CLI command interfaces were introduced in proposal artifacts. + +## Dependent Code Analysis + +Search-based dependency scan identified direct coupling points that must be considered during implementation: + +- `src/specfact_cli/registry/module_packages.py` + - Current source of truth for `ModulePackageMetadata` + - Parsing logic for `module-package.yaml` and lifecycle validation +- `src/specfact_cli/registry/bootstrap.py` + - Calls `register_module_package_commands()`; trust checks must not break startup resilience +- `src/specfact_cli/modules/init/src/commands.py` + - Reads discovered packages; UX/messages may need updates for trust failures +- `src/specfact_cli/registry/module_state.py` + - Consumes dependency metadata; versioned dependency structures may affect expectations +- `tests/unit/specfact_cli/registry/test_module_packages.py` +- `tests/unit/specfact_cli/registry/test_module_dependencies.py` +- `tests/unit/specfact_cli/registry/test_version_constraints.py` +- `tests/unit/specfact_cli/registry/test_init_module_lifecycle_ux.py` + +## Notable implementation caveat + +The proposal references `src/specfact_cli/models/module_package.py`, but the current active metadata model is defined in `src/specfact_cli/registry/module_packages.py`. Implementation should either: + +1. Keep changes in `src/specfact_cli/registry/module_packages.py`, or +2. Introduce a new model module and refactor imports safely. + +This is a scope/placement consideration, not a breaking-change blocker. + +## Breaking Change Analysis + +No immediate breaking changes are required by this proposal if implemented as follows: + +- New manifest fields are optional with safe defaults. +- Trust enforcement defaults to checksum baseline + explicit strict policy for signature/unsigned handling. +- Failed trust checks remain module-local (skip/reject offending module) without crashing unrelated module registration. + +## OpenSpec Validation + +- Command: `openspec validate arch-06-enhanced-manifest-security --strict` +- Result: `Change 'arch-06-enhanced-manifest-security' is valid` + +## Recommendation + +Proceed to implementation with explicit test coverage for: + +- Legacy manifest parsing compatibility +- Trust failure isolation (one module fails, others continue) +- Unsigned-module policy behavior in strict and non-strict modes diff --git a/openspec/changes/arch-06-enhanced-manifest-security/design.md b/openspec/changes/arch-06-enhanced-manifest-security/design.md new file mode 100644 index 00000000..3cf3e440 --- /dev/null +++ b/openspec/changes/arch-06-enhanced-manifest-security/design.md @@ -0,0 +1,99 @@ +# Design: Enhanced Module Manifest Security and Integrity Validation + +## Context + +The marketplace decoupling roadmap identifies trust and integrity as the next critical step after bridge interoperability. Current module manifests provide compatibility/dependency metadata but do not provide cryptographic guarantees that a module artifact is authentic and untampered. + +Current gaps: + +- Manifest metadata has no publisher identity model and no integrity block. +- Installation paths do not enforce checksum/signature verification. +- Unsigned module acceptance is not explicitly policy-gated. + +## Goals / Non-Goals + +**Goals:** + +- Add publisher and integrity metadata to module package manifests. +- Add checksum and optional signature verification primitives. +- Enforce trust checks in module install/registration pipeline. +- Provide explicit policy switch for unsigned modules. +- Provide signing automation for official modules. + +**Non-Goals:** + +- Full marketplace registry service APIs (marketplace-01). +- Runtime sandboxing/permission isolation for module execution. +- External key-management service integration. + +## Decisions + +### Decision 1: Additive manifest model extension + +**Choice:** Extend `ModulePackageMetadata` with optional nested models: `PublisherInfo`, `IntegrityInfo`, and versioned dependency entries. + +**Rationale:** + +- Maintains backward compatibility for existing manifests. +- Creates clear typed contract for security metadata. +- Enables phased enforcement without breaking local/community modules. + +### Decision 2: Integrity verification stages + +**Choice:** Enforce verification in ordered stages: checksum first, signature second (if present and required by policy). + +**Rationale:** + +- Deterministic and fast tamper detection via checksum. +- Signature verification adds provenance guarantee when key material is available. +- Supports progressive rollout from checksum-only to strict signature enforcement. + +### Decision 3: Explicit unsigned-module policy gate + +**Choice:** Require explicit allow-unsigned configuration/flag to install unsigned modules in strict mode. + +**Rationale:** + +- Prevents accidental trust bypass. +- Keeps development ergonomics by allowing opt-in exceptions. + +### Decision 4: CI-based signing for official modules + +**Choice:** Introduce `scripts/sign-module.sh` and `.github/workflows/sign-modules.yml` for official module artifacts. + +**Rationale:** + +- Standardizes signature generation. +- Reduces manual operational drift. +- Improves traceability for release artifacts. + +## Risks / Trade-offs + +- **Risk:** Key distribution/rotation complexity. + - **Mitigation:** Document trust model and key retrieval path; keep key URL in manifest. +- **Risk:** Signature verification dependencies may vary by environment. + - **Mitigation:** Keep checksum as baseline and provide clear error/fallback messaging. +- **Risk:** Overly strict defaults could block local development. + - **Mitigation:** Provide explicit `--allow-unsigned` flow with audit logging. +- **Trade-off:** Stronger security adds packaging and release complexity. + - **Mitigation:** Automate in CI and keep policy explicit. + +## Migration Plan + +1. Introduce manifest model extensions with backward-compatible parsing. +2. Implement checksum verification in installer. +3. Add optional signature verification and policy controls. +4. Add signing automation script and CI workflow. +5. Update docs and rollout guidance. + +Rollback strategy: + +- Keep metadata parsing but disable strict signature enforcement. +- Use checksum-only trust checks temporarily. +- Preserve unsigned opt-in path for emergency recovery. + +## Open Questions + +- Should strict signature verification be default for all environments or only release pipelines? +- How should key rotation metadata be represented (single key URL vs key set)? +- Should unsigned-module opt-in be per-module, per-repo, or global policy? diff --git a/openspec/changes/arch-06-enhanced-manifest-security/proposal.md b/openspec/changes/arch-06-enhanced-manifest-security/proposal.md new file mode 100644 index 00000000..bf5ffc7e --- /dev/null +++ b/openspec/changes/arch-06-enhanced-manifest-security/proposal.md @@ -0,0 +1,54 @@ +# Change: Enhanced Module Manifest Security and Integrity Validation + +## Why + +`arch-05-bridge-registry` enables modular interoperability, but marketplace readiness still lacks trust guarantees for published modules. To prevent tampering and unsafe dependency drift, module manifests must carry integrity metadata and installation must verify checksums/signatures before enabling modules. + +## What Changes + +- **MODIFY**: Extend module manifest metadata (`ModulePackageMetadata`) with publisher identity, integrity fields, and versioned dependency entries. +- **NEW**: Add `src/specfact_cli/registry/crypto_validator.py` for checksum and optional signature verification. +- **MODIFY**: Extend module installation and registration flows to enforce integrity checks and reject invalid artifacts. +- **NEW**: Add signing automation script (`scripts/sign-module.sh`) and CI signing workflow for official module packages. +- **NEW**: Add unsigned-module safety controls requiring explicit allow-unsigned opt-in. +- **NEW**: Add documentation for module trust model and signature verification (`docs/reference/module-security.md`). + +## Capabilities + +### New Capabilities + +- `module-security`: Cryptographic integrity and trust validation for module package installation and registration. + +### Modified Capabilities + +- `module-packages`: Manifest schema expanded with publisher/integrity metadata and versioned dependency contracts. +- `module-lifecycle-management`: Registration and installation behavior strengthened with integrity validation and unsigned-module controls. + +## Impact + +- **Affected specs**: New spec for `module-security`; delta specs for `module-packages` and `module-lifecycle-management`. +- **Affected code**: + - `src/specfact_cli/models/module_package.py` (publisher/integrity/versioned deps) + - `src/specfact_cli/registry/crypto_validator.py` (new) + - `src/specfact_cli/registry/module_installer.py` (integrity checks) + - `src/specfact_cli/registry/module_packages.py` (registration-time trust enforcement) + - `scripts/sign-module.sh` (new) + - `.github/workflows/sign-modules.yml` (new) +- **Affected documentation**: + - `docs/reference/module-security.md` (new) + - `docs/reference/architecture.md` (security/trust model updates) + - `docs/_layouts/default.html` (navigation update) +- **Integration points**: module manifest parsing, module install/registration paths, CI packaging/signing pipeline. +- **Backward compatibility**: Backward compatible by default; unsigned modules remain possible only with explicit opt-in policy. +- **Rollback plan**: Disable signature enforcement and fallback to checksum-only or legacy manifest fields while preserving compatibility parsing. + +--- + +## Source Tracking + + +- **GitHub Issue**: #208 +- **Issue URL**: +- **Repository**: nold-ai/specfact-cli +- **Last Synced Status**: proposed +- **Sanitized**: false diff --git a/openspec/changes/arch-06-enhanced-manifest-security/specs/module-lifecycle-management/spec.md b/openspec/changes/arch-06-enhanced-manifest-security/specs/module-lifecycle-management/spec.md new file mode 100644 index 00000000..13b54b55 --- /dev/null +++ b/openspec/changes/arch-06-enhanced-manifest-security/specs/module-lifecycle-management/spec.md @@ -0,0 +1,28 @@ +# Spec: Module Lifecycle Management + +## ADDED Requirements + +### Requirement: Registration pipeline SHALL enforce trust checks before enabling modules + +The system SHALL execute trust checks before module registration is finalized. + +#### Scenario: Trusted module proceeds to registration + +- **WHEN** checksum/signature checks pass for a module artifact +- **THEN** registration pipeline SHALL continue and enable module commands. + +#### Scenario: Untrusted module is skipped or rejected + +- **WHEN** trust checks fail +- **THEN** lifecycle pipeline SHALL skip or reject that module +- **AND** SHALL provide diagnostic logging with failure reason. + +### Requirement: Trust failures SHALL not block unrelated module registration + +The system SHALL degrade gracefully when one module fails trust checks. + +#### Scenario: One module fails, others continue + +- **WHEN** one module fails integrity verification during registration +- **THEN** other valid modules SHALL continue registration +- **AND** overall startup SHALL remain operational with warnings. diff --git a/openspec/changes/arch-06-enhanced-manifest-security/specs/module-packages/spec.md b/openspec/changes/arch-06-enhanced-manifest-security/specs/module-packages/spec.md new file mode 100644 index 00000000..5dc75dd0 --- /dev/null +++ b/openspec/changes/arch-06-enhanced-manifest-security/specs/module-packages/spec.md @@ -0,0 +1,35 @@ +# Spec: Module Packages + +## ADDED Requirements + +### Requirement: Module package manifest SHALL support publisher and integrity metadata + +The system SHALL support structured publisher and integrity metadata in `module-package.yaml`. + +#### Scenario: Manifest includes publisher identity + +- **WHEN** manifest includes `publisher` metadata +- **THEN** parser SHALL capture `name`, `email`, and optional publisher attributes +- **AND** parsed metadata SHALL be available to trust-validation workflows. + +#### Scenario: Manifest includes integrity metadata + +- **WHEN** manifest includes `integrity` metadata +- **THEN** parser SHALL capture checksum and optional signature fields +- **AND** validation SHALL ensure checksum format correctness. + +### Requirement: Manifest dependencies SHALL support versioned entries + +The system SHALL support versioned dependency declarations for both module and pip dependencies. + +#### Scenario: Versioned module dependency parsed + +- **WHEN** manifest declares module dependency with name and version specifier +- **THEN** parser SHALL store both values in typed metadata +- **AND** version specifier SHALL be validated as a supported constraint format. + +#### Scenario: Versioned pip dependency parsed + +- **WHEN** manifest declares pip dependency with name and version specifier +- **THEN** parser SHALL preserve versioned dependency for installation-time resolution +- **AND** legacy list formats SHALL remain backward compatible when possible. diff --git a/openspec/changes/arch-06-enhanced-manifest-security/specs/module-security/spec.md b/openspec/changes/arch-06-enhanced-manifest-security/specs/module-security/spec.md new file mode 100644 index 00000000..0e796b82 --- /dev/null +++ b/openspec/changes/arch-06-enhanced-manifest-security/specs/module-security/spec.md @@ -0,0 +1,51 @@ +# Spec: Module Security + +## ADDED Requirements + +### Requirement: Module artifacts SHALL be verified for integrity before installation + +The system SHALL verify module artifact checksums before extraction or registration. + +#### Scenario: Checksum verification succeeds + +- **WHEN** installer receives a module artifact and expected checksum +- **THEN** checksum verification SHALL pass when values match +- **AND** installation SHALL continue to next verification stage. + +#### Scenario: Checksum verification fails + +- **WHEN** artifact checksum does not match expected checksum +- **THEN** installation SHALL fail with a security error +- **AND** module SHALL NOT be extracted or registered. + +### Requirement: Signature verification SHALL be supported for signed modules + +The system SHALL support signature verification for modules that provide signature metadata. + +#### Scenario: Signed module verification succeeds + +- **WHEN** module manifest includes signature and trusted key metadata +- **THEN** signature verification SHALL validate artifact provenance +- **AND** installation SHALL proceed. + +#### Scenario: Signature verification fails + +- **WHEN** signature validation fails against trusted key material +- **THEN** installation SHALL fail with explicit signature error details +- **AND** module SHALL NOT be enabled. + +### Requirement: Unsigned module installation SHALL require explicit opt-in + +The system SHALL require explicit allow-unsigned policy override when strict trust mode is enabled. + +#### Scenario: Unsigned module blocked by default policy + +- **WHEN** strict trust mode is active and module has no signature metadata +- **THEN** installer SHALL reject the module by default +- **AND** output SHALL explain how to opt in explicitly. + +#### Scenario: Unsigned module allowed via explicit override + +- **WHEN** user sets allow-unsigned override +- **THEN** installer MAY continue after checksum validation +- **AND** system SHALL emit warning/audit logs. diff --git a/openspec/changes/arch-06-enhanced-manifest-security/tasks.md b/openspec/changes/arch-06-enhanced-manifest-security/tasks.md new file mode 100644 index 00000000..804a31d6 --- /dev/null +++ b/openspec/changes/arch-06-enhanced-manifest-security/tasks.md @@ -0,0 +1,108 @@ +# Tasks: Enhanced Module Manifest Security and Integrity Validation + +## TDD / SDD Order (Enforced) + +Per `openspec/config.yaml`, delivery follows strict SDD+TDD order: + +1. **Specs first** - Spec deltas define behavior and acceptance scenarios. +2. **Tests second** - Write tests from spec scenarios and run them expecting failure. +3. **Code last** - Implement until tests pass and behavior satisfies specs. + +Do not implement production code for changed behavior until corresponding tests exist and have been run expecting failure. + +--- + +## 1. Create git branch from dev + +- [ ] 1.1 Ensure `dev` is current and create `feature/arch-06-enhanced-manifest-security` +- [ ] 1.2 Verify current branch is `feature/arch-06-enhanced-manifest-security` + +## 2. Tests: manifest security metadata models (TDD) + +- [ ] 2.1 Add model tests for `PublisherInfo`, `IntegrityInfo`, and versioned dependency entries +- [ ] 2.2 Add manifest parsing tests for legacy and extended metadata +- [ ] 2.3 Run `pytest tests/unit/specfact_cli/registry/test_module_packages.py -v` and expect failure for new assertions + +## 3. Implementation: metadata model extension + +- [ ] 3.1 Extend `src/specfact_cli/models/module_package.py` with security metadata models +- [ ] 3.2 Update validation rules for checksum/signature fields and versioned dependencies +- [ ] 3.3 Ensure public APIs use `@icontract` and `@beartype` decorators +- [ ] 3.4 Re-run related model tests and expect pass + +## 4. Tests: checksum/signature validation engine (TDD) + +- [ ] 4.1 Add `tests/unit/specfact_cli/registry/test_crypto_validator.py` +- [ ] 4.2 Add checksum match/mismatch tests +- [ ] 4.3 Add signature verification success/failure tests (with fixtures/mocks) +- [ ] 4.4 Run `pytest tests/unit/specfact_cli/registry/test_crypto_validator.py -v` and expect failure + +## 5. Implementation: crypto validator + +- [ ] 5.1 Create `src/specfact_cli/registry/crypto_validator.py` +- [ ] 5.2 Implement checksum verification helper +- [ ] 5.3 Implement signature verification helper and key import flow +- [ ] 5.4 Add robust error handling for missing keys/signatures +- [ ] 5.5 Re-run validator tests and expect pass + +## 6. Tests: installer and lifecycle trust enforcement (TDD) + +- [ ] 6.1 Add tests for installer rejection on checksum/signature mismatch +- [ ] 6.2 Add tests for unsigned-module opt-in behavior (`--allow-unsigned`) +- [ ] 6.3 Add tests ensuring unaffected modules still register when one fails trust checks +- [ ] 6.4 Run registry/install tests and expect failure + +## 7. Implementation: trust enforcement integration + +- [ ] 7.1 Update `src/specfact_cli/registry/module_installer.py` to apply verification stages +- [ ] 7.2 Update `src/specfact_cli/registry/module_packages.py` for registration-time trust checks +- [ ] 7.3 Implement explicit allow-unsigned policy path and logging +- [ ] 7.4 Re-run updated lifecycle/installer tests and expect pass + +## 8. Tests: signing automation artifacts (TDD) + +- [ ] 8.1 Add tests for signing script invocation and artifact expectations +- [ ] 8.2 Add CI workflow lint/validation checks for signing workflow +- [ ] 8.3 Run script/workflow tests and expect failure where new artifacts are missing + +## 9. Implementation: signing automation + +- [ ] 9.1 Add `scripts/sign-module.sh` +- [ ] 9.2 Add `.github/workflows/sign-modules.yml` +- [ ] 9.3 Ensure signing outputs integrate with manifest integrity fields +- [ ] 9.4 Re-run signing-related tests and expect pass + +## 10. Quality gates and validation + +- [ ] 10.1 Run `hatch run format` +- [ ] 10.2 Run `hatch run lint` +- [ ] 10.3 Run `hatch run type-check` +- [ ] 10.4 Run `hatch run contract-test` +- [ ] 10.5 Run `hatch run smart-test` +- [ ] 10.6 Run `openspec validate arch-06-enhanced-manifest-security --strict` + +## 11. Documentation research and review + +- [ ] 11.1 Identify impacted docs: `docs/reference/`, `docs/guides/`, `README.md`, `docs/index.md` +- [ ] 11.2 Add `docs/reference/module-security.md` (trust model, checksum/signature flow) +- [ ] 11.3 Update architecture docs with module trust and integrity lifecycle +- [ ] 11.4 Update `docs/_layouts/default.html` navigation for new docs + +## 12. Version and changelog + +- [ ] 12.1 Determine semantic version bump for new security capability +- [ ] 12.2 Sync version in `pyproject.toml`, `setup.py`, `src/__init__.py`, `src/specfact_cli/__init__.py` +- [ ] 12.3 Add changelog entry for manifest security, integrity checks, and signing automation + +## 13. GitHub issue creation + +- [ ] 13.1 Export proposal to GitHub with sanitize enabled: + - `specfact sync bridge --adapter github --mode export-only --sanitize --repo-owner nold-ai --repo-name specfact-cli --repo /home/dom/git/nold-ai/specfact-cli --change-ids arch-06-enhanced-manifest-security` +- [ ] 13.2 Verify issue created in `nold-ai/specfact-cli` with labels and sanitized body +- [ ] 13.3 Verify `proposal.md` Source Tracking contains issue number and URL + +## 14. Create pull request to dev (LAST) + +- [ ] 14.1 Commit completed implementation tasks with conventional commit message +- [ ] 14.2 Push `feature/arch-06-enhanced-manifest-security` +- [ ] 14.3 Create PR to `dev` with links to OpenSpec change and issue