Repository navigation
Conversation
|
CI (stacked PR, so it ran on a CI-only branch): run https://github.com/TinyCloudLabs/tinycloud-node/actions/runs/39027726967 on |
…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.
S3BlockStore::remove called GetObjectAttributes without an attribute list, which S3 and MinIO reject, so every S3 block delete errored. Use HeadObject for the size and existence check, as #336 does. A missing object is still Ok(None), and the quota drops by the stored length. Adds a MinIO-backed test run in the at-rest harness CI job.
d8dddd3 to
79878f5
Compare
cc0e223 to
91a2a57
Compare
…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.
|
Rebased onto S1 round 3 (#327 daef3cf). Exact-head CI on 79878f5 (dispatched with workflow_dispatch on the PR branch): run https://github.com/TinyCloudLabs/tinycloud-node/actions/runs/39032820048, all jobs green. |
|
REQUEST_CHANGES: see TC-887 (head |
|
REQUEST_CHANGES: see TC-887 (head 79878f5) |
79878f5 to
6b01237
Compare
|
APPROVE: see TC-887 (head |
|
Review round (6b01237): exact-head CI run https://github.com/TinyCloudLabs/tinycloud-node/actions/runs/39045005162 — all jobs green, including the 6 MinIO tests in the harness job. |
|
APPROVE: see TC-887 (head 6b01237) |
6b01237 to
98efe3e
Compare
efa5bbb to
4dbf283
Compare
98efe3e to
dc5e68f
Compare
4dbf283 to
8ba1e92
Compare
|
APPROVE: see TC-887 (head dc5e68f) |
|
Rebased onto S1 #327 029c703. Exact-head CI on dc5e68f: run https://github.com/TinyCloudLabs/tinycloud-node/actions/runs/39054266209, all jobs green. |
With encryption at rest on, the S3 block store writes new blocks as TCE1 objects under their sealed names (v1/<space tag>/<object id>) and reads them back through the authenticated decrypting reader. Range reads fetch the header, then only the segments that cover the range. Legacy objects stay readable in encrypt mode and are refused in strict mode. While keys are locked, writes and sealed reads fail with the at-rest 503. Quotas count plaintext bytes, sealed objects by space tag. Removing a block removes its sealed copy, or else the legacy object. storage::attach_at_rest attaches the runtime to both stores. The object size check uses HeadObject: GetObjectAttributes without an attribute list is rejected by S3 and MinIO. tests/at_rest_s3_store.rs runs against the at-rest harness MinIO (ignored by default; the harness CI job runs it).
…doc for the S3 seal path
…ad; contains per §7; prepare hooks; more S3 tests (S3 review)
…t test asserts no aborted body; changelog (S3 review deltas)
8ba1e92 to
a6201d0
Compare
dc5e68f to
f5cb0b0
Compare
TC-887, slice S3 part c: the S3 block store seals KV blocks. Stacked: S1 #327 → #329 (S3a) → #333 (S3b, FileSystem) → this PR. Review only the top four commits (
c36b098S3 sealing,f87eb1cdouble-remove test and escrow doc,3268564review fixes,f5cb0b0review deltas). Off by default: withTINYCLOUD_AT_REST__MODEunset oroff, the store behaves as before.What changed
tinycloud-node-server/src/storage/s3.rspersistwrites TCE1 objects under the sealed namev1/<space tag>/<object id>(from feat(TC-887): sealed KV block helpers and plaintext sizes by space tag #329'ssealedmodule).prepare_write(feat(TC-887): seal KV blocks in the FileSystem store; prepare writes before the invoke lock #333's hook) loads the space's data key before the invoke lock.readstreams the whole object through the authenticated decrypting reader.read_rangemakes two GETs: the header, then only the segments that cover the range.416reports the plaintext length.read_planas the FileSystem store.removedeletes the sealed copy, or else the legacy object.total_sizecounts plaintext bytes; sealed bytes are counted by space tag, including by the boot scan.S3Readable = Either<Body, Box<DecryptReader<Body>>>. The read, range and persist futures are boxed behind the async-trait methods, the same fix as feat(TC-887): seal KV blocks in the FileSystem store; prepare writes before the invoke lock #333's stack-overflow change.removeused GetObjectAttributes without an attribute list, which S3 and MinIO reject (InvalidArgument: Invalid attribute name specified).storage/mod.rs:attach_at_restattaches the runtime to the S3 store as well as the FileSystem store, and declares the seal path for both.docs/at-rest-escrow.mdsays both stores seal.storage/size.rstest: a double remove floors plaintext sizes at zero under both the tag and the legacy entry.tests/at_rest_s3_store.rs: a new test against a real S3 API. It is ignored by default, and the harness CI job runs it against its MinIO in a new step after the RED checks.How it was tested
tests/at_rest_s3_store.rsagainst the harness MinIO (2/2 pass):Content::lenequal to the plaintext length.416with the plaintext total.InvalidData, before any plaintext is returned. Removing the block then makes it unreadable.cargo test -p tinycloud-node --lib storage::27/27 pass;did_resolution_single_entry10/10 pass.cargo clippy -p tinycloud-node --testsandcargo fmt --checkare clean.Review fixes (security 3c9d19cf, correctness d6a8c93b), commit
3268564If-Matchwith the header GET's ETag. If the object was replaced, removed or shrunk in between, the read starts over once, then answers 503. It never falls back to the legacy name once a sealed header was read, and never gives a false integrity 500.containschecks only the name a write would use (INTERFACES §7). The S3 store implementsprepares/prepare_readand usesLoggedDecrypt.tests/at_rest_s3_store.rs(6/6 pass locally against the harness MinIO):containsper §7;Delta round (6d578564, 3f0b1aec), commit
f5cb0b0object_size/deletefrom fix(TC-1354): size S3 block deletes with HeadObject #337 is dropped; feat(TC-887): seal KV blocks in the S3 store (S3c, stacked on #333) #336's copies are kept.rust.ymlkeeps both harness steps (s3_block_storeandat_rest_s3_store), andremovekeeps feat(TC-887): seal KV blocks in the S3 store (S3c, stacked on #333) #336's sealed-first version.at_rest_s3_store6/6 and main'ss3_block_store1/1.