Harden reusable keychain API
This commit is contained in:
parent
4013c868aa
commit
b6ffcde54c
6 changed files with 410 additions and 33 deletions
|
|
@ -352,13 +352,16 @@ are updated with signed `geth keychain admin-add` and `geth keychain
|
|||
admin-revoke` operations; `AdminKeyAdd` carries the public key material needed
|
||||
to reconstruct an OpenSSH `allowed_signers` view. `geth keychain verify` replays
|
||||
the log against the previously accepted admin-key view, mirroring the `git-skm`
|
||||
pattern of verifying key-registry changes from a prior trusted state. `geth
|
||||
keychain sync <node>` pulls keychain operations and signatures from an imported
|
||||
peer over Iroh and imports only operations with a valid OpenSSH signature from a
|
||||
currently trusted admin key over the canonical payload. See
|
||||
`docs/sigchain-keychain.md` for the detailed sigchain design. This is currently
|
||||
a pull-based signed operation log, not a CRDT or Keyhive-style convergent
|
||||
authority.
|
||||
pattern of verifying key-registry changes from a prior trusted state. The
|
||||
transport-neutral replay rules, application-specific signature namespaces,
|
||||
allowed-signers projection, and JSONL sigchain helpers live in `geth-keychain`
|
||||
so other applications can reuse the same identity-log model without depending
|
||||
on the daemon, SQLite, Iroh, or local control. `geth keychain sync <node>` pulls
|
||||
keychain operations and signatures from an imported peer over Iroh and imports
|
||||
only operations with a valid OpenSSH signature from a currently trusted admin
|
||||
key over the canonical payload. See `docs/sigchain-keychain.md` for the
|
||||
detailed sigchain design. This is currently a pull-based signed operation log,
|
||||
not a CRDT or Keyhive-style convergent authority.
|
||||
|
||||
New devices can use the node enrollment flow instead of hand-editing keychain
|
||||
state. `geth node enroll request` creates a canonical, agent-key-signed request
|
||||
|
|
|
|||
|
|
@ -332,6 +332,11 @@ resource-scoped capability decisions.
|
|||
- `[x]` `geth-keychain` exposes transport-neutral allowed-signers projection,
|
||||
replay verification with an injected verifier, and appendable JSONL
|
||||
sigchain encode/decode helpers for static hosting or alternate transports.
|
||||
- `[x]` `geth-keychain` exposes `KeychainProfile` so non-geth applications
|
||||
can use distinct signature namespaces and default principals.
|
||||
- `[x]` `geth-keychain` exposes a `KeychainSignatureVerifier` trait so
|
||||
callers can plug in OpenSSH, HSM, WebCrypto, service-side, or test
|
||||
verification backends without daemon coupling.
|
||||
- `[x]` `docs/sigchain-keychain.md` documents the sigchain data model,
|
||||
verification algorithm, commands, and current security limits.
|
||||
- `[x]` Missing `ssh-keygen` or unavailable hardware keys produce clear
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue