Amends the shred and mint cache-drain steps - #123
Merged
Merged
Conversation
A write on a warm encryption cache after a mint still wraps its data key under the old version: the engine's encryption cache id does not include the key. A new test in shred_drain_test pins it. ADR-0005 Amendment B records that P3 answers unknown_key at once for a provider that reads its store on every call, that P4 waits on the drain, and that P2 step 1 now needs a drain before the rewrite. The suspend/2 doc, the three guides and an ADR-0007 foot Note follow. Refs: enc-880r Refs: enc-w0i1 Refs: enc-t6b0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
A write on a warm encryption-materials cache after a mint still carries the old version's data key. The engine's encryption cache id (
aws_encryption_sdk1.0.0,Cmm.Caching.compute_encryption_cache_id/3) hashes the partition id, the suite and the request context, not the key, and the vault's partition id is the vault and the selector (Encryptor.Vault.Encrypt'smaybe_caching/3). So after P2 step 1 a write whose context finds a warm entry from before the mint is wrapped under version n whileencryption_key/2answers n+1.test/encryptor/vault/shred_drain_test.exs, describe "P2 step 1, the mint, on a warm encryption cache": the write after the mint names version 1 in its header; after a vault restart the write names version 2. The gap is real.lib/behaviour changes. The example fix, dropping the scope's encryption entry at the mint, cannot be built without a new public option:Encryptor.Envelope.provision/3takes the root vault, holds no handle on the scope's vault, and a drop there would bind one node. P2 step 1 now carries a drain before step 2 (waitmax_agefrom when the row is visible to every node's provider, or restart the vaults), and P4's second precondition is restated on that drain.{:unknown_key, selector}at once for a provider that reads its store on every call, so P3 step 3, the blast-radius P3 row, the "Cache drainage is now a runbook step" consequence and Amendment A's A5 contrast paragraph are superseded for such a provider. B2: P4 waits on the drain. B3: P2 step 1 needs a drain before step 2. B4: P4's second precondition holds from the end of that drain. It cites the 2026-09-29 Note "P4 depends on the cache drain and P3 does not" by heading andshred_drain_testby test name. The decision to amend was ruled by the operator, 2026-09-30.guides/rotation-runbook.md,guides/choosing-the-scope.md,guides/getting-started.md): each site now says that P3 answersunknown_keyat once for a provider that reads its store on every call and that P4 is the procedure that waits on the drain. The runbook also gains the P2 step 1 drain and a blast-radius row for it.No changelog fragment: the change is documentation, records and a test, which
changelog.d/README.mdexcludes.Review (in-turn, gate tier)
I re-read the diff against the three beads' acceptance fields. I checked every claim in the record text against the code by anchor at
9a399a0and in the engine at 1.0.0. The checks:decrypt/7andResolve.decryption_keys/3come before the client is built;maybe_caching/3passesPartition.id(vault, selector);rekey/2's write half builds its client throughEncrypt.client/3;GcpKms'srows/2calls the store closure and answersunknown_keyon an empty result;compute_encryption_cache_id/3takes no key input; andCacheEntry.new/2sets expiry from creation. I also re-located each of ADR-0005's self-cites (:132,:419-422,:455-456,:463,:602,:694,:796,:1095) at its anchor. The rekey claim is marked in the record as read from the code, not tested. Direction check of the record text: every claim verified on main, cites by anchor, zero removed lines underdocs/adr/. The pinned guide passages (test/guides_test.exs: the GCP subsection headings and the per-shape table) are untouched.Sabotage:
maybe_caching/3returning the uncached CMM makes the new test fail on the after-mint assertion (the header names version 2). Restored byte-equal, then recompiled.Provenance
GcpKmsrows/2cites were re-located to9a399a0(the lines moved), and the full gate ran green on the rebased head.Refs: enc-880r
Refs: enc-w0i1
Refs: enc-t6b0