Skip to content

security(cold state): bind delegated MIC policy in lineage verification #369

Description

@gnanirahulnutakki

Context

#368 closes the supported fresh-mint and live-parent downgrade paths by exactly inheriting the signed MIC bundle (conformance_profile, receipt_policy, tool_manifest_digest) and by comparing parent/child bundles whenever the raw signed parent token is available.

A narrower cold-state migration gap remains: a MIC child minted before #368, with the bundle absent, can still pass hash-only delegated verification after the parent-token cache is lost. The trusted lineage index authenticates token hashes and parent edges but stores no parent policy commitment, so the verifier has nothing against which to compare the child's missing profile.

Exact boundary

At dev lineage baseline 430ec3a7f416451b57a7a909186b24fd69b2d0f9:

  • verify_passport accepts either the raw parent token or the hash/edge indexes. The latter expose no parent claims.
  • GovernanceProxy.verify_passport_token deliberately falls back to lineage_hashes.json when the parent is not live.
  • ADR-016 intentionally keeps cold checks bounded and avoids loading ancestor session blobs.
  • ADR-020 already identifies the general upgrade problem: persisted pre-tightening session state can bypass newer verifier invariants unless it is reverified or evicted.

The #368 patch explicitly documents this boundary and does not add an ad hoc ancestor-session load: persisted passport_claims are not themselves reverified today, and a quick loader would need atomic-read behavior, lock-order analysis, migration semantics, and an ADR-016 design update.

Security impact

The residual requires an already-minted pre-#368 downgraded MIC child plus cold parent state/cache loss. New child derivation, raw-parent verification, live-parent session start, and idempotent /delegate replay are covered by #368. The cold residual is nevertheless real and must be fail-closed before claiming upgrade-safe MIC lineage enforcement.

Design questions

Choose and document one authenticated, bounded design:

  1. Version lineage_hashes.json to store a signed-parent-derived MIC-bundle commitment (or canonical bundle) per JTI, with safe migration/eviction; or
  2. Implement ADR-020-style persisted-session signature and lineage reverification, then safely resolve the raw parent token for cold child verification; or
  3. Reject/evict legacy delegated children whose MIC lineage cannot be proven under the new invariant.

Do not trust persisted passport_claims directly, weaken ADR-016's hash/edge checks, or silently accept an unverifiable legacy token.

Acceptance criteria

  • A pre-security: prevent delegated MIC profile downgrade #368 child missing the MIC bundle cannot start or reload after a cold proxy restart when its signed parent required MIC-State/MIC-Evidence.
  • Current valid MIC children still verify cold with bounded work.
  • Parent policy data/commitment is authenticated, schema-versioned, and integrity-checked.
  • Missing/corrupt/migration-ambiguous state fails closed with an operator-actionable reason.
  • Lock ordering, atomic persistence, crash recovery, and migration/eviction are tested.
  • ADR-016 and ADR-020 are updated or superseded consistently.
  • Targeted cold-restart, lineage, revocation, delegation, and security tests pass.

Follow-up from #368; does not invalidate the fresh/live fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    delegationDelegation narrowing, capability attenuation, cost/blast-radius gatesrelease-hygieneRelease process & versioning hygienesecuritySecurity hardeningverificationVerification and reproducibility

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions