Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ADR 0025: Signed addition of a backup policy authority

  • Status: Accepted
  • Date: 2026-10-14

Context

Slice 5 requires one backup signing authority for single-owner recovery. The receipt protocol described by ADRs 0023 and 0024 supports replacing a signer, but replacement retires an existing credential. Adding a backup only in the hosted database would make the new authority unverifiable from the customer’s pinned root. Replacing the primary with the backup would defeat the requirement to retain both keys. Expanding the initial root instead would require repinning and would not provide an ordered, authorized addition to an existing lineage.

Decision

Use receipt schema v3 with an explicit SignerAuthority / AddSigner transition. The complete new credential is carried in the existing replacement wire field (now the new-authority field for both transition actions). replaced_credential_id must be absent for addition. The receipt binds the workspace, audience, existing envelope, approved effective state, predecessor, sequence, current authority digest, current epoch, and new credential.

An already authorized signer provides proof; the exact new credential provides counter_proof, both over the complete receipt digest. Credential IDs and public keys cannot reuse any existing authority, including revoked keys. Verification advances the epoch by exactly one, appends the new credential, and retains every existing credential’s status. The new key is authorized only from that next epoch. Addition cannot change the configuration or envelope it re-approves.

Readers retain v2 verification and canonical digest derivation unchanged. AddSigner is accepted only in v3; unknown versions and invalid action/field combinations fail closed. Writers use v3. Published v2 golden vectors remain unchanged. EvidenceBundle v1 and Checkpoint v2 remain unchanged containers; their receipt/authority contents are verified using the appropriate protocol rules. Older clients reject v3 instead of silently treating addition as replacement. Signer-transition evidence always requires linkage to pinned/retained history; a server-carried post-state alone never establishes new authority.

Hosted implementation must land the receipt, head advance, and signer row in one transaction with the existing head lock. It must enforce at most two active policy signers per root (primary plus one backup) under that lock, not merely at begin or in the UI. Existing-factor authorization and proof by the new key are required; login recovery codes alone never confer policy authority.

Lost-primary replacement remains a ReplaceSigner transition: the authorized backup approves, the successor proves possession, and the signed retired ID names the lost primary rather than the backup. Enforcement never becomes inactive during addition, replacement, or trust reset. Losing all authorized keys still requires an independently accepted new root with an explicit discontinuity.

Consequences

  • Customers can verify the backup’s authorization from retained history rather than trusting a server-edited signer list.
  • The public protocol must be released and hosted code repinned before hosted addition is available. Protocol support alone does not claim that the hosted ceremony or recovery UI is deployed.
  • Hosted signer uniqueness must allow two active credentials per root while preserving immutable identity and forward-only retirement. This supersedes ADR 0024’s one-active-signer restriction, not its lineage/head-retention model. Bootstrap still emits no receipt; its preimage remains unchanged.
  • No operator-only recovery backdoor, multi-owner recovery, witness assurance, or execution attestation is introduced.