make sshsigchain the only portable sigchain format

This commit is contained in:
Eric Wendland 2026-07-18 21:00:06 +02:00
commit 73500e1944
15 changed files with 812 additions and 1603 deletions

View file

@ -173,7 +173,7 @@ admin devices without depending on one always-online coordination server.
resource data.
- `[ ]` The control plane has documented conflict semantics for concurrent
joins, renames, IP conflicts, route changes, and revocations.
- `[ ]` Nodes can converge from static sigchain publication, peer live-sync,
- `[ ]` Nodes can converge from SSHSIGCHAIN publication, peer live-sync,
and Iroh-connected peers without requiring a central coordinator.
- `[ ]` Stale or partitioned nodes are detectable in `geth overlay status`
and `geth sync status --json`.
@ -181,7 +181,7 @@ admin devices without depending on one always-online coordination server.
- `[ ]` Fault-tolerant peer and path selection.
Acceptance criteria:
- `[ ]` Nodes maintain multiple candidate addresses from Iroh relays, local
discovery, imported peer cards, and static publication.
discovery, imported peer cards, and configured bootstrap metadata.
- `[ ]` Packet routing retries healthy paths and backs off failed paths
without granting trust from discovery metadata.
- `[ ]` Relay use, direct connections, LAN discovery, and path failures are
@ -555,23 +555,33 @@ resource-scoped capability decisions.
- JSON is not used as the signed representation.
- Tests verify equivalent operations hash/sign identically across runs.
- `[~]` Replace the legacy static keychain sigchain with SSHSIGCHAIN v2.
- `[~]` Implement SSHSIGCHAIN version 1 as the only portable keychain
sigchain format.
Acceptance criteria:
- `[x]` Publish a transport-neutral, deterministic SSHSIGCHAIN v2 record
- `[x]` Publish a transport-neutral, deterministic SSHSIGCHAIN v1 record
format with explicit trust-anchor, chain-link, size-limit, and
non-claim documentation.
- `[x]` Provide a reusable verifier core and a geth keychain profile that
rejects self-bootstrap, non-linked forks, non-canonical payloads, and
post-revocation timestamp replay.
- `[ ]` Add explicit CLI storage, signing, verification, publication, and
import workflows for a pinned v2 trust tuple.
- `[ ]` Persist accepted v2 heads and require proof of extension before a
static source can advance.
- `[ ]` Disable the legacy static publish/fetch/import workflow by default
and provide an operator-visible migration path that creates a fresh v2
genesis chain.
- `[ ]` Add OpenSSH integration tests and independently generated wire test
- `[~]` Add explicit CLI storage, signing, verification, publication, and
import workflows for a pinned SSHSIGCHAIN trust tuple.
- `[x]` `geth keychain verify-sigchain` verifies a JSONL transport file
against an operator-pinned chain ID and OpenSSH root public key.
- `[ ]` Local record storage, signing, publication, import, and
head-advance workflows are complete.
- `[ ]` Persist accepted heads and require proof of extension before a source
can advance.
- `[x]` Delete the previous test-only static export, publication,
verification, import, checkpoint, and fetch workflow. It is not a
compatibility target because it was never deployed.
- `[~]` Add OpenSSH integration tests and independently generated wire test
vectors for the published standard.
- `[x]` An OpenSSH `ssh-keygen -Y` integration test signs and verifies a
linked root/init chain.
- `[x]` The specification and reference implementation share a base
signing-byte test vector.
- `[ ]` Add independently generated cross-implementation vectors.
- `[x]` SSH-admin-rooted keychain initialization.
Acceptance criteria:
@ -602,24 +612,11 @@ resource-scoped capability decisions.
- `[x]` `geth keychain verify-file --in <path> --signature <sig>` verifies a
snapshot signature against the current keychain-derived `allowed_signers`
projection or a supplied `--allowed-signers` file.
- `[x]` `geth keychain sigchain --out <path>` writes the appendable JSONL
sigchain suitable for static website publication.
- `[x]` `geth keychain publish-bundle --out <dir>` writes a static website
bundle rooted at `https://example.com/.well-known/sshsigchain/` by default.
- `[x]` Publication bundles include `allowed_signers`, `geth.sigchain.jsonl`,
`geth.sigchain.checkpoint.json`, and a detached checkpoint signature.
- `[x]` Publication bundles can copy and sign external snapshots with
`--snapshot <name>=<path>` without making the keychain own their contents.
- `[x]` `geth keychain verify-sigchain --in <path>` verifies a JSONL sigchain
file by replaying operations and signatures.
- `[x]` `geth keychain import-sigchain --in <path>` imports a JSONL sigchain
only if replay verification rejects no operations.
- `[x]` `geth keychain verify-checkpoint` verifies checkpoint signatures,
checkpoint hashes, base URL, and sigchain head consistency.
- `[x]` `geth keychain fetch --url <base> --import` fetches static bundles
with `curl` for HTTP(S) or filesystem reads for local/file URLs.
- `[x]` Static fetch/import records the last accepted checkpoint per source
URL and rejects older checkpoints for rollback resistance.
- `[x]` Previous test-only static JSONL export, publication, verification,
import, checkpoint, and fetch commands were deleted after review found that
their downloaded allowed-signers projection could self-bootstrap trust and
their timestamp ordering could not prove causal history. They are not a
compatibility target; SSHSIGCHAIN is the only portable format.
- `[x]` `geth keychain explain <op-id>` and `explain-signer <key-id>` provide
basic audit output for operations and admin signers.
- `[x]` Agent/FIDO signing is supported through OpenSSH by passing a public
@ -629,9 +626,9 @@ resource-scoped capability decisions.
previously accepted admin-key view.
- `[x]` Reusable sigchain mechanics live in `geth-keychain`, not in daemon
orchestration code.
- `[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 a transport-neutral SSHSIGCHAIN verifier,
bounded JSONL transport codec, and an explicit trust-tuple model alongside
local allowed-signers projection and replay verification.
- `[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