2026-07-18 22:05:57 +02:00
|
|
|
# ADR 0018: Sequence-free SSHSIGCHAIN authority protocol
|
2026-07-18 20:22:58 +02:00
|
|
|
|
|
|
|
|
## Status
|
|
|
|
|
|
2026-07-18 22:05:57 +02:00
|
|
|
Accepted for the generic core. The protocol is still pre-deployment and has no
|
|
|
|
|
legacy compatibility requirement.
|
2026-07-18 20:22:58 +02:00
|
|
|
|
|
|
|
|
## Context
|
|
|
|
|
|
2026-07-18 22:05:57 +02:00
|
|
|
The first linked draft improved on a timestamp-sorted static bundle, but still
|
|
|
|
|
made application profiles responsible for all key lifecycle semantics. It also
|
|
|
|
|
included both a sequence counter and a parent hash, fixed one application
|
|
|
|
|
profile for the whole chain, exposed every payload, and left rollback anchors
|
|
|
|
|
outside the protocol model.
|
|
|
|
|
|
|
|
|
|
That design would let applications fragment device/key behavior, made
|
|
|
|
|
multi-profile least privilege awkward, and offered no standard way to disclose
|
|
|
|
|
only selected profile data or compare independently anchored heads.
|
2026-07-18 20:22:58 +02:00
|
|
|
|
|
|
|
|
## Decision
|
|
|
|
|
|
2026-07-18 22:05:57 +02:00
|
|
|
SSHSIGCHAIN v1 is redesigned before deployment:
|
|
|
|
|
|
|
|
|
|
- the trust tuple is `(chain ID, SSHSIG namespace, root public key)`;
|
|
|
|
|
- parent hashes alone define order; there is no sequence number;
|
|
|
|
|
- link identity hashes the signed outer bytes, not the signature encoding;
|
|
|
|
|
- every link carries a mandatory public Authority v1 transition;
|
|
|
|
|
- authority owns devices, keys, proof-of-possession, causal revocation,
|
|
|
|
|
permission ceilings, delegation, and anchor policy;
|
|
|
|
|
- applications use profile-ID-scoped, salted payload commitments and cannot
|
|
|
|
|
mutate authority;
|
|
|
|
|
- disclosures are transport additions which do not change a link or its hash;
|
|
|
|
|
- authorized keys can sign head claims;
|
|
|
|
|
- distinct head attesters and backend-neutral receipts are evaluated by
|
|
|
|
|
separate weighted/required thresholds and required backend classes;
|
|
|
|
|
- cached ancestors are never replaced by older heads and incomparable verified
|
|
|
|
|
histories fail as forks; and
|
|
|
|
|
- a policy-change head is witnessed under the preceding policy before the new
|
|
|
|
|
policy governs descendants.
|
2026-07-18 20:22:58 +02:00
|
|
|
|
2026-07-18 22:05:57 +02:00
|
|
|
The generic core defines backend interfaces and deterministic policy behavior,
|
|
|
|
|
not Nostr, HTTP, blockchain, or transparency-log clients. Those adapters belong
|
|
|
|
|
outside `geth-keychain`. Backends provide evidence and discovery, not consensus.
|
2026-07-18 20:22:58 +02:00
|
|
|
|
2026-07-18 22:05:57 +02:00
|
|
|
The generic protocol remains independent of geth transports. All geth
|
|
|
|
|
node-to-node communication remains Iroh-only; SSH remains a trust and signature
|
|
|
|
|
integration.
|
2026-07-18 20:22:58 +02:00
|
|
|
|
|
|
|
|
## Consequences
|
|
|
|
|
|
2026-07-18 22:05:57 +02:00
|
|
|
Device and key behavior is interoperable rather than reinvented in each
|
|
|
|
|
profile. A verifier can validate current authority while withholding application
|
|
|
|
|
data, but must report affected profile state as incomplete. Proofs of possession
|
|
|
|
|
prevent an administrator from silently enrolling a key it does not control.
|
|
|
|
|
Device ceilings and delegable permission sets constrain later amplification.
|
|
|
|
|
|
|
|
|
|
The wire format is intentionally incompatible with every pre-deployment test
|
|
|
|
|
draft. No migration parser or version alias is retained.
|
2026-07-18 20:22:58 +02:00
|
|
|
|
2026-07-18 22:05:57 +02:00
|
|
|
Rollback protection still depends on persistent local accepted heads and the
|
|
|
|
|
operator's anchor policy. A Nostr relay, mutable HTTP URL, blockchain, or
|
|
|
|
|
transparency service has only the guarantees its receipt verifier and deployment
|
|
|
|
|
actually establish. Concrete publication, durable accepted-head storage, and
|
|
|
|
|
cross-implementation vectors remain follow-up work.
|