Harden reusable keychain API

This commit is contained in:
Eric Wendland 2026-05-26 18:58:25 +02:00
commit b6ffcde54c
6 changed files with 410 additions and 33 deletions

View file

@ -26,6 +26,19 @@ The durable log is `KeychainOp[]` plus `KeychainOpSignature[]`. Each operation
has a deterministic canonical signing payload under the
`geth.keychain.v1@geth.local` namespace.
The namespace is part of a `KeychainProfile`. geth uses:
- `geth.keychain.v1@geth.local`
- `geth.node-enrollment-request.v1@geth.local`
- default admin principal `admin`
Other applications should create their own profile with explicit namespaces or
`KeychainProfile::for_application("<app>", "<domain>")`. For example,
`for_application("acme-notes", "example.com")` produces
`acme-notes.keychain.v1@example.com`. This prevents signatures from one
application's keychain from being replayed into another application's
keychain.
Important operation kinds:
- `KeychainInit`
@ -105,12 +118,31 @@ provide:
- ordered or unordered `KeychainOp[]`
- `KeychainOpSignature[]`
- a signature verification callback
- a `KeychainProfile`
- a `KeychainSignatureVerifier`
The callback is responsible for the cryptographic backend, such as
`ssh-keygen -Y verify`, WebCrypto, an HSM, or a test verifier. The crate owns
the replay order, bootstrap rule, previous-view authorization rule,
`allowed_signers` projection, and reduced keychain view.
The verifier is responsible for the cryptographic backend, such as
`ssh-keygen -Y verify`, WebCrypto, an HSM, a service-side verifier, or a test
verifier. The crate owns the replay order, bootstrap rule, profile namespace
check, previous-view authorization rule, `allowed_signers` projection, and
reduced keychain view.
Minimal reusable Rust shape:
```rust
let profile = geth_keychain::KeychainProfile::for_application(
"acme-notes",
"example.com",
)?;
let entries = geth_keychain::decode_sigchain_jsonl(sigchain_text)?;
let (ops, signatures) = geth_keychain::flatten_sigchain_entries(&entries);
let report = geth_keychain::verify_sigchain_with_profile(
&ops,
&signatures,
&profile,
&my_verifier,
);
```
## Static Sigchain File