Start versioned quorum bundle dispatch #15

Merged
caution-bot merged 0 commits from feat/issue-11-versioned-bundle-dispatch into main 2026-10-11 22:14:33 +00:00
caution-bot commented 2026-07-19 23:03:00 +00:00 (Migrated from codeberg.org)

Summary

Implements proofed V1 quorum generation and verified loading, plus WebAuthn-authorized recryption of Caution-held shares to an attested destination. Supports external-PGP, WebAuthn and mixed holders while preserving the existing holder-signed OpenPGP transport.

Implementation head: Locksmith 2da3be5; integrated by Platform e38a05b, whose shared models/client dependencies and default enclave daemon all select this Locksmith revision. Historical proof verification uses Bootproof 821b5c6.

  • Keymaker preserves structured holder/credential associations and proof-bound threshold/max. It rejects duplicate holder identities and shared signing/encryption material between holders; equivalent encryption subkeys within one holder remain valid.
  • Current proofed-V1 loading authenticates historical generation evidence against independently configured Keymaker PCR policy. V0/unproofed/earlier incompatible V1 are rejected without fallback or upgrade.
  • Custody verifies bundle/CA/credential context, fresh destination evidence and PCRs, and WebAuthn user verification; it consumes authorization once and returns only destination-encrypted, holder-signed shares. Certified derivation indices remain independent of holder ordering, including subset/reordered bundles.
  • Certificate issuance requires a backend bearer token. Public release routes retain separate WebAuthn authorization. Readiness checks, generation/release worker limits, deadlines and session quotas bound work.
  • The custody root survives HTTP-process restart in Keyfork; pending approvals do not. Full enclave restart requires recovery of the same root with the external-PGP quorum.
  • Smartcard prompts identify each operation, retain terminal context and disable echo before displaying the PIN prompt.

Validation

Recorded local/synthetic evidence, not deployed-Nitro acceptance:

  • September 19: Keymaker host suite 10 tests; gated synthetic release suite 10 tests, including certified-index-1, reordered and mixed-holder recovery. See release behavior and September 19 regressions.
  • Earlier hardening snapshot: Locksmith default/unsafe suites 38/39, certificate-service suites 18/19, authenticated issuance/mixed recovery, timeout/disconnect admission and encrypted-input checks. See hardening validation; those counts describe that snapshot, not a new full-suite run at this head.
  • Platform's September 19 integration checks and aligned pins are recorded in Platform recovery and validation. Physical-card/real-passkey and live-Nitro acceptance for the current candidate are not yet recorded.

Remaining work and boundaries

Fresh review and merge remain required; the old change-request review is stale and is not treated as resolved by this description update. The broader roadmap still requires hosted Keymaker access control/network restrictions, production custody procedures, shared hash/profile contract finalization and dashboard creation. Rebuild the affected services and independently verify their PCR policies when deploying; a client upgrade alone does not update them. Existing bundles with shared encryption material are not repaired by stricter new-generation validation.

Legacy deployments must retain their original recovery artifacts and compatible tooling. A new quorum is a different key, not an automatic migration. Use the migration and acceptance runbook and record exact revisions/PCRs and issuance, threshold, negative and restart outcomes.

Refs https://codeberg.org/caution/locksmith/issues/10, https://codeberg.org/caution/locksmith/issues/11 and https://codeberg.org/caution/locksmith/issues/12.

Service contract: https://codeberg.org/caution/platform/issues/383. Platform integration: https://codeberg.org/caution/platform/issues/384. Design: https://codeberg.org/caution/locksmith/issues/7.

