trust-model.md
1 # Trust Model 2 3 Auths enables cryptographic verification without a central authority. This page explains how trust is established, maintained, and verified -- and where the security boundaries are. 4 5 ## Zero-trust by design 6 7 Auths implements the core tenets of zero-trust architecture (NIST SP 800-207) as structural properties, not bolted-on policies: 8 9 - **Never trust, always verify.** Every attestation is verified cryptographically — signatures, expiration, capability scope. No implicit trust is granted based on network location, credential source, or issuer reputation. Verification is a pure computation requiring no server contact. 10 - **Least privilege.** Attestations grant specific capabilities (`sign:commit`, `deploy:staging`) with mandatory expiration. Delegation chains enforce capability narrowing: a child entity can never hold more authority than its parent granted. 11 - **Assume breach.** KERI pre-rotation means key compromise is survivable. The next rotation key is pre-committed as a hash in the current event — an attacker who steals the active key cannot rotate to a key they control. 12 - **Verify explicitly.** Dual signatures (identity + device) on every attestation, hash-chained Key Event Logs, and optional witness receipts provide independent, layered verification that does not depend on a single trust anchor. 13 14 These properties hold whether the identity belongs to a human developer, an AI agent, or a CI/CD workload. 15 16 ## Verification without a central authority 17 18 Traditional identity systems rely on a central authority (a CA, an identity provider, a blockchain) to vouch for the binding between an identity and a key. Auths takes a different approach: **the identity is the event log itself**. 19 20 Trust in Auths is rooted in three properties: 21 22 1. **Self-addressing identifiers**: The identity prefix is the Blake3 hash of the inception event. The identifier is cryptographically bound to its content. No authority assigns it. 23 2. **Pre-rotation commitments**: Each event commits to the next rotation key. Only the holder of the pre-committed key can perform a valid rotation. 24 3. **Hash-chained event log**: Each event references the previous event's SAID, forming a tamper-evident chain that can be independently verified. 25 26 A verifier does not need to contact a server or look up a registry. Given the Key Event Log and the relevant attestations, verification is a pure computation. 27 28 ## Inception events: the root of trust 29 30 The inception event is the foundation of all trust in an Auths identity. It establishes: 31 32 - The **identity prefix** (`i` field) -- derived from the event's own SAID 33 - The **initial signing key** (`k` field) -- Ed25519 public key with `D` derivation code prefix 34 - The **next-key commitment** (`n` field) -- Blake3 hash of the next rotation key with `E` prefix 35 - The **witness configuration** (`bt`/`b` fields) -- threshold and list of witnesses 36 37 Because the prefix equals the SAID of the inception event, any modification to the inception event would change the prefix. This makes the inception event immutable by construction: altering it produces a different identity, not a corrupted one. 38 39 ``` 40 Inception event (icp, sequence 0): 41 42 ┌─────────────────────────────────────────┐ 43 │ d: E<blake3-hash> ← SAID │ 44 │ i: E<blake3-hash> ← same as d │ 45 │ k: [D<pubkey>] ← current key │ 46 │ n: [E<hash>] ← next-key commit │ 47 │ x: <signature> ← signed by k │ 48 └─────────────────────────────────────────┘ 49 │ 50 └─── This hash IS the identity. 51 Change anything, get a different identity. 52 ``` 53 54 ## Key Event Logs: tamper-evident history 55 56 The Key Event Log (KEL) is a sequence of signed events stored at `refs/did/keri/<prefix>/kel`. Each event after inception includes a `p` field referencing the SAID of the previous event, creating a hash chain. 57 58 ``` 59 ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ 60 │ icp (seq 0) │ │ rot (seq 1) │ │ ixn (seq 2) │ 61 │ d: ESAID_0 │────>│ p: ESAID_0 │────>│ p: ESAID_1 │ 62 │ k: [D<key1>] │ │ d: ESAID_1 │ │ d: ESAID_2 │ 63 │ n: [E<hash>] │ │ k: [D<key2>] │ │ a: [{seal}] │ 64 │ x: <sig1> │ │ n: [E<hash>] │ │ x: <sig3> │ 65 └──────────────┘ │ x: <sig2> │ └──────────────┘ 66 └──────────────┘ 67 ``` 68 69 ### Validation rules 70 71 KEL validation (`validate_kel`) enforces these invariants: 72 73 | Rule | Check | Error on violation | 74 |------|-------|--------------------| 75 | First event must be inception | `events[0]` is `icp` | `NotInception` | 76 | Sequence numbers are monotonic | `s` = 0, 1, 2, ... | `InvalidSequence` | 77 | SAID matches content | Blake3 hash of canonical JSON = `d` field | `InvalidSaid` | 78 | Chain is linked | `p` field = previous event's `d` field | `BrokenChain` | 79 | Pre-rotation commitment holds | New key matches previous `n` commitment | `CommitmentMismatch` | 80 | Signature is valid | Ed25519 signature over canonical event JSON | `SignatureFailed` | 81 82 Validation is a **pure function**: it takes a slice of events and returns a `KeyState` or an error. No filesystem, network, or platform access. This makes it suitable for property-based testing and embedding in any environment. 83 84 ### KeyState: the resolved view 85 86 Replaying the KEL produces a `KeyState` -- the current cryptographic state of the identity: 87 88 ```rust 89 KeyState { 90 prefix: Prefix, // The did:keri prefix 91 current_keys: Vec<String>, // Active signing key(s) 92 next_commitment: Vec<String>, // Next-key commitment(s) 93 sequence: u64, // Current sequence number 94 last_event_said: Said, // SAID of the last event 95 is_abandoned: bool, // True if next commitment is empty 96 } 97 ``` 98 99 The `KeyState` tells you which key is currently authorized to sign, whether the identity can still be rotated, and what the latest event in the log is. 100 101 ## Pre-rotation: defense against key compromise 102 103 Pre-rotation is the most important security property in the trust model. At every point in the KEL, the identity has committed to which key will be used *next*. This commitment is a Blake3 hash of the next public key. 104 105 ``` 106 Timeline of compromise scenarios: 107 108 Without pre-rotation: 109 Attacker steals key_A → rotates to attacker_key → identity hijacked 110 111 With pre-rotation: 112 Attacker steals key_A → cannot rotate (doesn't have key_B) 113 Legitimate owner uses key_B → rotates to key_B, commits to key_C 114 Attacker's window is limited to the period before rotation 115 ``` 116 117 The commitment is verified during KEL validation: the new key's public bytes are hashed with Blake3 and compared to the previous event's `n` field. A mismatch produces `CommitmentMismatch` -- a hard validation error. 118 119 ## Attestation verification 120 121 Attestations are verified independently of the KEL. The `auths-verifier` crate provides two levels: 122 123 ### Single attestation (`verify_with_keys`) 124 125 Verifies one attestation against known public keys: 126 127 - Is the `identity_signature` valid over the canonical attestation data? 128 - Is the `device_signature` valid over the canonical attestation data? 129 - Is the attestation expired? (`expires_at` checked with 5-minute clock skew tolerance) 130 - Is the attestation revoked? (`revoked_at` field present) 131 132 ### Chain verification (`verify_chain`) 133 134 Verifies a chain of attestations from root identity to leaf device: 135 136 - Does each link's `subject` match the next link's `issuer`? 137 - Are all individual signatures valid? 138 - Is the chain unbroken? 139 140 Both functions are pure: no network, no filesystem, no platform dependency. This is why `auths-verifier` can run in web browsers (WASM), CI pipelines, mobile apps (FFI), and edge functions. 141 142 ## Seals: anchoring data in the KEL 143 144 Seals create a cryptographic link between the KEL and external data. An interaction event (`ixn`) can include seals in its `a` field: 145 146 ```json 147 { 148 "d": "<SAID-digest>", 149 "type": "device-attestation" 150 } 151 ``` 152 153 The seal contains the SAID (Blake3 hash) of the anchored data and a type indicator. Seal types include: 154 155 | Seal type | Purpose | 156 |-----------|---------| 157 | `device-attestation` | Links a device attestation to the KEL | 158 | `revocation` | Links a revocation event to the KEL | 159 | `delegation` | Links a capability delegation to the KEL | 160 161 Anchoring attestations in the KEL makes them part of the tamper-evident history. A verifier can check that an attestation's digest matches a seal in the KEL, proving it was authorized by the identity at a specific point in time. 162 163 ## How witnesses work 164 165 Witnesses provide **split-view attack detection**. A split-view attack occurs when a malicious node shows different versions of a KEL to different peers: 166 167 ``` 168 Without witnesses: 169 Attacker shows KEL_A to Peer 1 (key1 is current) 170 Attacker shows KEL_B to Peer 2 (key2 is current) 171 Both peers think they have the correct view. 172 173 With witnesses: 174 Peer 1 asks witness: "What is the head of identity E123?" 175 Witness: "I see event ESAID_abc" 176 Peer 1: "My local copy shows ESAID_def" 177 → Split-view detected. 178 ``` 179 180 ### Witness receipts 181 182 When a witness observes a KEL event, it issues a **receipt** -- a signed acknowledgment following the KERI `rct` (non-transferable receipt) format: 183 184 ```json 185 { 186 "v": "KERI10JSON000000_", 187 "t": "rct", 188 "d": "<receipt-SAID>", 189 "i": "did:key:z6MkWitness...", 190 "s": 5, 191 "a": "<event-SAID-being-receipted>", 192 "sig": "<Ed25519-signature-hex>" 193 } 194 ``` 195 196 Receipts are stored at `refs/did/keri/<prefix>/receipts/<event-said>` and can be verified by checking the witness's signature over the event SAID. 197 198 ### Witness thresholds 199 200 Witnesses support threshold-based security. The inception (or rotation) event declares a witness threshold (`bt`) and witness list (`b`). For an event to be considered sufficiently witnessed, it must have receipts from at least `bt` witnesses. 201 202 ### Limitations 203 204 Witnesses are **not Byzantine fault tolerant**: 205 206 - A single witness can be compromised or collude with an attacker 207 - Multiple witnesses (quorum) reduce risk but do not eliminate it 208 - Witnesses must be trusted to some degree 209 210 For full BFT guarantees, transparency logs or blockchain anchoring would be needed. Auths provides witness infrastructure as an optional layer for ecosystems where split-view attacks are a concern. 211 212 ### Default: disabled 213 214 By default, witness checking is disabled (`NoOpWitness`). This is appropriate for: 215 216 - Private repositories 217 - Single-user setups 218 - Systems with existing consistency mechanisms (e.g., Radicle gossip protocol) 219 220 Enable witness checks for public ecosystems where split-view detection matters. 221 222 ## What verification does NOT do 223 224 It is important to understand the boundaries of Auths verification: 225 226 | What it does | What it does not do | 227 |-------------|-------------------| 228 | Verifies cryptographic signatures | Resolve DIDs over a network | 229 | Checks attestation expiration and revocation | Contact a revocation server | 230 | Validates KEL chain integrity | Determine if the issuer *should* be trusted | 231 | Verifies pre-rotation commitments | Fetch attestations from Git | 232 233 The verifier answers: *"Are these signatures mathematically valid?"* The caller decides: *"Do I trust this root identity?"* Trust in the root is established out-of-band -- by pinning a known identity, by receiving it through a trusted channel, or by organizational policy. 234 235 ## Trust boundaries summary 236 237 ``` 238 ┌─────────────────────────────────────────────────────────┐ 239 │ Out-of-band trust │ 240 │ "I trust did:keri:E... because my organization │ 241 │ published it, or I verified it in person." │ 242 ├─────────────────────────────────────────────────────────┤ 243 │ KEL verification │ 244 │ Inception → Rotation → Rotation → ... │ 245 │ Each event: SAID, chain link, pre-rotation, signature │ 246 ├─────────────────────────────────────────────────────────┤ 247 │ Attestation verification │ 248 │ Identity ──attestation──> Device │ 249 │ Dual signatures, expiration, revocation check │ 250 ├─────────────────────────────────────────────────────────┤ 251 │ Witness layer (optional) │ 252 │ Receipts from k-of-n witnesses │ 253 │ Split-view detection, not BFT │ 254 └─────────────────────────────────────────────────────────┘ 255 ``` 256 257 Trust flows from the top down: you trust a root identity (out-of-band), the KEL proves the key history is intact, attestations prove devices are authorized, and witnesses provide additional assurance against equivocation. 258 259 ## Audit trail 260 261 Auths provides tamper-evident audit capabilities as a structural property of the identity system, not as a separate logging layer. 262 263 - **Key Event Log (KEL):** Every key operation — inception, rotation, interaction — is a signed, content-addressed record in a hash chain. The KEL is an immutable, independently verifiable history of every change to an identity's cryptographic state. 264 - **Attestation lifecycle in Git:** Attestation creation, extension, and revocation are recorded as Git commits under `refs/auths/`. The commit history is the lifecycle audit trail — who authorized what, when, and under what constraints. 265 - **Seals:** Interaction events can include seals — cryptographic digests that bind external data (attestation creation, revocations, delegations) to a specific point in the identity's event timeline. 266 - **Delegation chain provenance:** Every agent action that produces a signature is traceable through the attestation chain back to the authorizing human. The `delegated_by` field, combined with `signer_type`, creates an unbroken accountability chain from autonomous action to human authorization. 267 268 Because identifiers are self-certifying and logs are hash-chained, audit entries are independently verifiable without access to any central system.