/ docs / getting-started / trust-model.md
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.