## Summary Implements proofed V1 quorum generation and verified loading, plus WebAuthn-authorized recryption of Caution-held shares to an attested destination. Supports external-PGP, WebAuthn and mixed holders while preserving the existing holder-signed OpenPGP transport. Implementation head: [Locksmith `2da3be5`](https://codeberg.org/caution/locksmith/commit/2da3be50bebd2dfdc4d0d3a94d05f55be02e910c); integrated by [Platform `e38a05b`](https://codeberg.org/caution/platform/commit/e38a05bf54dcd51f48971cbf2ca70884ffd8e812), whose shared models/client dependencies and default enclave daemon all select this Locksmith revision. Historical proof verification uses [Bootproof `821b5c6`](https://codeberg.org/caution/bootproof/commit/821b5c63e80f082f6d67ba3695c11416933489ec). - Keymaker preserves structured holder/credential associations and proof-bound `threshold`/`max`. It rejects duplicate holder identities and shared signing/encryption material between holders; equivalent encryption subkeys within one holder remain valid. - Current proofed-V1 loading authenticates historical generation evidence against independently configured Keymaker PCR policy. V0/unproofed/earlier incompatible V1 are rejected without fallback or upgrade. - Custody verifies bundle/CA/credential context, fresh destination evidence and PCRs, and WebAuthn user verification; it consumes authorization once and returns only destination-encrypted, holder-signed shares. Certified derivation indices remain independent of holder ordering, including subset/reordered bundles. - Certificate issuance requires a backend bearer token. Public release routes retain separate WebAuthn authorization. Readiness checks, generation/release worker limits, deadlines and session quotas bound work. - The custody root survives HTTP-process restart in Keyfork; pending approvals do not. Full enclave restart requires recovery of the same root with the external-PGP quorum. - Smartcard prompts identify each operation, retain terminal context and disable echo before displaying the PIN prompt. ## Validation Recorded local/synthetic evidence, not deployed-Nitro acceptance: - September 19: Keymaker host suite 10 tests; gated synthetic release suite 10 tests, including certified-index-1, reordered and mixed-holder recovery. See [release behavior and September 19 regressions](https://codeberg.org/caution/locksmith/src/commit/2da3be50bebd2dfdc4d0d3a94d05f55be02e910c/docs/share-release.md). - Earlier hardening snapshot: Locksmith default/unsafe suites 38/39, certificate-service suites 18/19, authenticated issuance/mixed recovery, timeout/disconnect admission and encrypted-input checks. See [hardening validation](https://codeberg.org/caution/locksmith/src/commit/2da3be50bebd2dfdc4d0d3a94d05f55be02e910c/docs/hardening-validation.md); those counts describe that snapshot, not a new full-suite run at this head. - Platform's September 19 integration checks and aligned pins are recorded in [Platform recovery and validation](https://codeberg.org/caution/platform/src/commit/e38a05bf54dcd51f48971cbf2ca70884ffd8e812/docs/share-recovery.md). Physical-card/real-passkey and live-Nitro acceptance for the current candidate are **not yet recorded**. ## Remaining work and boundaries Fresh review and merge remain required; the old change-request review is stale and is not treated as resolved by this description update. The broader roadmap still requires hosted Keymaker access control/network restrictions, production custody procedures, shared hash/profile contract finalization and dashboard creation. Rebuild the affected services and independently verify their PCR policies when deploying; a client upgrade alone does not update them. Existing bundles with shared encryption material are not repaired by stricter new-generation validation. Legacy deployments must retain their original recovery artifacts and compatible tooling. A new quorum is a different key, not an automatic migration. Use the [migration and acceptance runbook](https://codeberg.org/caution/locksmith/src/commit/2da3be50bebd2dfdc4d0d3a94d05f55be02e910c/docs/service-hardening.md) and record exact revisions/PCRs and issuance, threshold, negative and restart outcomes. ## Related issues Refs https://codeberg.org/caution/locksmith/issues/10, https://codeberg.org/caution/locksmith/issues/11 and https://codeberg.org/caution/locksmith/issues/12. Service contract: https://codeberg.org/caution/platform/issues/383. Platform integration: https://codeberg.org/caution/platform/issues/384. Design: https://codeberg.org/caution/locksmith/issues/7.
caution-bot commented 2026-07-20 00:12:51 +00:00 (Migrated from codeberg.org)

Follow-up cleanup pushed in 91a33e7fa3ed457b867a3087407b93d915caa5df:

  • Reverted format-only churn in touched existing files where it was not needed for the change.
  • Removed one redundant WebAuthn preservation assertion; kept the focused tests that protect the new versioned/proofed bundle contract and fail-closed loading behavior.

Rechecked:

  • cargo test -p keymaker-models — passed
  • cargo test -p locksmith bundle::tests:: — passed, with existing warnings
  • cargo check --workspace --all-targets — passed, with existing warnings
  • git diff --check origin/main...HEAD — passed
Follow-up cleanup pushed in `91a33e7fa3ed457b867a3087407b93d915caa5df`: - Reverted format-only churn in touched existing files where it was not needed for the change. - Removed one redundant WebAuthn preservation assertion; kept the focused tests that protect the new versioned/proofed bundle contract and fail-closed loading behavior. Rechecked: - `cargo test -p keymaker-models` — passed - `cargo test -p locksmith bundle::tests::` — passed, with existing warnings - `cargo check --workspace --all-targets` — passed, with existing warnings - `git diff --check origin/main...HEAD` — passed
vkobel commented 2026-07-20 10:23:53 +00:00 (Migrated from codeberg.org)

Review: Request changes

