diff options
| author | tv <tv@krebsco.de> | 2026-11-07 22:35:22 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-11-07 22:35:22 +0100 |
| commit | cdc81b0f1f0cba1f36d38a8151cad7660074d9f4 (patch) | |
| tree | de26b087749ab2481e1b896443a2829e7dca4e3f /docs | |
| parent | b99e7ddf38233120ea19485968c12c5548e7fa61 (diff) | |
docs: trust as it stands
trust.md: no policy, a policy, strict, sealed values; what members are
trusted with at each step, and the logins.
Auth plan (docs).
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/trust.md | 92 |
1 files changed, 60 insertions, 32 deletions
diff --git a/docs/trust.md b/docs/trust.md index 5444b8b..3839958 100644 --- a/docs/trust.md +++ b/docs/trust.md @@ -33,9 +33,11 @@ makes its peer ID and addresses public. secret like the swarm key: readable by its owner only (a node warns otherwise; a key it creates is). -**The HTTP API.** Every endpoint but the API description needs a user from -`--htpasswd`, one a reverse proxy names (`--user-header`), or a token a node of the -swarm issued to one of those ([`access.md`](access.md), Tokens): the node believes that +**The HTTP API.** Every endpoint but the API description, the login page (`/login`) and +logging in by key needs a user from `--htpasswd`, one a reverse proxy names +(`--user-header`), or a token a node of the swarm issued to one of those or to a user +signing a challenge with one of its keys ([`access.md`](access.md), Tokens), sent as a +header or as the browser session's cookie: the node believes the proxy's header from `--trusted-proxies` alone, but from those blindly, so whoever can send requests from there can be any user. With the default loopback addresses, that is every user of the host; with only the API's Unix socket (`--trusted-proxies unix`), those its @@ -56,31 +58,58 @@ Protect the configuration like the swarm key. ## What members are trusted with -Everything in the document. A member syncs changes to and from its peers, and every -node acts on what the document says. Unless the swarm has a policy -([`access.md`](access.md), Changes judged on every node): then every node judges every -change it receives by rules by path, and those below are refused where a change breaks -them, as far as the node and user a change claims are who wrote it: +Everything in the document, unless the swarm says otherwise. What it can say comes in +three steps, each adding to the one before ([`access.md`](access.md)). + +**Without a policy**, a member syncs changes to and from its peers, and every node acts +on what the document says: * **User data**: any member can write or delete any path. * **Who wrote what** (`GET /admin/changes`): each change names its node and API user as the writing node says. Nodes sign their changes ([`api.md`](api.md), Signed - changes), so a change a signature vouches for shows `verified`: its node made it. - One that shows unverified may yet be vouched for by its node's next signature, or - may be another member's claiming that node; nothing is refused for it yet. The user a - change names is its node's claim, signed or not. The names of the users who write - are in the document, and so on every node. -* **The member registry**: each node writes its own entry, but nothing stops a member - from writing others'. The registry decides the topology and, through the alive - stamps, the electorate of a remake. -* **The user registry**: written through the API only by users given protocol data, - but a member can write any entry into its own document, and every node then serves - users as it says; the checks at the API bind honest nodes only. -* **Forget records**: any member can make the swarm forget a peer (until it says HELLO - again). -* **Remakes**: any member can propose one, vote, and, as coordinator, decide. Votes - are not signed: the votes register says who voted, but any member could write any - entry. Every node switches to a committed epoch without counting the votes again. + changes), so a change a signature vouches for shows `verified`: its node made it. One + that shows unverified may yet be vouched for by its node's next signature, or may be + another member's claiming that node. The user a change names is its node's claim, + signed or not. The names of the users who write are in the document, and so on every + node. +* **The member registry, the user registry, forget records, remakes and votes**: the + API lets only users given protocol data write them, but a member can write anything + into its own document, and every node acts on it: the topology, the electorate, who + may do what, which peers are forgotten, which remakes commit. Votes aren't counted + again by the nodes that switch. + +So a member that misbehaves, by a bug or on purpose, can rewrite or delete data, +manipulate the registries and the electorate, forge votes, commit a remake without a +majority, and make the swarm forget peers. + +**With a policy** (Changes judged on every node), every node judges every change it +receives, as the document stood when it was written, and refuses one breaking the +rules, with everything built on it: a member writes its own entry and votes only; epochs +and the swarm ID come from roots only; a remake's decision from its coordinator; the +rest, user data and protocol data alike, as the registry lets the user the change +names. A banned node gets nothing in, and no handshake answered. With signatures +required, a change counts only once its node's signature vouches for it, so a member +can no longer write as another member. What stays: the user a change names is its +node's word, so a member can write wherever any user may; and a node refusing a change +diverges from the member that wrote it without anyone being told more than the log and +`GET /admin/refused` say. + +**Strict** (`"values": "signed"`, Values signed by their users): the registry, the +policy, the bans and the paths the swarm lists hold values their users signed, with +their SSH keys, checked by every node against the registry as the writer saw it. No +member can grant itself or anyone a capability, change the policy or lift a ban, or +write a listed path, but as a user who may signed it; there, the user is proven, not +claimed. + +**Sealed values** (Values sealed for their readers) are read only by those they are +sealed for: no node holds their keys. Members still see that they exist, their sizes, +and when and by whom they were written, and keep what they read before a reader was +removed. + +Whatever the steps: every member reads the whole document (but sealed values), any +member can propose a remake and coordinate it, and what a member says about itself is +believed: + * **Epochs it advertises**: a rejoining node follows the epoch ready members advertise, corroborated by two of them once it was ready (one if only one is active, and one before it was ever ready), and downloads the epoch's snapshot from them, @@ -91,11 +120,11 @@ them, as far as the node and user a change claims are who wrote it: claiming to be ready can become a joining node's catch-up source (though one with an empty document can't make it ready: empty heads prove nothing), and one misreporting absences can move a node between tiers. +* **A joining node's first sync**: an empty document has no policy, so what it gets + first is taken as the node it joins through judged it. -So a member that misbehaves, by a bug or on purpose, can rewrite or delete data, -manipulate the registry and the electorate, forge votes, commit a remake without a -majority, and make the swarm forget peers. Nothing but the swarm key protects against -that; keep it to nodes you trust as much as your data. +Keep the swarm key to nodes you trust as much as your data, and the policy, strict +where it matters, for the rest. ## What depends on clocks @@ -130,7 +159,6 @@ Not against a hostile member, but against honest ones getting in each other's wa ## Not yet -Revoking a single member, or limiting what a member may do, needs per-node keys: a -member list in the document, with keys that sign what each node writes about itself -(its registry entry, its votes). See [`review-rejections.md`](review-rejections.md), "Author binding for remake -votes and decisions". +What is left of protecting the swarm against its members, and of keys in browsers, is in +[`future-work.md`](future-work.md): Write protection by checking changes, Read access +beyond sealed values, Keys in browsers. |
