0x06Threat model
→ normative spec on GitHubWhat fd0 defends. What it leaves to you.
Each threat T## is catalogued with status, mitigation, and a code reference. A representative slice below; the full catalogue lives in docs/THREATS.md.
T02mitigated
Stolen vault file → offline brute-force
The vault body is AEAD-sealed under a key wrapped to each enrolled method. Offline resistance is Argon2id at M=64 MiB / T=3, so it rests on the strongest method you enrol — a YubiKey removes the guessing game entirely.
T07mitigated
Same-UID malware reads agent memory
super_priv lives mlocked inside fd0-agent and is wiped on lock, idle timeout and exit. An attacker already running as you is not fully excluded — this narrows the window rather than closing it.
T26mitigated
Forged member.change (unsigned author)
Every event is signed by its author over a domain-separated prefix, and the server validates authorship before storing. The server holds no member signing key.
T27mitigated
Foreign-author event splice
Replay checks each event's author against the member set as of that point in the chain, so a non-member's write is rejected on read even if the server stored it.
T35mitigated
Server equivocation between two clients
An independent witness cosigns the server's tree head, and clients cross-check it. Two distinct roots at the same tree size are detectable rather than a matter of trust.
T41mitigated
First-fetch checkpoint rollback
A client with no prior anchor probes for the highest checkpoint before accepting one, so a server cannot quietly seed a new device with an old view.
T06accepted
Coordinated local rollback (vault + chain)
Replacing vault.enc and ~/.fd0/chains/ together, on your own machine, is outside the model: an attacker with that access already has the device. Single-file rollback is caught (T05).
T38accepted
Witness collusion with the server
A witness that colludes stops being an independent check. It still cannot decrypt anything; pinning a second, independently operated witness is what reduces this.
T52accepted
Metadata side channels
The server learns sizes, timing and access patterns even though it cannot read content. Hiding those needs padding and cover traffic, which fd0 does not currently do.
The threat-coverage tool (go run ./tools/threat-coverage) cross-references every T## with a code annotation; CI fails if a mitigated threat loses its code reference.