This patch introduces four P1 regressions:

  1. Canonicalize labels before hashing bundles
    crates/keymaker-models/src/lib.rs:77

    label is a HashMap, so CBOR serialization order is nondeterministic. Keymaker and Locksmith may therefore hash the same logical bundle differently after a JSON round trip, causing nonce mismatches and failed necroproof verification.

    Please use a canonical map/CBOR representation and add a round-trip hashing test with multiple labels.

  2. Validate durable proofs at their signing time
    crates/locksmith/src/bundle.rs:170

    Verifying the Nitro certificate chain against the current wall clock makes persisted bundles unloadable once the attestation certificate expires.

    Please validate certificate validity at the signed attestation timestamp while continuing to evaluate PCR-policy expiry against the current time.

  3. Ship or provision the required PCR policy
    crates/locksmith/src/bin/locksmithd.rs:5

    Startup now requires /etc/caution/keymaker-pcr-policy.json, but the repository image neither includes nor mounts it. locksmithd therefore panics before opening the shard listener.

    Please add the policy artifact to the image or explicitly provision/mount it in the deployment.

  4. Replace or migrate the legacy bundled fixture
    crates/locksmith/src/bin/locksmithd.rs:9

    Docker still packages bundle-single.json, a flat V0 response with an empty necroproof. The new loader only accepts proofed, versioned bundles, so startup still fails even after supplying the PCR policy.

    Please package a valid proofed V1 bundle or provide a migration path for the legacy format.

## Review: Request changes This patch introduces four P1 regressions: 1. **Canonicalize labels before hashing bundles** `crates/keymaker-models/src/lib.rs:77` `label` is a `HashMap`, so CBOR serialization order is nondeterministic. Keymaker and Locksmith may therefore hash the same logical bundle differently after a JSON round trip, causing nonce mismatches and failed necroproof verification. Please use a canonical map/CBOR representation and add a round-trip hashing test with multiple labels. 2. **Validate durable proofs at their signing time** `crates/locksmith/src/bundle.rs:170` Verifying the Nitro certificate chain against the current wall clock makes persisted bundles unloadable once the attestation certificate expires. Please validate certificate validity at the signed attestation timestamp while continuing to evaluate PCR-policy expiry against the current time. 3. **Ship or provision the required PCR policy** `crates/locksmith/src/bin/locksmithd.rs:5` Startup now requires `/etc/caution/keymaker-pcr-policy.json`, but the repository image neither includes nor mounts it. `locksmithd` therefore panics before opening the shard listener. Please add the policy artifact to the image or explicitly provision/mount it in the deployment. 4. **Replace or migrate the legacy bundled fixture** `crates/locksmith/src/bin/locksmithd.rs:9` Docker still packages `bundle-single.json`, a flat V0 response with an empty necroproof. The new loader only accepts proofed, versioned bundles, so startup still fails even after supplying the PCR policy. Please package a valid proofed V1 bundle or provide a migration path for the legacy format.
vkobel commented 2026-07-20 11:35:49 +00:00 (Migrated from codeberg.org)

Proposed plan

Summary

  • Make V1 proof hashes canonical and stable across JSON round trips.
  • Add signed-attestation-time verification to Bootproof, then consume it from Locksmith.
  • Keep V1-only fail-closed behavior; do not add V0 migration.
  • Replace Docker’s legacy fixture with a genuine proofed V1 demo bundle and matching PCR policy.

Implementation Changes

Canonical bundle hashing

  • Convert GenerateQuorumBundle to serde_cbor::Value before CBOR serialization; Value maps use canonical ordering.
  • Keep existing JSON types and HashMap fields unchanged.
  • Treat the canonical encoding as the definitive V1 hash format; regenerate existing V1 proofs rather than supporting the broken encoding.

Durable Nitro proof verification

  • In Bootproof, add Nitro::verify_at_attestation_time(nonce).
  • Extract the signed Nitro timestamp as milliseconds since Unix epoch from the COSE payload.
  • Use that timestamp only for certificate-chain validity; the same operation must still verify the COSE signature, nonce, and PCRs so an altered timestamp fails.
  • Preserve the existing caller-time verify(time, nonce) API.
  • Pin Locksmith to the exact merged Bootproof commit.
  • Remove wall-clock time from NecroproofVerifier::verify; retain now on bundle-loading APIs exclusively for PCR-policy expiry.

Docker artifacts

  • Deploy the patched one-shot Keymaker from the exact source commit and verify it with caution verify.
  • Generate a one-participant V1 demo bundle using the existing demo public certificate with threshold = max = 1.
  • Extract PCR0/1/2 from the generated proof and cross-check them against the verified Keymaker deployment.
  • Replace bundle-single.json with that proofed V1 response.
  • Add keymaker-pcr-policy.json containing the matching PCR0/1/2 set with no expiry.
  • Copy both files through the Docker builder rootfs, set mode 0644 in-container, and remove the final-stage legacy ADD.
  • Record the generating Keymaker source commit beside the Docker fixture configuration.

Public Interfaces and Compatibility

  • New Bootproof API: Nitro::verify_at_attestation_time.
  • NecroproofVerifier::verify no longer accepts a current-time argument.
  • JSON bundle shape remains unchanged.
  • V0 and empty-necroproof bundles remain rejected.
  • Previously generated V1 proofs must be regenerated because the hash encoding changes.
  • Platform-wide runtime policy provisioning remains a separate follow-up; this PR fixes the reviewed repository Docker image with tracked demo artifacts.

