Repository navigation
Conversation
|
REQUEST_CHANGES: see TC-887 (security review of head 1b300a2) |
|
REQUEST_CHANGES: see TC-887 (correctness/operability review of head 1b300a2) |
Workspace isolation: - tinycloud-at-rest-cli is excluded from the node workspace, with its own Cargo.lock and CI job (fmt, clippy, tests incl. stock age v1.3.2 interop, sha256-pinned). dcap-qvl no longer enters the node's dependency graph: `cargo tree -p tinycloud-node -e features` is identical to main and the root lockfile only adds the escrow crate's dependencies. Escrow crate: - Accept age1yubikey1 (piv-p256) recipients, the format released age-plugin-yubikey 0.5.1 prints and decrypts, sealed exactly as the plugin's wrap_file_key; age1tag1 stays supported. - RecipientPolicy: X25519 software recipients are refused unless explicitly allowed (tests and self-host). - Bundle, record and recovery response are parsed version-first; RecoveryInfo gains a version. Clearer share/commitment errors. - forbid(unsafe_code). CLI: - TCB status is a fixed class: UpToDate passes; SWHardeningNeeded / ConfigurationNeeded / ConfigurationAndSWHardeningNeeded only if allowed and every advisory ID is pinned; OutOfDate*, TDRelaunch*, Revoked and unknown never pass. Status, advisories and collateral dates are printed. - Local checks (stale bundle, nonce, binding) run before any PCCS/DCAP work; PCCS fetch has a 60 s timeout. - --expect-efp and --allow-software on every bundle command; exit codes 0 OK / 1 REFUSED / 2 usage / 3 ERROR; verify-node shows node state and shares held; verify-record renamed record-efp and marked NOT AUTHENTICATED. - New: self-test (ceremony step 0 round trip with the TEE's sealing code), recipient-key (compare with a YubiKey attestation), and verify-compose (compose_hash + every image pinned by @sha256:). - Tests: every TCB class from a genuine quote and collateral, identity event ordering/duplication, v2 preimage, malformed logs, binary-level exit codes and messages, stock age interop (X25519 round trip and a Go-produced p256tag vector).
|
REQUEST_CHANGES: see TC-887 (security review of head 8d124b0) |
|
APPROVE: see TC-887 (correctness re-review of head 8d124b0; Linear comment defc9998) |
…#325) - verify-compose parses the compose YAML with yaml-rust2 (=0.13.0, CLI workspace only) and accepts a strict subset: one document, no anchors, aliases, merge keys, tags or duplicate keys, a services mapping without include, and every service with an `image` of exactly `<name>[:tag]@sha256:<64 hex>` and no build/extends. It also lists the other app-compose settings the hash covers. The four reported bypasses (comment, flow mapping, quoted key, build) are tests. - Checked-in piv-p256 vector produced by the released age-plugin-yubikey 0.5.1; the test identity now rejects what the plugin's from_stanza rejects (argument lengths, uncompressed epk, body length). - Warn on age1tag1 holders (0.5.1 can't decrypt p256tag). - Version-first parsing keeps duplicate-key rejection; RecoveryInfo mode and state are validated. - CLI: self-test creates --out; malformed bundle/recovery/record JSON is exit 3 (ERROR); a hardening TCB class without advisories is refused.
Workspace isolation: - tinycloud-at-rest-cli is excluded from the node workspace, with its own Cargo.lock and CI job (fmt, clippy, tests incl. stock age v1.3.2 interop, sha256-pinned). dcap-qvl no longer enters the node's dependency graph: `cargo tree -p tinycloud-node -e features` is identical to main and the root lockfile only adds the escrow crate's dependencies. Escrow crate: - Accept age1yubikey1 (piv-p256) recipients, the format released age-plugin-yubikey 0.5.1 prints and decrypts, sealed exactly as the plugin's wrap_file_key; age1tag1 stays supported. - RecipientPolicy: X25519 software recipients are refused unless explicitly allowed (tests and self-host). - Bundle, record and recovery response are parsed version-first; RecoveryInfo gains a version. Clearer share/commitment errors. - forbid(unsafe_code). CLI: - TCB status is a fixed class: UpToDate passes; SWHardeningNeeded / ConfigurationNeeded / ConfigurationAndSWHardeningNeeded only if allowed and every advisory ID is pinned; OutOfDate*, TDRelaunch*, Revoked and unknown never pass. Status, advisories and collateral dates are printed. - Local checks (stale bundle, nonce, binding) run before any PCCS/DCAP work; PCCS fetch has a 60 s timeout. - --expect-efp and --allow-software on every bundle command; exit codes 0 OK / 1 REFUSED / 2 usage / 3 ERROR; verify-node shows node state and shares held; verify-record renamed record-efp and marked NOT AUTHENTICATED. - New: self-test (ceremony step 0 round trip with the TEE's sealing code), recipient-key (compare with a YubiKey attestation), and verify-compose (compose_hash + every image pinned by @sha256:). - Tests: every TCB class from a genuine quote and collateral, identity event ordering/duplication, v2 preimage, malformed logs, binary-level exit codes and messages, stock age interop (X25519 round trip and a Go-produced p256tag vector).
…#325) - verify-compose parses the compose YAML with yaml-rust2 (=0.13.0, CLI workspace only) and accepts a strict subset: one document, no anchors, aliases, merge keys, tags or duplicate keys, a services mapping without include, and every service with an `image` of exactly `<name>[:tag]@sha256:<64 hex>` and no build/extends. It also lists the other app-compose settings the hash covers. The four reported bypasses (comment, flow mapping, quoted key, build) are tests. - Checked-in piv-p256 vector produced by the released age-plugin-yubikey 0.5.1; the test identity now rejects what the plugin's from_stanza rejects (argument lengths, uncompressed epk, body length). - Warn on age1tag1 holders (0.5.1 can't decrypt p256tag). - Version-first parsing keeps duplicate-key rejection; RecoveryInfo mode and state are validated. - CLI: self-test creates --out; malformed bundle/recovery/record JSON is exit 3 (ERROR); a hardening TCB class without advisories is refused.
05c5200 to
65d3f4c
Compare
Workspace isolation: - tinycloud-at-rest-cli is excluded from the node workspace, with its own Cargo.lock and CI job (fmt, clippy, tests incl. stock age v1.3.2 interop, sha256-pinned). dcap-qvl no longer enters the node's dependency graph: `cargo tree -p tinycloud-node -e features` is identical to main and the root lockfile only adds the escrow crate's dependencies. Escrow crate: - Accept age1yubikey1 (piv-p256) recipients, the format released age-plugin-yubikey 0.5.1 prints and decrypts, sealed exactly as the plugin's wrap_file_key; age1tag1 stays supported. - RecipientPolicy: X25519 software recipients are refused unless explicitly allowed (tests and self-host). - Bundle, record and recovery response are parsed version-first; RecoveryInfo gains a version. Clearer share/commitment errors. - forbid(unsafe_code). CLI: - TCB status is a fixed class: UpToDate passes; SWHardeningNeeded / ConfigurationNeeded / ConfigurationAndSWHardeningNeeded only if allowed and every advisory ID is pinned; OutOfDate*, TDRelaunch*, Revoked and unknown never pass. Status, advisories and collateral dates are printed. - Local checks (stale bundle, nonce, binding) run before any PCCS/DCAP work; PCCS fetch has a 60 s timeout. - --expect-efp and --allow-software on every bundle command; exit codes 0 OK / 1 REFUSED / 2 usage / 3 ERROR; verify-node shows node state and shares held; verify-record renamed record-efp and marked NOT AUTHENTICATED. - New: self-test (ceremony step 0 round trip with the TEE's sealing code), recipient-key (compare with a YubiKey attestation), and verify-compose (compose_hash + every image pinned by @sha256:). - Tests: every TCB class from a genuine quote and collateral, identity event ordering/duplication, v2 preimage, malformed logs, binary-level exit codes and messages, stock age interop (X25519 round trip and a Go-produced p256tag vector).
65d3f4c to
91c5411
Compare
…#325) - verify-compose parses the compose YAML with yaml-rust2 (=0.13.0, CLI workspace only) and accepts a strict subset: one document, no anchors, aliases, merge keys, tags or duplicate keys, a services mapping without include, and every service with an `image` of exactly `<name>[:tag]@sha256:<64 hex>` and no build/extends. It also lists the other app-compose settings the hash covers. The four reported bypasses (comment, flow mapping, quoted key, build) are tests. - Checked-in piv-p256 vector produced by the released age-plugin-yubikey 0.5.1; the test identity now rejects what the plugin's from_stanza rejects (argument lengths, uncompressed epk, body length). - Warn on age1tag1 holders (0.5.1 can't decrypt p256tag). - Version-first parsing keeps duplicate-key rejection; RecoveryInfo mode and state are validated. - CLI: self-test creates --out; malformed bundle/recovery/record JSON is exit 3 (ERROR); a hardening TCB class without advisories is refused.
Adds two workspace crates that the node does not use yet: - tinycloud-at-rest-escrow: 2-of-3 Shamir split of the at-rest root key (vsss-rs 5.4.0, GF(256)), shares sealed with age 0.12.1 to pinned age1tag1 (hardware) or age1 recipients, the escrow bundle and its fingerprint, the canary, the ARK-MACed verification record and the recovery wire format. - tinycloud-at-rest-cli (tinycloud-at-rest): recipients config, nonce, inspect, extract-share, check-share, verify-node, share-wrap and verify-record. share-wrap verifies the node's TDX quote with DCAP collateral (dcap-qvl 0.7.0) and a pinned trust policy before it releases a share; shares are read from stdin only. Fixtures: real TDX quotes and collateral from dcap-qvl 0.7.0 (MIT). Lockfile: dcap-qvl raises anyhow, borsh, chrono and typenum within their semver ranges. docs/at-rest-escrow.md describes the formats.
Workspace isolation: - tinycloud-at-rest-cli is excluded from the node workspace, with its own Cargo.lock and CI job (fmt, clippy, tests incl. stock age v1.3.2 interop, sha256-pinned). dcap-qvl no longer enters the node's dependency graph: `cargo tree -p tinycloud-node -e features` is identical to main and the root lockfile only adds the escrow crate's dependencies. Escrow crate: - Accept age1yubikey1 (piv-p256) recipients, the format released age-plugin-yubikey 0.5.1 prints and decrypts, sealed exactly as the plugin's wrap_file_key; age1tag1 stays supported. - RecipientPolicy: X25519 software recipients are refused unless explicitly allowed (tests and self-host). - Bundle, record and recovery response are parsed version-first; RecoveryInfo gains a version. Clearer share/commitment errors. - forbid(unsafe_code). CLI: - TCB status is a fixed class: UpToDate passes; SWHardeningNeeded / ConfigurationNeeded / ConfigurationAndSWHardeningNeeded only if allowed and every advisory ID is pinned; OutOfDate*, TDRelaunch*, Revoked and unknown never pass. Status, advisories and collateral dates are printed. - Local checks (stale bundle, nonce, binding) run before any PCCS/DCAP work; PCCS fetch has a 60 s timeout. - --expect-efp and --allow-software on every bundle command; exit codes 0 OK / 1 REFUSED / 2 usage / 3 ERROR; verify-node shows node state and shares held; verify-record renamed record-efp and marked NOT AUTHENTICATED. - New: self-test (ceremony step 0 round trip with the TEE's sealing code), recipient-key (compare with a YubiKey attestation), and verify-compose (compose_hash + every image pinned by @sha256:). - Tests: every TCB class from a genuine quote and collateral, identity event ordering/duplication, v2 preimage, malformed logs, binary-level exit codes and messages, stock age interop (X25519 round trip and a Go-produced p256tag vector).
…#325) - verify-compose parses the compose YAML with yaml-rust2 (=0.13.0, CLI workspace only) and accepts a strict subset: one document, no anchors, aliases, merge keys, tags or duplicate keys, a services mapping without include, and every service with an `image` of exactly `<name>[:tag]@sha256:<64 hex>` and no build/extends. It also lists the other app-compose settings the hash covers. The four reported bypasses (comment, flow mapping, quoted key, build) are tests. - Checked-in piv-p256 vector produced by the released age-plugin-yubikey 0.5.1; the test identity now rejects what the plugin's from_stanza rejects (argument lengths, uncompressed epk, body length). - Warn on age1tag1 holders (0.5.1 can't decrypt p256tag). - Version-first parsing keeps duplicate-key rejection; RecoveryInfo mode and state are validated. - CLI: self-test creates --out; malformed bundle/recovery/record JSON is exit 3 (ERROR); a hardening TCB class without advisories is refused.
91c5411 to
4222883
Compare
|
REQUEST_CHANGES: see TC-887 (security review round 2, head |
…; review round 3 (#325) - The strict app-compose reader moves to tinycloud_at_rest_escrow::compose (yaml-rust2 =0.13.0), shared by the CLI and the node. - docker_compose_file may contain only newlines and printable ASCII: Unicode line breaks (U+0085, U+2028, U+2029), CR, tabs, BOM and control characters are refused before parsing. The review's four line-break PoCs are fixtures; the production compose is a test. - runner must be docker-compose. - literal_env: the escrow recipients and pin, if set, must be literal environment values (no interpolation or pass-through). - verify-compose prints the escrow literals and every other app-compose setting in full (pre_launch_script included); all untrusted text the CLI echoes is escaped (\u{..}), including REFUSED/ERROR lines. - docker-compose.dstack-postgres.yaml: an em dash in a comment replaced, so the production compose is ASCII-only.
|
APPROVE: see TC-887 (head 4222883) |
|
APPROVE: see TC-887 (security review round 3, head |
…elling (#325) - app-compose.json with an object key repeated at any depth is refused (serde_json would keep the last; dstack's struct parse refuses it). - Null, NULL, null, ~ and empty escrow values are pass-through, refused explicitly rather than failing later.
|
APPROVE: see TC-887 (correctness round 3, head |
|
APPROVE: see TC-887 (security review round 3 delta, final head |
|
APPROVE: see TC-887 (security review round 4, head |
|
APPROVE: see TC-887 (correctness round 4, head |
TC-887 (S1, PR 1 of 3). Adds the escrow format and the ceremony/recovery tool. The node binary doesn't use them yet, so behaviour is unchanged. Merge only after the current main release is cut (TC-887 merge order).
What's added
tinycloud-at-rest-escrowis a node workspace member; nothing uses it yet. It provides:vsss-rs5.4.0, GF(256));age0.12.1) to a pinned recipient. Accepted kinds areage1yubikey1(thepiv-p256format that released age-plugin-yubikey 0.5.1 handles) andage1tag1(the tool warns that 0.5.1 can't decryptage1tag1). X25519 is accepted only with an explicit software-recipient policy;tinycloud-at-rest-cli(tinycloud-at-restbinary) is its own Cargo workspace with its ownCargo.lock. It is excluded from the node workspace and has its own CI job: fmt, clippy, tests, and interop with a sha256-pinned stock age v1.3.2. Commands:recipients,self-test,recipient-key,nonce;inspect,extract-share,check-share;verify-compose,verify-node,share-wrap,record-efp.verify-nodeandshare-wrapcheck, in order:dcap-qvl0.7.0);docs/at-rest-escrow.md: formats, commands, exit codes, and what is checked before a share is released.Dockerfilecopies the escrow crate (a workspace member), andrelease-plz.tomlmarks itrelease = false.Node dependency graph
cargo tree -p tinycloud-node -e featuresis identical to main.alloc/std/default/ecdh/derive/const-generics);serde_jsonis unchanged.Tests (local,
--locked)RUSTFLAGS=-Dwarnings cargo clippy --workspace --all-targetsis clean.cargo test --workspace --no-fail-fastagainst a local PG14 matches main exactly. On both main and this head, the same 5 environment-specific tests fail: the TC-320 collation test and 4postgres_pool_timeoutsblackhole tests.Next in the stack: #326 (core keyring/store/migration,
DataKeyProvider), then #327 (node wiring: config, gate, locked mode, recovery routes). Both stay off by default. This branch includes current main (merged in).tinycloud_at_rest_escrow::composereadsapp-compose.jsonstrictly. The CLI'sverify-composeand the node use the same reader. It requires:runnerisdocker-compose;imagepinned as<name>[:tag]@sha256:<64 hex>, with nobuild,extendsorinclude;verify-composeprints those escrow values and every other app-compose setting in full. All untrusted text the CLI echoes is escaped. The production compose's one non-ASCII comment character is replaced.