aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* access: maps made on the way judged by what they holdtv3 days2-0/+86
| | | | | | | | | | | | A write makes the maps on its way where there are none (store::write_path); the rules judged each made map as a write at its own path, so a user whose capability lies below a map not made yet (write on servers/eu, a first PUT at servers/eu/0) had its first write taken by its node and refused by every other. A map made where there was none, in a change writing within it, is now judged by what is written within it. Review finding 3 (parent maps created on the way).
* access: signed values in before the next is judgedtv3 days1-2/+73
| | | | | | | | | | | Under a strict policy the rules read user data: the value at a signed place (prev) and what holds one. A batch judged at its frontier missed a signed write earlier in the same batch, so two successive signed writes at one path received together were refused on some nodes and taken on others. A change at, within or above a signed path now goes in before the next is judged. Review finding 2.
* access: judged by the policy written undertv3 days3-3/+43
| | | | | | | | | | The rules read the policy at the change's dependencies only for strict mode, so history from before the policy was judged by today's rules when a late node caught up, or when REFUSALS had it judged again. A change written while the document had no policy, or one this node doesn't know, is now judged by none. Review finding 6.
* access: a forgotten node cancels its own recordtv3 days2-1/+9
| | | | | | | | | | A node forgotten swarm-wide while alive cancels its forget record with a change naming no user; the rules judged _continuum/forgotten by the registry alone, so every node refused the cancellation and everything the node wrote after it. A node may now write its own _continuum/forgotten/<id>, as it may its member entry. Review finding 4.
* access: an epoch's root is never droppedtv3 days4-4/+54
| | | | | | | | | | | | | | | A REFUSALS naming the swarm's first change made the node receiving it judge that change again in a document that isn't empty, refuse it as "a change without dependencies that isn't the epoch's root", and drop it with everything built on it: its whole document. The first epoch's root is now the first change a document holds, as it comes to an empty one or as it is in one; a change judged again on a peer's word is never refused for having no dependencies; and drop_taken refuses to drop an epoch's root, or anything that would leave nothing kept, logging an error instead. Review finding 1 (critical).
* dashboard: flashes below labelstv4 days1-3/+5
| | | | Flashes are drawn beneath the nodes' labels.
* dashboard: message flashestv4 days2-33/+99
| | | | | messages: off / dots / flash: a message expands at its own speed and leaves an afterglow fading out in the direction it went.
* simtest: members against the rules, and a policy unknowntv4 days1-0/+102
| | | | | | | | A member writing past its API's checks is refused, told, drops its change and is taken again; a node under a policy it doesn't know takes no writes and syncs on. Auth plan M6 (tests).
* dashboard: a token handed over to another member's dashboardtv4 days6-12/+62
| | | | | | | | Opening another member's dashboard passes a token reading only, for five minutes, in the URL's fragment; its login page begins a session with it. Tokens may be asked for with a shorter lifetime. Auth plan M3 (hand-off).
* swarm: changes taken unjudged, dropped (REFUSALS)tv4 days16-38/+462
| | | | | | | | | A node refusing changes a peer brought tells it which broke a rule; the peer judges them itself, and if its rules refuse them too, drops them with all built on them (its document forked without them, a fresh actor), quarantining its own writes among them. Wire version 42. Auth plan M6 (rejoin on taint).
* access: members refused as a wholetv4 days11-6/+168
| | | | | | | | | With signatures required, a member whose own change broke a rule is refused as a whole: sent nothing, shown in /peers (refused), in stats (sync.refusedPeers) and on the dashboard, until a change of its is taken again or the epoch changes. Auth plan M6 (diverged standing).
* auth: the session cookie lets in reads onlytv4 days4-12/+33
| | | | | | | | The cookie lets in GET, HEAD and the session's own requests; anything changing something brings the token itself, which no page of another site or port can make a browser send. The dashboard's writes send it. Auth plan M3 (browsers).
* access: refused oncetv4 days5-17/+203
| | | | | | | | A refused change is remembered by its hash: offered again it is refused without decoding, judging or logging, so is one built on it, and a peer offering nothing else is answered later each time, up to a minute. Auth plan M6 (re-sending).
* docs: trust as it standstv4 days1-32/+60
| | | | | | | trust.md: no policy, a policy, strict, sealed values; what members are trusted with at each step, and the logins. Auth plan (docs).
* auth: a login page and browser sessionstv4 days9-20/+292
| | | | | | | | | GET /login without authentication: log in by password or with a token (from a login by key). POST/DELETE /auth/session keep the token as an HttpOnly, SameSite=Strict cookie; the dashboard sends a browser without a user there and renews the session while open. Auth plan M2/M3 (browsers).
* docs: reading keys and declarationstv4 days2-0/+20
| | | | | | | Clients checking signatures or sealing read the registry and _continuum/access: operators grant reading them. Auth plan M7, M8 (docs).
* simtest: sealed valuestv4 days1-1/+81
| | | | | | | A value sealed for its declared readers goes everywhere; one sealed for a stranger too, or plain, gets nothing past the others. Auth plan M8.
* scripts: sealing and opening in the reference clienttv4 days2-5/+71
| | | | | | | continuum-signed seal and open, with age, for the readers declared or CONTINUUM_READERS. Auth plan M8.
* access: values sealed for their readerstv4 days8-3/+531
| | | | | | | | | | cs1.<age file>: a value encrypted with age to its readers' SSH keys, which no node decrypts. _continuum/access/sealed declares paths whose values must be sealed, for named readers or anyone; nodes check the recipients by age's key tags, at the API and on receipt. Auth plan M8, reworked: sealed values instead of containers, readers as users only (nodes hold no keys).
* simtest: a strict swarmtv4 days1-1/+154
| | | | | | | | Signed values everywhere, carried over by a remake and replaced after it; a member writing the registry or a signed path plain gets nothing past the others. Auth plan M7.
* scripts: a reference client for signed valuestv4 days2-0/+145
| | | | | | | | scripts/continuum-signed (ssh-keygen, curl, jq): login by key, put and delete signed values, get envelopes, verify one against its user's keys. Auth plan M7.
* access: --bootstrap-keystv4 days8-21/+98
| | | | | | | The first users' SSH keys, recorded at genesis with their entries, so a swarm can be strict from its start. Auth plan M7.
* auth: logging in by keytv4 days8-7/+383
| | | | | | | | POST /auth/challenge and /auth/login/key: a node-signed challenge, valid five minutes and taken once, signed with one of the user's SSH keys (ssh-keygen -Y sign -n continuum-login), for a token. Auth plan M7 (key login, M2b).
* access: signed values judged on receipttv4 days5-19/+319
| | | | | | | | | Inspection gives each operation's kind; under strict every node refuses, at a signed place, anything but an envelope that checks and replaces the one there (deleting first as replacing does), anything within one, and above one anything replacing what holds one. Auth plan M7.
* access: a node registers before it writestv4 days3-38/+116
| | | | | | | | | Under a policy, a change by a node that isn't a member is refused with all built on it: a node's registration is written before any write of its own or through the API, not after (the registration itself exempt). Auth plan M6 (fix).
* api: signed values at the storetv4 days8-27/+416
| | | | | | | | | PUT with application/continuum-signed writes an envelope where values are signed (403/409 saying why); reads open envelopes and name the signer (x-continuum-signed-by), ?raw=true shows them. Under strict, unsigned writes reaching a signed value and the users API are 409. Auth plan M7.
* access: strict policy, signed pathstv4 days6-26/+151
| | | | | | | | | "values": "signed" (strict, requiring signatures too): the registry, _continuum/access, bans and the paths in _continuum/access/userSigned (* for any key) hold values their users signed. Envelopes read as the values they hold where the node reads protocol data. Auth plan M7.
* access: logouts apart from users' entriestv4 days7-25/+32
| | | | | | | | _continuum/logouts/<name> holds when a user's tokens were last revoked, written by the user itself or by one who may manage users, so users' entries can be signed by their managers alone. Auth plan M7.
* access: values signed by their userstv4 days5-2/+289
| | | | | | | | | access::envelope: cv1.<payload>.<signature>, the payload naming the path, value, user, time and the envelope it replaces (prev), signed with one of the user's SSH keys from the registry (keys). Checked against the registry as the writer saw it. Auth plan M7.
* access: SSH signaturestv4 days2-0/+260
| | | | | | | access::sshsig: OpenSSH's SSHSIG, verified and made natively (Ed25519, sha512/sha256), checked against OpenSSH's own test vector. Auth plan M7.
* docs: what is left of write protectiontv4 days1-1/+1
| | | | future-work brought up to date with M6.
* access: banstv4 days6-2/+91
| | | | | | | | _continuum/banned/<node ID>: every node refuses the banned node's changes from then on (judged as the ban stood) and leaves its handshakes unanswered. Auth plan M6.
* simtest: the policy, and a remake under ittv4 days2-0/+165
| | | | | | | | A swarm judging every change: honest writes everywhere, a joining node registers, a forged write stays where it was made; a compaction under the policy refuses nothing honest. Auth plan M6.
* access: signatures requiredtv4 days10-26/+290
| | | | | | | | "signatures": "required": a change counts only once a signature by its committer vouches for it, and waits until then; every node then signs every change it makes. Auth plan M6.
* access: the policy enforcedtv4 days15-11/+374
| | | | | | | | _continuum/access/policy ({"version": 1}) has every node screen every change it receives, on every path changes come in. A policy a node doesn't know stops its writes through the API. GET /admin/refused. Auth plan M6.
* access: screening received changestv4 days5-2/+418
| | | | | | | | | access::screen: a batch of received changes judged change by change, those that change what rules read applied before the next is judged; a refused change stays out with whatever builds on it, kept aside for operators; changes missing dependencies wait. Auth plan M6.
* remake: replays keep their writerstv4 days6-28/+203
| | | | | | | | A remake's replay writes each value as the user who wrote it, splitting where several users wrote under a path, so replays are judged as the original writes. Auth plan M6 (remakes, 2.4).
* remake: forgetting and releasing name their usertv4 days5-7/+53
| | | | | | | Forget records and released quarantines name the user who made them, so they are judged by its capabilities. Auth plan M6.
* access: rules by pathtv4 days4-2/+411
| | | | | | | | | | access::rules::judge: a change judged as its writer saw the document (at its dependencies): committer a member or registering itself; members' entries and votes their own; epochs and swarm ID from roots; a remake's decision by its coordinator; the rest by the registry for the user the change names. Auth plan M6.
* inspect: the paths changes touchtv4 days3-1/+300
| | | | | | | | document::inspect: each change's paths read from its operations before it is applied, the same on every node: an object's place as made, cut at lists and text; unknown objects at the root. Auth plan M6.
* bench: change pathstv4 days3-3/+155
| | | | | | | Finding the paths changes touch, from documents and from raw change bytes, measured before M6 is built. Auth plan M6 (measure first).
* simtest: signed changestv4 days2-1/+115
| | | | | | | Every change vouched for on every node within a second; a forged signature vouches for nothing. Auth plan M5.
* signatures: verified changestv4 days5-16/+32
| | | | | | | GET /admin/changes shows whether a signature by its node vouches for each change. Auth plan M5.
* signatures: on their own (SIGNATURES)tv4 days13-8/+140
| | | | | | | Signatures no sync message took go on their own within a second, to each peer not sent them yet (wire version bumped). Auth plan M5.
* signatures: with sync messagestv4 days9-45/+314
| | | | | | | Sync messages carry, for each actor's writes, the latest signature the sender checked; the receiver checks it once it holds the change. Auth plan M5.
* signatures: kept in the document filetv4 days9-62/+268
| | | | | | | A node's signatures are saved with its document (--document-file) and loaded with it. Auth plan M5.
* signatures: --sign-everytv4 days8-6/+198
| | | | | | | | Changes left unsigned are vouched for by the node's next signature: --sign-every 1s (default) signs the latest within a second, all signs every change, none only those that must be. Auth plan M5.
* signatures: changes signed by their nodetv4 days12-14/+283
| | | | | | | | | | Every node signs the changes it commits with its node key, an Ed25519 signature over the change's hash, kept beside the document. One signature on an actor's latest change vouches for its earlier ones. Protocol data and paths listed in _continuum/access/signed are signed, and writes with ?signed=true. Auth plan M5.
* bench: change signaturestv4 days2-1/+231
| | | | | | | Signing and checking change signatures, per change and per actor's latest change, measured before M5 is built (development.md). Auth plan M5 (measure first).
* docs: user names from the registrytv4 days1-3/+5
| | | | | | api.md names users as the registry has them. Auth plan M1 (docs).