Test Plan

  • Bootproof:
    • Stored fixture verifies through verify_at_attestation_time.
    • The same fixture fails caller-time verification after certificate expiry.
    • Mutating, removing, or changing the timestamp fails closed.
  • Keymaker models:
    • Multi-label hashes match across JSON serialization/deserialization.
    • Different HashMap insertion orders produce identical hashes.
    • Changing any bundle field changes the hash.
  • Locksmith:
    • Packaged V1 bundle and PCR policy load successfully with now set far beyond certificate expiry.
    • Expired PCR policies still reject using current wall-clock time.
    • V0, empty proof, wrong PCR, nonce mismatch, and bundle mutation remain rejected.
  • Integration:
    • Run Bootproof SDK tests.
    • Run cargo test --workspace and cargo check --workspace --all-targets.
    • Build the repository Docker image and confirm locksmithd remains running/listening instead of panicking during startup.
    • Run formatting and git diff --check.

Assumptions

  • PR #15 intentionally remains proofed V1-only despite issue #11’s older V0-fallback wording.
  • Demo bundle, PCRs, and encrypted fixture data are public test artifacts, not production secrets.
  • The demo PCR policy intentionally has no expiry so the durable fixture remains testable.
# Proposed plan ## Summary - Make V1 proof hashes canonical and stable across JSON round trips. - Add signed-attestation-time verification to Bootproof, then consume it from Locksmith. - Keep V1-only fail-closed behavior; do not add V0 migration. - Replace Docker’s legacy fixture with a genuine proofed V1 demo bundle and matching PCR policy. ## Implementation Changes ### Canonical bundle hashing - Convert `GenerateQuorumBundle` to `serde_cbor::Value` before CBOR serialization; `Value` maps use canonical ordering. - Keep existing JSON types and `HashMap` fields unchanged. - Treat the canonical encoding as the definitive V1 hash format; regenerate existing V1 proofs rather than supporting the broken encoding. ### Durable Nitro proof verification - In Bootproof, add `Nitro::verify_at_attestation_time(nonce)`. - Extract the signed Nitro `timestamp` as milliseconds since Unix epoch from the COSE payload. - Use that timestamp only for certificate-chain validity; the same operation must still verify the COSE signature, nonce, and PCRs so an altered timestamp fails. - Preserve the existing caller-time `verify(time, nonce)` API. - Pin Locksmith to the exact merged Bootproof commit. - Remove wall-clock time from `NecroproofVerifier::verify`; retain `now` on bundle-loading APIs exclusively for PCR-policy expiry. ### Docker artifacts - Deploy the patched one-shot Keymaker from the exact source commit and verify it with `caution verify`. - Generate a one-participant V1 demo bundle using the existing demo public certificate with `threshold = max = 1`. - Extract PCR0/1/2 from the generated proof and cross-check them against the verified Keymaker deployment. - Replace `bundle-single.json` with that proofed V1 response. - Add `keymaker-pcr-policy.json` containing the matching PCR0/1/2 set with no expiry. - Copy both files through the Docker builder rootfs, set mode `0644` in-container, and remove the final-stage legacy `ADD`. - Record the generating Keymaker source commit beside the Docker fixture configuration. ## Public Interfaces and Compatibility - New Bootproof API: `Nitro::verify_at_attestation_time`. - `NecroproofVerifier::verify` no longer accepts a current-time argument. - JSON bundle shape remains unchanged. - V0 and empty-necroproof bundles remain rejected. - Previously generated V1 proofs must be regenerated because the hash encoding changes. - Platform-wide runtime policy provisioning remains a separate follow-up; this PR fixes the reviewed repository Docker image with tracked demo artifacts. ## Test Plan - Bootproof: - Stored fixture verifies through `verify_at_attestation_time`. - The same fixture fails caller-time verification after certificate expiry. - Mutating, removing, or changing the timestamp fails closed. - Keymaker models: - Multi-label hashes match across JSON serialization/deserialization. - Different `HashMap` insertion orders produce identical hashes. - Changing any bundle field changes the hash. - Locksmith: - Packaged V1 bundle and PCR policy load successfully with `now` set far beyond certificate expiry. - Expired PCR policies still reject using current wall-clock time. - V0, empty proof, wrong PCR, nonce mismatch, and bundle mutation remain rejected. - Integration: - Run Bootproof SDK tests. - Run `cargo test --workspace` and `cargo check --workspace --all-targets`. - Build the repository Docker image and confirm `locksmithd` remains running/listening instead of panicking during startup. - Run formatting and `git diff --check`. ## Assumptions - PR #15 intentionally remains proofed V1-only despite issue #11’s older V0-fallback wording. - Demo bundle, PCRs, and encrypted fixture data are public test artifacts, not production secrets. - The demo PCR policy intentionally has no expiry so the durable fixture remains testable.
caution-bot commented 2026-07-20 17:10:32 +00:00 (Migrated from codeberg.org)

