# Security Considerations and Caveats This document collects the security properties FablePool **does** provide, the properties it explicitly does **not** provide, and the caveats that apply to the reference implementation in this repository. It complements the threat model from milestone #1 and the stated non-goals in [README.md](README.md). Read this before deploying anything beyond the demo. ## 1. What the protocol guarantees ### 1.1 Integrity and attribution Every operation in the log is signed (Ed25519) over its canonical encoding. A node that verifies signatures and hash links can detect: - **Tampering** — any modification of an operation's payload changes its content hash and invalidates its signature. - **Forgery** — an operation claiming to come from a device key it was not signed by will fail verification. - **Reordering within an author chain** — each author's operations form a hash-linked chain; a gap or splice is detectable. ### 1.2 Provenance Every claim carries references to the evidence operations and derivation rules that produced it. A delegate (or the user) can always answer "why does this claim exist?" by walking the derivation graph — and corrections cascade, so a refuted input mechanically invalidates downstream claims. ### 1.3 Scoped delegation Capability grants are signed by the user's key, bound to the delegate's public key, scoped to a claim filter, and carry an expiry. The slice served to a delegate contains **claims only**: evidence payloads are never transmitted, only opaque evidence identifiers sufficient for audit. Revocation is itself a signed operation in the log; a conforming delegate that syncs after revocation must stop serving the slice and the granting node stops answering slice requests for the revoked grant. ## 2. What the protocol does NOT guarantee These are **structural limits**, not bugs. Second implementations must not advertise stronger properties. ### 2.1 Revocation is mechanical, not magical Revocation guarantees that: - the user's nodes stop serving new or existing claims under the grant, and - a *conforming* delegate verifiably discards its local slice (and our reference delegate does, with an auditable tombstone). Revocation **cannot** guarantee that a malicious or compromised delegate did not copy data while the grant was live. Once bytes leave your devices, they can be retained. Treat every grant as a disclosure decision, not a loan. ### 2.2 Claims can leak evidence A claim like `"attends physiotherapy weekly"` discloses information about the underlying calendar evidence even though the evidence itself is never sent. Filters operate on claim subjects/predicates, not on semantic sensitivity. The inspection UI (milestone #5) exists precisely so users review a slice before granting it — use it. ### 2.3 No metadata privacy between user-owned nodes Sync between the user's own nodes (phone-like, laptop-like) replicates the full log. Both nodes see everything, including refutations and grant history. There is no partial trust tier between "my device" and "delegate". ### 2.4 Availability and freshness A delegate that never reconnects never learns it was revoked. The grant expiry is the hard backstop: conforming delegates must treat an expired grant as revoked even offline. Choose short expiries for sensitive slices. ### 2.5 Inference quality Confidence scores are heuristic outputs of the derivation engine, not calibrated probabilities. Do not use them as a security control. ## 3. Reference-implementation caveats (demo-grade) The reference node is built for auditability and interop testing, **not** production deployment. Specifically: | Area | Reference behavior | Production requirement | |---|---|---| | Transport | Plain HTTP on localhost in the demo; in-process transport in tests | TLS 1.3 or Noise with channel binding to node keys | | Key storage | Private keys stored as files on disk, unencrypted | OS keystore / hardware-backed keys, passphrase encryption at rest | | Authentication of sync peers | Signed sync requests verified against known peer keys | Same, plus transport-level mutual auth | | Rate limiting / DoS | None | Required on any network-exposed endpoint | | Log growth | Append-only, no compaction or garbage collection | Snapshot/compaction strategy with signed checkpoints | | Clock handling | Trusts local clocks for expiry checks (with bounded skew tolerance in sync) | Monotonic-clock discipline; consider signed time attestations for expiry-sensitive grants | | Storage at rest | SQLite, unencrypted | Full-disk or database-level encryption | The demo's HTTP transport sends signed operations, so **integrity** holds even over plaintext — but **confidentiality** does not. Anyone observing the demo's loopback traffic sees claim contents. Never run the demo transport across a real network. ## 4. Known attack surfaces and mitigations - **Malicious peer during sync.** A peer can withhold operations (a liveness attack) but cannot inject or alter them. Detection of withholding across authors requires cross-checking heads with a second peer; the protocol exposes heads for exactly this purpose. - **Replay of slice requests.** Slice requests are signed by the delegate and include a nonce and timestamp; the granting node rejects stale or repeated requests within the skew window. - **Grant confusion.** Grants name the delegate's public key; a slice response is only served to a requester proving possession of that key. Grants are not bearer tokens. - **Cascade poisoning.** A compromised device key can author false evidence, producing false claims. Provenance makes this auditable after the fact (the user can refute the evidence and the cascade invalidates derived claims), but the protocol does not prevent a fully compromised device from lying. Per-device keys exist so a single compromise can be revoked without losing the rest of the log's integrity. - **Canonicalization ambiguity.** Signature validity depends on every implementation producing byte-identical canonical encodings. This is why the milestone-2 conformance vectors exist; run them against any second implementation before trusting interop (see `conformance/`). ## 5. Reporting vulnerabilities This is a public, pre-1.0 reference implementation. Report suspected protocol flaws (canonicalization ambiguities, signature bypass, capability scope escape, revocation bypass in a *conforming* delegate) by opening a public issue — there is no embargoed channel because there are no production deployments to protect. Include a failing conformance vector or a reproducing test where possible.