Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

## [Unreleased]
### Changes
- Encryption root and named keys read both v1 and TCW2 key wraps by default. The independent, default-off `key_wrap_require_v2` policy requires v2 incoming network-key wraps without restricting receiver responses. Response wraps remain v1 by default; `key_wrap_v2 = true` selects v2. V1 writers avoid the reserved TCW2 prefix, malformed surrogate headers are refused, and stored network secrets require encrypted seals. Descriptors and payload schemas are unchanged. Details: TC-2518
- Encryption network reader policy is checked during `/invoke` preflight, before replay reservation. Details: TC-2518
- Encryption: v2 column format with key ids, per-purpose keys and recorded format metadata. Optional strict reads are off by default. Details: TC-2516, TC-2517.
- Encryption network key-wrap v1 uses the explicit legacy column codec after the TC-2516 integration; wire bytes and default-off v2 writer flags are unchanged. Details: TC-2518.
- Deploys: the workflow supports an explicit, reason-recorded rollback to an earlier released dstack image on the unchanged N0 compose. It checks image labels, release tag, ancestry, and identical migration sources while preserving the normal forward-release guard.
- A new Policy/v3 registration records the share key its content source names (`share/<shareId>` on the owner's `default` network) in the registration's transaction, so publishing a share needs no `tinycloud.encryption/key.create` grant: the publisher encrypts to the key's public key and registers. A missing key is created at `keyVersion` 1 and counts toward the network's key limit; at the limit the registration answers 403 `key_limit_exceeded` and stores nothing. An existing key keeps its state. The registration now also requires the source's network to exist and be active. Docs: `docs/encryption-named-keys.md`. Details: TC-2525
- Share-email issuer trust bundles can pin one next key for the same issuer DID during an explicit UTC overlap window. The legacy key stops at `issuerNotAfter`; malformed, duplicate, unbounded or expired overlaps fail startup and `--validate-config`. Existing single-key bundles remain unchanged. This is node-side trust support only: the OpenCredentials witness and js-sdk policy contract must also support key rotation before activation. Older node images reject overlap fields; restore the previous single-key bundle before rollback. See `deploy/share-email/production-trust-bundle-contract.md`.
Expand Down
26 changes: 26 additions & 0 deletions docs/encryption-named-keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@ are refused.
A key is named by `urn:tinycloud:encryption:<owner>:<network>/<path>`. A prefix
grant is the same URN with one trailing `/`.

## Key-wrap formats

Root and named keys accept both `x25519-aes256gcm/v1` wraps and TCW2
`x25519-hkdf-aes256gcm/v2` wraps. Network and key descriptors keep the v1
algorithm identifier because their key material supports either format.
Request `alg` identifies the incoming wrap; response `alg` identifies the
returned receiver wrap independently.

`[global.encryption_network] key_wrap_v2 = false` keeps response writes on v1.
Set it to `true` (or `TINYCLOUD_ENCRYPTION_NETWORK__KEY_WRAP_V2=true`) only when
receiving clients support v2. Independently, `key_wrap_require_v2 = true` (or
`TINYCLOUD_ENCRYPTION_NETWORK__KEY_WRAP_REQUIRE_V2=true`) rejects v1 incoming
network-key wraps for root and named-key decrypt. This reader policy defaults
to `false` and does not require v2 receiver responses: v2 requests may still
receive signed v1 responses while `key_wrap_v2` remains off.
TCW2 uses X25519, HKDF-SHA256 and AES-256-GCM with a canonical authenticated
header binding the recipient, purpose, network, exact key path, key version
and string metadata. Receiver wraps use empty metadata. Key version is checked
against the network or named-key row before opening.
V1 writers reroll ephemeral public keys whose prefix is `TCW2`, keeping format
detection unambiguous. Header strings must be valid Unicode; malformed escaped
surrogates are rejected by JSON parsing. Stored network secrets and named-key
seeds require versioned encrypted seals, never plaintext.

Details: TC-2518

## Key paths

A path is 1 to 8 segments of `[a-z0-9][a-z0-9._-]{0,63}` joined by `/`, at most
Expand Down
Loading
Loading