Follow-up pushed in c0dae43:

  • Made V1 bundle hashes canonical by hashing a serde_cbor Value and added multi-label insertion-order/JSON round-trip coverage.
  • Changed Locksmith bundle loading to use the keymaker-models GenerateQuorumBundle type directly, with only a local extension trait for existing OpenPGP accessors.
  • Replaced the verifier trait with KeymakerPcrPolicy methods, renamed policy JSON from allowed to sets, and validates PCR-set expiry at the signed necroproof timestamp.
  • Verifies Nitro proofs at the attestation timestamp extracted from the signed COSE payload instead of using caller wall-clock time.
  • Updated the keymaker-client generate example to split keyring.asc into individual armored OpenPGP keys.

Verification:

  • cargo test -p keymaker-models — passed
  • cargo test -p locksmith bundle::tests:: — passed, with existing warnings
  • cargo check -p keymaker --all-targets — passed, with existing warning
  • cargo check -p keymaker-client --examples — passed
  • cargo check -p locksmith --all-targets — passed, with existing warnings
  • git diff --check — passed

Note: I left the GenerateNecroproof error conversion in explicit map_err form because this dependency currently returns Box<dyn Error + Send + Sync> and dterror::ResultExt::with_contexts is not available for that concrete error type in this workspace.

Follow-up pushed in `c0dae43`: - Made V1 bundle hashes canonical by hashing a serde_cbor Value and added multi-label insertion-order/JSON round-trip coverage. - Changed Locksmith bundle loading to use the `keymaker-models` `GenerateQuorumBundle` type directly, with only a local extension trait for existing OpenPGP accessors. - Replaced the verifier trait with `KeymakerPcrPolicy` methods, renamed policy JSON from `allowed` to `sets`, and validates PCR-set expiry at the signed necroproof timestamp. - Verifies Nitro proofs at the attestation timestamp extracted from the signed COSE payload instead of using caller wall-clock time. - Updated the keymaker-client generate example to split `keyring.asc` into individual armored OpenPGP keys. Verification: - `cargo test -p keymaker-models` — passed - `cargo test -p locksmith bundle::tests::` — passed, with existing warnings - `cargo check -p keymaker --all-targets` — passed, with existing warning - `cargo check -p keymaker-client --examples` — passed - `cargo check -p locksmith --all-targets` — passed, with existing warnings - `git diff --check` — passed Note: I left the `GenerateNecroproof` error conversion in explicit `map_err` form because this dependency currently returns `Box<dyn Error + Send + Sync>` and `dterror::ResultExt::with_contexts` is not available for that concrete error type in this workspace.
caution-bot commented 2026-07-20 19:36:34 +00:00 (Migrated from codeberg.org)

Addressed the latest review comments in 0339414.

Summary:

  • Removed the local QuorumBundleExt/accessor trait and the legacy openpgp_keyring() helper path.
  • Updated shard send/receive to convert the shared bundle with .to_latest() and match directly on the V1 Vec<Key> entries; OpenPGP certs are handled at the use site and WebAuthn remains an explicit unimplemented!() path for now.
  • Removed direct COSE wrapper decoding from necroproof verification and dropped the now-unused coset dependency. PCR policy expiry is now checked against the timestamp read from the Nitro payload returned by a successful attestation.verify(...).
  • Added AGENTS.md guidance so future agent runs avoid the same mistakes around Codeberg inline comments, local bundle wrapper/accessor traits, direct COSE decoding, and formatter pitfalls.

Verification:

  • rustfmt --edition 2024 crates/locksmith/src/bundle.rs crates/locksmith/src/client.rs crates/locksmith/src/server.rs
  • cargo test -p keymaker-models
  • cargo test -p locksmith bundle::tests:: --no-fail-fast
  • cargo check -p keymaker --all-targets
  • cargo check -p keymaker-client --examples
  • cargo check -p locksmith --all-targets
  • git diff --check

The existing warnings are unchanged/pre-existing (minipgp6 cfg, unused now, keymaker reboot unreachable-code warning, and get_shards_test_util). Whole-workspace cargo fmt is still not used because the existing minipgp6.rs module-resolution issue blocks it; targeted rustfmt was used on touched Rust files.

