Skip to content

feat(sensitive): bind opaque handle use to audience - #55

Draft
seonghobae wants to merge 8 commits into
feat/sensitive-handle-revocation-statefrom
feat/sensitive-handle-audience-binding
Draft

feat(sensitive): bind opaque handle use to audience#55
seonghobae wants to merge 8 commits into
feat/sensitive-handle-revocation-statefrom
feat/sensitive-handle-audience-binding

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Partial implementation of #10.

Buyer/security gap

Issue #10 requires an opaque sensitive-value handle to be usable only by the intended authenticated workload/service audience. The stacked #53 state already binds tenant/task/field/purpose/destination/classification, expiry, authoritative use count, and revocation; this PR adds an explicit non-transferable audience dimension to the in-process policy primitive.

Current exact implementation

This Draft remains stacked on exact #53 base 86ce4bc1c11c270dc532593d673c42bd6f623d74. Current exact head is 8d3ccf0a3b99fd9789210dd9798b422431fab7d8.

The active implementation now requires:

  • SensitiveValueHandleScope to carry an explicit bounded ASCII audience identifier;
  • every HandleUseRequest and authoritative reserve_use call to present that audience again;
  • invalid or mismatched audiences to fail closed as AudienceMismatch without consuming a use;
  • the existing exact authority/classification, expiry and use-count controls to remain fail-closed;
  • authoritative revocation to take precedence over later request mismatches so a revoked handle cannot disclose whether a different scope, audience, expiry or use-limit condition would otherwise have matched; and
  • concurrent callers sharing one externally synchronized in-process state to compete for the same authoritative count: with a one-use scope, two correct-audience contenders yield exactly one Authorized and one UseLimitReached, while a wrong-audience contender remains AudienceMismatch and cannot consume the use.

TDD / RCA evidence

Audience binding initially moved the revocation check after general request evaluation. A revoked handle with a different scope could therefore return ScopeMismatch rather than the authoritative Revoked result, regressing #53 lifecycle semantics and exposing later policy-state information.

Test-only head 95f0f1e418024f5dbe7aa613e5fd1e9d88a9417a added revocation_precedes_request_mismatch_without_leaking_later_policy_state. CI run 31419991170 established the intended RED: formatting and workspace check passed, while the regression failed with actual ScopeMismatch versus required Revoked.

The narrow production repair moved the revocation check back ahead of request evaluation while retaining audience binding. A subsequent concurrency regression exercises three synchronized contenders through Arc<Mutex<SensitiveHandleUseState>> without adding a false cross-process transaction claim.

Exact-head evidence

Exact head 8d3ccf0a3b99fd9789210dd9798b422431fab7d8 passes CI run 31421061134:

  • repository Python contracts: success;
  • cargo fmt --all --check: success;
  • locked workspace/all-target check: success;
  • all workspace tests, including the synchronized concurrency case: success;
  • strict Clippy: success;
  • rustdoc/API documentation: success;
  • exact owned production function/line/region/branch coverage: success; and
  • CodeRabbit exact-head status: success.

No predecessor-head result is transferred to this exact head.

Scope boundary

This is still only an in-process authority/audience primitive. External synchronization in the concurrency test proves the state composes safely with one-process exclusive mutation; it is not a durable or distributed transaction guarantee. This PR does not claim authenticated workload identity, token-audience verification, durable handle storage, protected-value resolution, KMS, mTLS identity, database persistence, cross-process transactions, model disclosure, browser fill, or release readiness. A later trusted broker/service-identity boundary must derive the audience from authenticated caller identity rather than user-controlled input.

Keep Draft while #53/#46 remain active. Canonical whole-product documentation remains owned by PR #44, and this active branch must not be described as protected-main shipped truth.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c95cba44-6ad2-4e7c-ac5d-3083507497ee

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

seonghobae added a commit that referenced this pull request Aug 10, 2026
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.

1 participant