Skip to content

feat(stack-encrypt): v2 sealed leaf naming the key backend and key mode (CIP-5305) - #1524

Closed
freshtonic wants to merge 10 commits into
james/cip-5304-make-datakeysource-and-indexkeysource-vendor-neutralfrom
james/cip-5305-v2-sealed-leaf-with-key-backend-and-key-mode
Closed

freshtonic wants to merge 10 commits into
james/cip-5304-make-datakeysource-and-indexkeysource-vendor-neutralfrom
james/cip-5305-v2-sealed-leaf-with-key-backend-and-key-mode

Conversation

@freshtonic

@freshtonic freshtonic commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Layer 3 of the CIP-5203 stack. Implements CIP-5305 (ADR-0010).

  • v2 leaf: 0x02 ‖ backend ‖ mode ‖ keyset_id ‖ iv ‖ tag_len ‖ tag ‖ ct. The header is bound by the leaf AAD. v1 does not change, and a known-answer test pins it.
  • KeyBackend, KeyVendor and KeyMode have stable byte values.
  • Error::ForeignBackend refuses a leaf from another backend before any key call.
  • A v2 leaf passes through eql-bindings unchanged. Fuzz seeds are added.

Decisions are in docs/plans/2026-11-05-key-vendor-backends-decisions.md (CIP-5305 section).

@freshtonic
freshtonic added this pull request to stack #1523 November 5, 2026 00:11
@changeset-bot

changeset-bot Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: dbdc34e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@freshtonic freshtonic changed the title james/cip 5305 v2 sealed leaf with key backend and key mode feat(stack-encrypt): v2 sealed leaf naming the key backend and key mode (CIP-5305) Nov 5, 2026
@coderabbitai

coderabbitai Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Mutation testing (cargo-mutants, --in-diff, stack-auth + stack-encrypt)

caught missed unviable timeout
0 0 0 0

cargo-mutants exited 4 with no surviving mutants recorded. The run may not have completed cleanly; check the workflow run logs.

@freshtonic
freshtonic force-pushed the james/cip-5304-make-datakeysource-and-indexkeysource-vendor-neutral branch from 8a5f036 to d6c5305 Compare November 6, 2026 05:10
@freshtonic
freshtonic force-pushed the james/cip-5305-v2-sealed-leaf-with-key-backend-and-key-mode branch from bb8fc9d to 15163ba Compare November 6, 2026 05:10
coderdan added a commit that referenced this pull request Nov 8, 2026
…at track it

Checked on 8 November 2026 against next at e4990e4, which has not
moved since the plan's last check. Also: ExpectedContext already exists
on next; the frozen fixtures predate the rc.3 tag; the three stacked
conformance pull requests are in review; #1503 adds Zeroizing; the
nonexistent #1326 is no longer cited; and draft #1524 claims the same
envelope version byte as the key request items, recorded as a conflict
and an open question.
@coderdan

coderdan commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Issue #1566 plans to use the SealedValue format byte 0x02 for values whose context parts go to ZeroKMS as key request items. This pull request also uses 0x02 for its version 2 leaf. The two need to agree before either lands: either one version 2 header that includes both, or one of them takes the next byte. #1566 records the decision.

@freshtonic
freshtonic force-pushed the james/cip-5304-make-datakeysource-and-indexkeysource-vendor-neutral branch from d6c5305 to cd77cf8 Compare November 9, 2026 04:16
@freshtonic
freshtonic force-pushed the james/cip-5305-v2-sealed-leaf-with-key-backend-and-key-mode branch from 15163ba to 22594ee Compare November 9, 2026 04:16
@freshtonic
freshtonic removed this pull request from stack #1523 November 9, 2026 04:17
@freshtonic
freshtonic added this pull request to stack #1579 November 9, 2026 04:17
Add ADR-0009 (two key modes), ADR-0010 (v2 leaf with backend and mode)
and ADR-0011 (hand-written vendor clients, signed in the guest). Widen
the Keyset term and add the key backend terms to CONTEXT.md.
Add the seams a key vendor backend needs:

- KeyLifetime and LoadedIndexKey, returned by the new provided method
  IndexKeySource::load_index_key_with_lifetime. The default is
  UntilEvicted, the ZeroKMS behaviour.
- Error::Backend { vendor, kind, source } with BackendErrorKind, and
  Error::ZeroKmsOnly { vendor, feature }.
- ZeroKmsFeature, ZeroKmsExtensions and refuse_zerokms_extensions, so a
  key vendor backend refuses a context, a decryption policy or an
  unverified context and never ignores it.
- IndexKey::from_key_bytes, a public constructor from raw key material.

The Go guest maps the two new error variants to statuses.

BREAKING CHANGE: stack_kms::Error has two new variants. An exhaustive
match on it must handle them.
…304)

The cipher loads index keys with load_index_key_with_lifetime. A key for
one settle only is never cached, a key with a TTL is evicted when the TTL
ends, and a ZeroKMS key stays until evicted. init refuses a default keyset
whose key the cipher may not keep (Error::DefaultKeysetLifetime).

A key vendor backend's NotFound now counts as keyset not found, and
Descriptor::MAX_LEN no longer reads a ZeroKMS constant.
…(CIP-5305)

Add KeyBackend (ZeroKMS or a key vendor backend), KeyVendor and KeyMode.
KeyVendor and KeyMode have stable bytes for the v2 sealed leaf; 0 is
invalid for both. DataKeySource::key_backend says which backend a source
is, and defaults to ZeroKMS.
…backend (CIP-5305)

A v2 leaf is 0x02 ‖ backend ‖ mode ‖ keyset_id ‖ iv ‖ tag_len ‖ tag ‖ ct.
The leaf AAD binds the three header bytes. A v1 leaf, its AAD and its
serde form do not change, and ZeroKMS still writes v1.

A cipher refuses a leaf that names another key backend than its own with
Error::ForeignBackend, before any key call. A key vendor backend cannot
seal yet (Error::SealUnsupported); CIP-5306 wires that path.

Add a v1 known-answer test, v2 layout pins, header-byte tamper tests,
v2 fuzz seeds, an eql-bindings pass-through test, and the Go guest
status for ForeignBackend.
@freshtonic
freshtonic force-pushed the james/cip-5305-v2-sealed-leaf-with-key-backend-and-key-mode branch from 22594ee to dbdc34e Compare November 10, 2026 02:37
@freshtonic
freshtonic force-pushed the james/cip-5304-make-datakeysource-and-indexkeysource-vendor-neutral branch from 8036d19 to fb05412 Compare November 12, 2026 03:44
@freshtonic
freshtonic removed this pull request from stack #1579 November 12, 2026 03:45
@freshtonic

Copy link
Copy Markdown
Contributor Author

Closed by the scope reduction. The v2 sealed leaf is dropped: stack-encrypt is now unchanged from next, and every leaf is the v1 leaf. The key router sends a leaf to its backend by the leaf's keyset id, and stack-kms-vendor binds the vendor and mode bytes into every derived key (#1526). ADR-0010 is marked rejected in #1521.

The plan is docs/plans/2026-11-12-key-vendor-backends-scope-reduction.md, and the decision log (docs/plans/2026-11-05-key-vendor-backends-decisions.md, "Scope reduction") records what changed. The old branch tip is kept locally as refs/backup/2026-11-12/<branch>.

@freshtonic freshtonic closed this Nov 12, 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.

2 participants