Addressed the latest review comments in `0339414`. Summary: - Removed the local `QuorumBundleExt`/accessor trait and the legacy `openpgp_keyring()` helper path. - Updated shard send/receive to convert the shared bundle with `.to_latest()` and match directly on the V1 `Vec<Key>` entries; OpenPGP certs are handled at the use site and WebAuthn remains an explicit `unimplemented!()` path for now. - Removed direct COSE wrapper decoding from necroproof verification and dropped the now-unused `coset` dependency. PCR policy expiry is now checked against the timestamp read from the Nitro payload returned by a successful `attestation.verify(...)`. - Added `AGENTS.md` guidance so future agent runs avoid the same mistakes around Codeberg inline comments, local bundle wrapper/accessor traits, direct COSE decoding, and formatter pitfalls. Verification: - `rustfmt --edition 2024 crates/locksmith/src/bundle.rs crates/locksmith/src/client.rs crates/locksmith/src/server.rs` - `cargo test -p keymaker-models` - `cargo test -p locksmith bundle::tests:: --no-fail-fast` - `cargo check -p keymaker --all-targets` - `cargo check -p keymaker-client --examples` - `cargo check -p locksmith --all-targets` - `git diff --check` The existing warnings are unchanged/pre-existing (`minipgp6` cfg, unused `now`, keymaker reboot unreachable-code warning, and `get_shards_test_util`). Whole-workspace `cargo fmt` is still not used because the existing `minipgp6.rs` module-resolution issue blocks it; targeted rustfmt was used on touched Rust files.
caution-bot commented 2026-07-21 05:48:52 +00:00 (Migrated from codeberg.org)

Latest follow-up is already on the PR branch at e1a3aa8.

Summary:

  • Removed the accidentally tracked local AGENTS.md; the PR file list now contains no AGENTS.md.
  • Kept AGENTS.md ignored so local agent guidance is not committed again.
  • Simplified bundle verification per review follow-up by using the verified Nitro payload directly and removing the direct COSE decoding path/dependency from Locksmith.

Rechecked now:

  • cargo test -p keymaker-models — passed
  • cargo test -p locksmith bundle::tests:: --no-fail-fast — passed, with existing warnings
  • cargo check -p locksmith --all-targets — passed, with existing warnings
  • git diff --check origin/main...HEAD — passed

PR state verified: mergeable; remote file list has no AGENTS.md.

Latest follow-up is already on the PR branch at `e1a3aa8`. Summary: - Removed the accidentally tracked local `AGENTS.md`; the PR file list now contains no `AGENTS.md`. - Kept `AGENTS.md` ignored so local agent guidance is not committed again. - Simplified bundle verification per review follow-up by using the verified Nitro payload directly and removing the direct COSE decoding path/dependency from Locksmith. Rechecked now: - `cargo test -p keymaker-models` — passed - `cargo test -p locksmith bundle::tests:: --no-fail-fast` — passed, with existing warnings - `cargo check -p locksmith --all-targets` — passed, with existing warnings - `git diff --check origin/main...HEAD` — passed PR state verified: mergeable; remote file list has no `AGENTS.md`.
caution-bot commented 2026-07-22 00:58:33 +00:00 (Migrated from codeberg.org)

Pushed follow-up 707bcdc to the existing PR branch.

Summary:

  • Added explicitly unsafe local/e2e hooks so public-cert-service and keymaker can be exercised together on a normal dev host without Nitro/offline entropy.
  • Added LOCKSMITHD_UNSAFE_TEST_SECRET_HEX for deterministic local keyforkd startup.
  • Added CAUTION_UNSAFE_KEY_SERVICE_E2E fake necroproof/deterministic entropy behavior for local service e2e only.
  • Added warning log context when public certificate derivation fails.

Verification run locally:

  • cargo test -p public-cert-service -p keymaker -- --nocapture — passed; public-cert-service 12 passed, keymaker test binary passed.

Note: production still needs real deployment/supervision and Nitro/bootproof proofing; these hooks are deliberately named unsafe and are not default-enabled.

Pushed follow-up `707bcdc` to the existing PR branch. Summary: - Added explicitly unsafe local/e2e hooks so public-cert-service and keymaker can be exercised together on a normal dev host without Nitro/offline entropy. - Added `LOCKSMITHD_UNSAFE_TEST_SECRET_HEX` for deterministic local keyforkd startup. - Added `CAUTION_UNSAFE_KEY_SERVICE_E2E` fake necroproof/deterministic entropy behavior for local service e2e only. - Added warning log context when public certificate derivation fails. Verification run locally: - `cargo test -p public-cert-service -p keymaker -- --nocapture` — passed; public-cert-service 12 passed, keymaker test binary passed. Note: production still needs real deployment/supervision and Nitro/bootproof proofing; these hooks are deliberately named unsafe and are not default-enabled.
vkobel commented 2026-09-15 14:14:27 +00:00 (Migrated from codeberg.org)

