Skip to content

feat(schemas): ProvenanceLabelAllowlist caveat + narrowing helper (#226) - #246

Merged
George-RD merged 2 commits into
mainfrom
George-RD/dev-226
Aug 21, 2026
Merged

George-RD merged 2 commits into
mainfrom
George-RD/dev-226

Conversation

@George-RD

@George-RD George-RD commented Aug 21, 2026

Copy link
Copy Markdown
Owner

What

Adds the ProvenanceLabelAllowlist grant caveat and its narrowing helper effectively_allows_provenance_label, an exact mirror of the AD-060 typed egress-class caveat discipline (D-174, spec #220). Builds on #222 (ProvenanceOrigin/IdentityRef, merged).

  • crates/openspine-schemas/src/grant_chain.rs: Caveat::ProvenanceLabelAllowlist { origins: Vec<ProvenanceOrigin> }, its MAC-covered caveat_bytes arm, SupportedCaveatKind::ProvenanceLabelAllowlist + exhaustive fail-closed arm in has_unsupported_caveats_except, and effectively_allows_provenance_label.
  • crates/openspine-authority/src/worker_grant.rs: mint_worker_grant appends an empty ProvenanceLabelAllowlist unconditionally (mirrors the empty EgressClassAllowlist).
  • crates/openspine-gate/src/gate.rs: chain_valid() declares the caveat supported.

Why

The Immune-system egress gate must be able to narrow which typed-identity origin's data a sub-grant may disclose. Per spec #220 / D-174, authority to widen that closure travels the grant chain as a caveat that can only narrow — chain-appended, empty-list-narrows, fail-closed on unknown, never a root-field mutation (there is no provenance root field; adding one would desync seal_child_from_parent_tip from verify_mac, AD-148).

v1 posture / scope

  • Worker sub-grants adopt the caveat (provably closed); the single-owner owner grant is minted without it (caveat dormant on the owner grant).
  • Gate only declares support — no gate-time origin enforcement (request-side provenance-origin input is out of scope; the label binding is owned in parallel by dev-224).
  • Diff is confined to the caveat + narrowing helper + adoption; owner/root mint paths untouched.

Tests

Mirror the egress-class suite: intersection/empty-list narrowing, named-origin narrowing, MAC tamper detection (caveat is MAC-covered), fail-closed-unless-supported, and worker sub-grant narrowing (MAC stays valid per AD-148). ./scripts/check.sh passes green.

Implementation-notes summary

  1. Added Caveat::ProvenanceLabelAllowlist { origins: Vec<ProvenanceOrigin> }, its MAC-covered caveat_bytes arm, SupportedCaveatKind::ProvenanceLabelAllowlist + fail-closed arm, and effectively_allows_provenance_label — an exact mirror of the egress-class caveat (AD-060).
  2. Narrowing is chain-only (no root field), so the MAC stays consistent between seal_child_from_parent_tip and verify_mac (AD-148); empty list narrows to "no origin allowed", unknown caveat fails closed.
  3. mint_worker_grant appends an empty ProvenanceLabelAllowlist so worker sub-grants are provably closed; the owner grant is minted without it (dormant on the v1 single-owner grant).
  4. gate.rs::chain_valid() declares the new kind supported so worker grants still validate; no gate-time origin enforcement (request-side input out of scope, owned by dev-224's label binding).
  5. Tests mirror the egress suite (intersection, empty-list narrowing, named-origin narrowing, MAC tamper, fail-closed support, worker narrowing); ./scripts/check.sh passes green.

Closes #226


Summary by cubic

Adds a provenance-origin allowlist caveat and a narrowing helper so sub-grants can only disclose data from permitted origins. Previously origins were not narrowable; now origin membership intersects across chain caveats, empty lists narrow to none, and the caveat is MAC-covered and fails closed unless the verifier declares support.

  • openspine-schemas: adds Caveat::ProvenanceLabelAllowlist { origins: Vec<ProvenanceOrigin> }, canonicalizes caveat_bytes, declares SupportedCaveatKind::ProvenanceLabelAllowlist, fail-closed validation, and effectively_allows_provenance_label(...) (chain-only intersection; no root field).
  • openspine-authority: mint_worker_grant appends an empty ProvenanceLabelAllowlist to worker sub-grants (provably closed). Owner grants are unchanged. Test fixture retyped TaskGrant.user to PrincipalId.
  • openspine-gate: declares the new caveat supported in chain validation; no gate-time origin enforcement yet.
  • Tests cover intersection semantics, empty-list narrowing, named-origin narrowing, MAC tamper invalidation, unsupported-caveat gating, and user retyping MAC/wire invariants.
  • Rollout: upgrade verifiers (openspine-gate) to this version before minting or relying on worker grants with this caveat. No data migrations.

Written for commit 2b96fac. Summary will update on new commits.

Review in cubic

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@George-RD, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3d8c065b-ac2d-4607-a255-809cfbee83ad

📥 Commits

Reviewing files that changed from the base of the PR and between ba94d51 and 2b96fac.

📒 Files selected for processing (5)
  • crates/openspine-authority/src/worker_grant.rs
  • crates/openspine-authority/tests/common/projection.rs
  • crates/openspine-gate/src/gate.rs
  • crates/openspine-schemas/src/grant_chain.rs
  • crates/openspine-schemas/src/grant_chain/tests.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Mirror the AD-060 typed egress-class caveat discipline for provenance
origins (D-174, spec #220). Add Caveat::ProvenanceLabelAllowlist, its
MAC-covered caveat_bytes arm, SupportedCaveatKind + fail-closed arm, and
effectively_allows_provenance_label (chain-only intersection, empty-list
narrows, no root field so the MAC stays consistent per AD-148).

Worker sub-grants adopt an empty caveat (provably closed); the v1
single-owner owner grant is minted without it (dormant). Gate declares
the caveat supported so worker grants still validate; no gate-time origin
enforcement (request-side input out of scope, owned in parallel by dev-224).

Closes #226
#245 retyped TaskGrant.user to PrincipalId but missed the
project_catalog integration-test fixture builder, which broke
`cargo clippy --all-targets`. Apply the same Ulid::new().into()
pattern used across #245's test updates.
@George-RD
George-RD merged commit 27ca4ab into main Aug 21, 2026
3 checks passed
@George-RD
George-RD deleted the George-RD/dev-226 branch August 21, 2026 03:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add grant caveat ProvenanceLabelAllowlist and narrowing helper

1 participant