Repository navigation
test(TC-887): keep the at-rest key mirror out of KV pairing; check it for raw keys - #335
Merged
Merged
Conversation
… for raw keys With at-rest keys on, a space's first sealed put also writes its wrapped data key to _tc/at-rest/dek-*.json in the block bucket. The KV RED check paired and size-checked every new object, so the two spaces' mirror JSONs (which share a prefix) kept it falsely RED. Key-mirror objects are now separated from block objects and checked on their own: JSON, the data-key mirror's exact fields, a 60-byte wrapped key, no 32-byte base64 value, no space id or address in the name. Offline self-test included. INTERFACES.md notes which parts are not on main yet.
Contributor
Author
|
REQUEST_CHANGES: see TC-887 (head d03f5c1) |
… and re-derived key authentication Review 4bcaddcf on #335 (Naomi's rulings 1-6): - Every new object, key mirrors included, gets the marker and fingerprint scans; compressibility stays on blocks. A _tc/ object is a mirror only by an exact name per kind (ark/escrow/record/dek, from store.rs); any other _tc/ object is RED. - Every _tc/ object in a boot snapshot (taken by harness.sh up before any write) and after the puts is checked against its exact typed schema (MirroredArk, MirroredDek, EscrowBundle, VerificationRecord): exact fields, integer types, strict bounded RFC 3339, exact hex, canonical base64 of 60 bytes, armored age shares, duplicate keys refused. - Raw-key backstop over every string and JSON key: hex/base64/base64url, padded or not, whitespace and common prefixes stripped; 32-byte values, 32-int arrays and 16+16 splits are RED. - Object names (and mirror text) are scanned for every space's id and wallet address, raw, lowercase, hex, base64 and base64url at any alignment. - The test re-derives the S1 hierarchy from the harness's Static root (W, ARK seal and chain, KEK, DEK wrap AAD, DEK mirror tag; escrow canary, EFP and record MAC) and requires every sealed ARK and wrapped DEK to authenticate; DEK tags map to the spaces logged by sign-in. - Offline self-tests: RFC 5869 vectors and seal/open round trips with every one-bit flip rejected; S1-shaped mirrors pass; one negative case per rule and per listed bypass.
Contributor
Author
|
APPROVE: see TC-887 (head fe18014) |
This was referenced Oct 17, 2026
samgbafa
added a commit
that referenced
this pull request
Oct 17, 2026
…e, bounded generations, required mirrors Review a7e06ef6 on #335 (Naomi's round-5 rulings): - Escrow-none runs: any escrow bundle or record object is RED. Every mirror string (exempt fields, commitments, holder names alone, in pairs and in order, the armored share text and its payload, record fields) must not carry a secret the harness derived or unwrapped (root, W, ARK_g, KEK_g, chain/canary/MAC keys, NK, the DEK tag key, any DEK) in hex, base64, base64url or base32, at any alignment. - Escrow holder names are left out of the 16+16 split check (they are checked exactly by the schema). - ARK generations above 9 are refused outright and a gap is one finding; no loop is bounded by a number read from a name. - Encrypt/strict mode: an ARK mirror must exist and every block must be sealed-named, its NK space tag a harness space whose DEK mirror authenticates. - Raw-key backstop also decodes base32 and any short label: prefix and flags anything decoding to more than 32 bytes. - INTERFACES status note names #336. Self-tests for each rule.
samgbafa
added a commit
that referenced
this pull request
Oct 17, 2026
…e, bounded generations, required mirrors (#338) Review a7e06ef6 on #335 (Naomi's round-5 rulings): - Escrow-none runs: any escrow bundle or record object is RED. Every mirror string (exempt fields, commitments, holder names alone, in pairs and in order, the armored share text and its payload, record fields) must not carry a secret the harness derived or unwrapped (root, W, ARK_g, KEK_g, chain/canary/MAC keys, NK, the DEK tag key, any DEK) in hex, base64, base64url or base32, at any alignment. - Escrow holder names are left out of the 16+16 split check (they are checked exactly by the schema). - ARK generations above 9 are refused outright and a gap is one finding; no loop is bounded by a number read from a name. - Encrypt/strict mode: an ARK mirror must exist and every block must be sealed-named, its NK space tag a harness space whose DEK mirror authenticates. - Raw-key backstop also decodes base32 and any short label: prefix and flags anything decoding to more than 32 bytes. - INTERFACES status note names #336. Self-tests for each rule.
This was referenced Oct 18, 2026
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.
Part of TC-887 (encryption at rest): harness and doc follow-ups from the #331 review (F2, F1), reworked per review 4bcaddcf so that mirrors are checked against an allowlist. No product code changes.
What changed
tests/at_rest_harness.rs: KV blocks and_tc/objects are checked separately._tc/at-rest/._tc/names and contents included.An exact allowlist for mirror names. A
_tc/object is a mirror only if its name matches one of these exactly (numbers ≥ 1):_tc/at-rest/ark-<10 digits>-<32 hex>.json_tc/at-rest/escrow-<64 hex>.json_tc/at-rest/record-<64 hex>.json_tc/at-rest/dek-<32 hex>-<10 digits>.jsonAny other
_tc/object is RED.Every mirror kind is inspected, at boot as well as after the puts.
harness.sh upsaves a boot snapshot of the bucket before it reports STATE._tc/object in both snapshots against the exact schema for its kind: ARK, DEK, escrow bundle or verification record. An unknown kind is RED.Typed schemas.
created_atis strict RFC 3339, at most 35 characters.sealed,chainandwrappedare canonical base64 of exactly 60 bytes.A raw-key scan over every string and every JSON key.
Name check. Every space id and wallet address the harness created is checked, in raw, lowercase, hex (text and bytes), base64 and base64url forms at all byte alignments.
Re-derived key authentication.
Self-tests (offline, in plain
cargo test):selftest_key_hierarchy_reference_vectors: HKDF matches the RFC 5869 vectors. The test's own sealed ARK and wrapped DEK open, and every single-bit flip of each is rejected; wrong root, id, generation, label, space, dek_id or KEK are each rejected.selftest_key_mirror_accepts_s1_shaped_mirrors: a full ARK, chain, DEK, escrow and record set produces no findings.selftest_key_mirror_flags_every_bypass: 74 negative cases, each required to produce its specific finding, plus loops over every identity form and over a marker or fingerprint inside a mirror.scripts/at-rest-harness/{harness.sh,README.md}: the boot snapshot, aspaces.logfor mapping tags to spaces, and the residual: escrow share contents can't be checked without the holders' keys, so only their format is checked.docs/at-rest/INTERFACES.md: a status note. Key continuity and sealed KV storage aren't onmainyet; they land with feat(TC-887): at-rest key escrow crate and ceremony CLI #325–feat(TC-887): node wiring for at-rest keys and escrow recovery #327 and feat(TC-887): sealed KV block helpers and plaintext sizes by space tag #329/feat(TC-887): seal KV blocks in the FileSystem store; prepare writes before the invoke lock #333/feat(TC-887): seal KV blocks in the S3 store (S3c, stacked on #333) #336.How it's tested
cargo test -p tinycloud-node --test at_rest_harness: the 4 self-tests pass; the 4 live harness checks stay ignored, as before.cargo clippy … --test at_rest_harness -- -D warnings,cargo fmt --checkandbash -n harness.share clean.main's node: the boot snapshot is empty.test greenpasses, andtest redis RED as expected, with 28 KV and 16 SQL findings._tc/objects (the ARK and 4 DEKs);--expect kv=green,sql=red, KV is GREEN and SQL is RED;wrappedreplaced with a raw key plus padding, and a stray_tc/other/blobadded. KV is RED with exactly those 2 findings.