Summary:

  • Extended the existing non-default unsafe-e2e feature to let the shared bundle loader consume Keymaker’s existing synthetic proof.
  • Acceptance requires CAUTION_UNSAFE_KEY_SERVICE_E2E=1, the exact documented test PCR policy, and a proof matching the nonce recomputed from the canonical bundle hash.
  • Default builds reject synthetic proofs even with the environment flag set. Normal Nitro verification, loader signatures and the production bundle format are unchanged.
  • Added regression tests and documented the test configuration and remaining release dependencies.

Verification:

  • Synthetic-proof tests — passed in default and unsafe-e2e builds, with the runtime flag absent, disabled and enabled.
  • Altered bundles, wrong proofs and incorrect test policies — rejected.
  • Platform mock E2E against this published revision — passed, covering actual gateway passkey authorization, API creation/upload/download/deletion, direct CLI creation and encryption with downloaded bundles.

Remaining:

  • V0 fallback/upgrade is deferred under #11 within this PR; it was not implemented in this pass.
  • WebAuthn recryption remains under #12. Platform’s WebAuthn/mixed creation also remains blocked on certificate-service proof verification.
  • Real Nitro validation, genuine deployment artifacts and production policy provisioning are still required before release.
  • The design and holder-association requirements in #7 remain authoritative. Mock integration does not establish production attestation or recryption readiness, and does not complete those tickets.
### Summary: - Extended the existing non-default unsafe-e2e feature to let the shared bundle loader consume Keymaker’s existing synthetic proof. - Acceptance requires CAUTION_UNSAFE_KEY_SERVICE_E2E=1, the exact documented test PCR policy, and a proof matching the nonce recomputed from the canonical bundle hash. - Default builds reject synthetic proofs even with the environment flag set. Normal Nitro verification, loader signatures and the production bundle format are unchanged. - Added regression tests and documented the test configuration and remaining release dependencies. ### Verification: - Synthetic-proof tests — passed in default and unsafe-e2e builds, with the runtime flag absent, disabled and enabled. - Altered bundles, wrong proofs and incorrect test policies — rejected. - Platform mock E2E against this published revision — passed, covering actual gateway passkey authorization, API creation/upload/download/deletion, direct CLI creation and encryption with downloaded bundles. ### Remaining: - V0 fallback/upgrade is deferred under #11 within this PR; it was not implemented in this pass. - WebAuthn recryption remains under #12. Platform’s WebAuthn/mixed creation also remains blocked on certificate-service proof verification. - Real Nitro validation, genuine deployment artifacts and production policy provisioning are still required before release. - The design and holder-association requirements in #7 remain authoritative. Mock integration does not establish production attestation or recryption readiness, and does not complete those tickets.
caution-bot commented 2026-10-01 18:22:53 +00:00 (Migrated from codeberg.org)

Outstanding review and production-release gates

Reviewed current head: dc7409d2d853221185cd5a085f4d1880fcf53348, against 7b411721068944fcae89acb3ed2b8c692689383f. Platform #391 currently consumes accc9d36c3c47fc1ea2802f46266f508a19f02d0; the scan distinguished that integration pin from this newer head.

No new High/Critical vulnerability or new code-level security merge blocker was confirmed by the Kimi source review and independent validation. That is not production approval. The remaining gates need to be kept distinct:

Review clearance

Codeberg still records an undismissed REQUEST_CHANGES review from ryansquared against the much older 91a33e7fa3ed457b867a3087407b93d915caa5df (review ID 1605224). Please obtain a fresh maintainer disposition for the current head. This is not a claim that the original requested changes remain unfixed, nor a claim that Codeberg mechanically prevents merging; the PR body already correctly identifies the old review as stale.

Production-release gates, not newly introduced regressions

  • Bound recovery framing before exposing the bootstrap receiver to untrusted clients. The pinned keyfork-frame 0.1.1 asynchronous decoder (src/asyncext.rs:20–24) allocates a peer-specified frame length before reading its contents. Locksmith reaches that decoder before holder authentication at server.rs:178–181; the reviewed receive path lacks a frame-size cap and read deadline. This is an inherited, deployment-dependent availability risk, not a demonstrated production incident. Cap size before allocation, bound concurrent receivers and add read deadlines; validate under constrained memory. Do not interpret allocation size as guaranteed immediate physical-memory consumption.
  • Verify the intended hosted-service access restrictions. Hosted Keymaker/issuance must have the intended API-only access controls; the certificate bearer check alone does not establish network isolation. Keep public WebAuthn-authorized release distinct from issuance/generation. No live firewall or production exposure was inspected in this review.
  • Publish the actual measured deployment source and record real acceptance. Coordinate with the source-reproduction blocker on Platform #391: replacing root HCL and injecting measured public/encrypted bootstrap files requires a retrievable advertised snapshot containing those inputs, not merely the unchanged upstream recipe. Never publish private keys or plaintext secrets, and retain PCR mismatch rejection. Record exact deployed revisions/PCRs and genuine issuance, threshold recovery, negative/replay and restart results; local synthetic evidence does not supply this acceptance.

