Repository navigation
test(TC-887): harness follow-ups 3: secrets in blocks, blocks tied to their DEK, ARK sanity cap - #340
Merged
Merged
Conversation
… their DEK, ARK sanity cap Review 159550aa on #338 (Naomi's round-6 rulings): - Every block's name and bytes are scanned for the harness-derived secrets (root, W, ARK_g, KEK_g, chain/canary/MAC keys, NK, tag key, every unwrapped DEK): raw bytes, and hex, base64 or base64url text at any alignment. A DEK in the TCE1 header salt or b64url(DEK/NK) as the object name is RED. - Encrypt/strict mode ties each block to its mirrored DEK: name v1/<22>/<43>, NK tag of a harness space, TCE1 header dek_id among that space's authenticated DEKs, name equal to the sealed name of a logged put (puts.log), and the block opens under that DEK (main's at_rest::open, AAD space + content hash) to the put's content. - ARK generations get a harness-only sanity cap of 1000 (they are unbounded in the node; 1..=9 is the TCE format generation); absurd names still fail fast, a chain of 10 passes. - Cheap free-field bypasses closed: bech32 recipient data, hex/base64 text inside the armor payload, holder splits with -/_ separators, shifts up to 7 chars and any order. The rest is listed as out of scope in the README. Self-tests for each rule.
Contributor
Author
|
REQUEST_CHANGES: see TC-887 (head 200a499) |
Contributor
Author
|
APPROVE: see TC-887 (head 1fd4faf) |
This was referenced Oct 17, 2026
samgbafa
added a commit
that referenced
this pull request
Oct 17, 2026
…ces as out of scope (#344) Approval nits on #340: - Encoded runs are now taken per alphabet (all decoders together, and base32, hex and base64url each on their own), in block bodies and names and in mirror strings, so a base32-encoded secret followed by a character outside base32 (9, 1) is still decoded at every alignment. Self-test covers a block body and a mirror string, and fails with the previous single-alphabet runs. - README: the out-of-scope list names a secret split into 3 or more pieces across salts.
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.
TC-887 harness follow-ups from the #338 approval (review 159550aa). No product code changes.
What changed (
tests/at_rest_harness.rs,scripts/at-rest-harness/{harness.sh,README.md})Blocks are scanned for derived secrets. In both snapshots and in every mode, each block is scanned for each secret the harness derives: root, W, each ARK, KEK, chain, canary and MAC key, NK, tag key, and every unwrapped DEK.
b64url(DEK)as a name, is now RED.ARK generation cap.
ARK_GENERATION_SANITY_CAP = 1000is a harness-only bound. ARK generations themselves are unbounded (rotate_arkmakes g+1), and 1..=9 is the TCE format generation, a different field. The code comment and the README say so. Absurd names still fail fast.Every block is tied to its mirrored DEK. In encrypt and strict modes, every block must:
v1/<22>/<43>, with an NK tag that maps to a harness space;Header::parse), with a headerdek_idthat is one of that space's authenticated DEKs;sealed_object_namefor a logged put (kv_putappends toputs.log;harness.shexportsTC887_PUTS_LOG);at_rest::openunder that DEK, with the store'sKvBlock{space, content_hash}AAD, to bytes whose blake3 equals the logged hash.Every block is opened, not only one per space.
Free-field bypasses. Now caught:
-/_separators or shifted by 0–7 characters;label:prefix.The rest are listed in the README, one line each, as out of scope for a regression harness: unopenable commitments and shares, XOR splits, other separators and encodings, and secrets encrypted under an unknown key.
How it's tested
cargo test -p tinycloud-node --test at_rest_harness: 9 self-tests pass, 4 live checks ignored. New or extended self-tests:selftest_blocks_carry_no_derived_secret, run in encrypt and off modes;selftest_blocks_open_under_their_mirrored_dek, with 8 RED cases: wrongdek_id, the wrong DEK, a constant key, a cross-space swap, a bit flip, a non-TCE1 body, an unlogged name, an empty name;selftest_key_mirror_bounds_absurd_generations;selftest_key_mirror_refuses_escrow_contents_and_derived_keys.cargo clippy … --test at_rest_harness -- -D warnings,cargo fmt --checkandbash -n harness.share clean.dek_idset to 7: RED, "names data key 7, but its space's authenticated DEK mirror(s) are [1]".Review fixes (5bf91292), commit
1fd4fafbody[20..52], perHeader::build), any 16-byte window of any derived secret is RED. Each salt is checked on its own, so halves split across two blocks' salts flag both blocks. New self-testselftest_salts_hold_no_piece_of_a_secret, run in encrypt and off modes:byte_viewsdecodings (hex, base64, base64url, base32, bech32 data, armor; prefixes stripped; shifts) apply to the body as text, to the whole name and to every name segment;selftest_blocks_carry_no_derived_secret;cargo fmt --checkandcargo clippy --test at_rest_harness -- -D warningsare clean, and 10 self-tests pass (4 ignored). The live run against the S3 stack node gives KV GREEN and SQL RED in encrypt mode; the new decodings raise no false RED on real ciphertext. In mode off, KV and SQL are both RED.