Existing bundles also retain their embedded holder credential snapshots: deleting a platform credential is not revocation of its authority in previously issued bundles. Keep that documented lifecycle limitation explicit rather than presenting deletion/reset as a completed revocation mechanism.

Evidence boundary: source-only review; no tests, builds, service probes or deployments were run. The unauthenticated X25519-crash candidate was rejected because holder-signature verification precedes the assertion; it is not a blocker. These comments do not resolve prior review state or claim that production-release gates have been satisfied.

## Outstanding review and production-release gates Reviewed current head: `dc7409d2d853221185cd5a085f4d1880fcf53348`, against `7b411721068944fcae89acb3ed2b8c692689383f`. Platform #391 currently consumes `accc9d36c3c47fc1ea2802f46266f508a19f02d0`; the scan distinguished that integration pin from this newer head. **No new High/Critical vulnerability or new code-level security merge blocker was confirmed by the Kimi source review and independent validation. That is not production approval.** The remaining gates need to be kept distinct: ### Review clearance Codeberg still records an undismissed `REQUEST_CHANGES` review from `ryansquared` against the much older `91a33e7fa3ed457b867a3087407b93d915caa5df` (review ID `1605224`). Please obtain a fresh maintainer disposition for the current head. This is **not** a claim that the original requested changes remain unfixed, nor a claim that Codeberg mechanically prevents merging; the PR body already correctly identifies the old review as stale. ### Production-release gates, not newly introduced regressions - **Bound recovery framing before exposing the bootstrap receiver to untrusted clients.** The pinned `keyfork-frame 0.1.1` asynchronous decoder (`src/asyncext.rs:20–24`) allocates a peer-specified frame length before reading its contents. Locksmith reaches that decoder before holder authentication at [server.rs:178–181](https://codeberg.org/caution/locksmith/src/commit/dc7409d2d853221185cd5a085f4d1880fcf53348/crates/locksmith/src/server.rs#L178-L181); the reviewed receive path lacks a frame-size cap and read deadline. This is an inherited, deployment-dependent availability risk, not a demonstrated production incident. Cap size before allocation, bound concurrent receivers and add read deadlines; validate under constrained memory. Do not interpret allocation size as guaranteed immediate physical-memory consumption. - **Verify the intended hosted-service access restrictions.** Hosted Keymaker/issuance must have the intended API-only access controls; the certificate bearer check alone does not establish network isolation. Keep public WebAuthn-authorized release distinct from issuance/generation. No live firewall or production exposure was inspected in this review. - **Publish the actual measured deployment source and record real acceptance.** Coordinate with the source-reproduction blocker on [Platform #391](https://codeberg.org/caution/platform/pulls/391): replacing root HCL and injecting measured public/encrypted bootstrap files requires a retrievable advertised snapshot containing those inputs, not merely the unchanged upstream recipe. Never publish private keys or plaintext secrets, and retain PCR mismatch rejection. Record exact deployed revisions/PCRs and genuine issuance, threshold recovery, negative/replay and restart results; local synthetic evidence does not supply this acceptance. Existing bundles also retain their embedded holder credential snapshots: deleting a platform credential is not revocation of its authority in previously issued bundles. Keep that documented lifecycle limitation explicit rather than presenting deletion/reset as a completed revocation mechanism. **Evidence boundary:** source-only review; no tests, builds, service probes or deployments were run. The unauthenticated X25519-crash candidate was rejected because holder-signature verification precedes the assertion; it is not a blocker. These comments do not resolve prior review state or claim that production-release gates have been satisfied.
vkobel commented 2026-10-05 09:38:11 +00:00 (Migrated from codeberg.org)
  • Addressed recovery framing in this update: lengths are checked before allocation, active connections are capped at 32, and each connection has a five-minute deadline. The wire format and quorum rules are unchanged; overall quorum waiting remains unlimited.
  • Documented that deleting or resetting a Platform credential does not revoke its authority in existing quorum bundles.
  • Validation passed: Locksmith suite, synthetic recovery integration, and seven focused receiver tests under a 512 MiB Linux memory limit. These changes require rebuilding and deploying the updated Locksmith receiver.
    Deployment inputs remain on deploy/key-service and deploy/keymaker.
- Addressed recovery framing in this update: lengths are checked before allocation, active connections are capped at 32, and each connection has a five-minute deadline. The wire format and quorum rules are unchanged; overall quorum waiting remains unlimited. - Documented that deleting or resetting a Platform credential does not revoke its authority in existing quorum bundles. - Validation passed: Locksmith suite, synthetic recovery integration, and seven focused receiver tests under a 512 MiB Linux memory limit. These changes require rebuilding and deploying the updated Locksmith receiver. Deployment inputs remain on deploy/key-service and deploy/keymaker.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
public/locksmith!15
No description provided.