diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/access.md | 37 | ||||
| -rw-r--r-- | docs/example.toml | 10 | ||||
| -rw-r--r-- | docs/openapi.yaml | 34 | ||||
| -rw-r--r-- | docs/remakes.md | 5 |
4 files changed, 82 insertions, 4 deletions
diff --git a/docs/access.md b/docs/access.md index 5941bdb..9bd99cc 100644 --- a/docs/access.md +++ b/docs/access.md @@ -380,8 +380,11 @@ API changes nothing (`409`). Values there before the policy stay as they are unt replaced: a registry whose entries hold the users' keys turns strict as it is. As it is means trusted as it is: whatever entries, policy and bans it holds then count, plain values and envelopes alike, checked or not, whoever wrote them before (under a policy -that isn't strict, a member may write as any user). Look them over before turning -strict (`continuum-signed verify` on each entry). A value there that isn't an envelope +that isn't strict, a member may write as any user). So a swarm is best strict from its +start (`--bootstrap-keys`, A new swarm, above); one already running turns strict +through a remake (Turning a swarm strict, below), which keeps only what an operator +looked over. Writing the strict policy into it directly trusts it as it is: look it +over first (`continuum-signed verify` on each entry). A value there that isn't an envelope starts its chain anew: any envelope its user once signed for that path replacing nothing (`prev` empty) can be put there again. Without the policy, signed values may be written all the same, and plain ones too. @@ -397,6 +400,36 @@ replacing or deleting what holds one (a map made where there is none yet is fine a member writing to its document directly gets nothing there past the others: the registry, the policy and the bans change only as a user who may change them signed. +### Turning a swarm strict + +A running swarm turns strict through a remake of its own kind, `strict`: compaction +that keeps, at the places values are signed (the registry, `_continuum/access`, the +bans, the paths listed in `userSigned`), only the values an operator looked over and +signed, and sets the strict policy. What was written after its base reaches the new +epoch only by replays, which every node judges by the strict policy: a value planted +before, plain or signed by a key its planter put there itself, is gone unless the +operator kept it. + +Every node is given the keys whose signature it takes on such a remake, out of the +document (`--strict-keys`, `authorized_keys` lines): one an operator holds. A node +votes for a strict remake only with its manifest signed by one of them; without any, +it votes for none (logged, `Not voting for a strict remake`), unless +`--follow-strict-remakes`. Once a majority commits one, every node switches, as with +any remake. + +```sh +continuum-signed strict +``` + +shows the values it would keep (`GET /admin/strict-manifest`: every value at a signed +place now, by its digest, and the policy with `"values": "signed"`), signs the +manifest once confirmed (`ssh-keygen -Y sign -n continuum-strict`, with a key of +`--strict-keys`), and proposes the remake at the heads it was made at (`{"kind": +"strict", "spec": {"manifest": "<its line>\n<its signature>"}, "baseHeads": […]}`). To +keep less, take the manifest from `GET /admin/strict-manifest`, leave out of its `keep` +what should go, and sign that instead. Reading it needs reading `_continuum`, proposing +writing `_continuum/remakes`. + ## Values sealed for their readers Anyone may read the whole document: every member holds it. A value only some may read diff --git a/docs/example.toml b/docs/example.toml index cce8780..2c3a2ab 100644 --- a/docs/example.toml +++ b/docs/example.toml @@ -105,6 +105,16 @@ htpasswd = "/etc/continuum/htpasswd" # together at most. # key-logins-per-user = 100 +# SSH keys, as authorized_keys lines (ssh-ed25519 <base64> [comment]), whose signature +# on a strict remake's manifest this node takes: the values kept when the swarm turns +# strict (docs/access.md). Without, it votes for no strict remake, unless +# follow-strict-remakes. +# strict-keys = ["ssh-ed25519 AAAA… alice"] + +# Without strict-keys: vote for strict remakes all the same, taking the manifests as +# the members proposing them sign them. +# follow-strict-remakes = false + # Where the reverse proxies whose user-header is believed connect from: IP addresses (or # ranges, as ADDRESS/BITS), and unix for the API's Unix sockets (bind-addr). On a host # with other users, leave out the addresses and have the proxy use a Unix socket: others diff --git a/docs/openapi.yaml b/docs/openapi.yaml index de62b59..bb017f0 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -1643,6 +1643,30 @@ paths: '503': $ref: '#/components/responses/Error' + /admin/strict-manifest: + get: + tags: [Remakes] + summary: A manifest turning the swarm strict + description: 'Keeping every value at the places values are signed as it is now (by its digest), with the policy and `"values": "signed"`, for the caller to look over, sign (`ssh-keygen -Y sign -n continuum-strict`) and propose as a `strict` remake at `heads` (`baseHeads`). Needs reading `_continuum`.' + responses: + '200': + description: The manifest's line, the values it keeps, the heads they are at. + content: + application/json: + schema: + type: object + properties: + manifest: { type: string } + values: + type: array + items: + type: object + properties: + path: { type: array, items: { type: string } } + value: {} + heads: { type: array, items: { type: string } } + namespace: { type: string } + /admin/epochs: get: tags: [Remakes] @@ -2878,16 +2902,24 @@ components: properties: kind: type: string - enum: [compact, replace, import] + enum: [compact, replace, import, strict] default: compact spec: description: | `compact`: none. `replace`: `{document: <store root object>, rules}`. `import`: `{document: <base64 of an Automerge document>, rules}`; its `_continuum` and history are left out, Automerge types are kept. + `strict`: `{manifest: "<its line>\n<its signature>"}`, as + `GET /admin/strict-manifest` gives the line, signed by a key of + `--strict-keys` (`403` from a node that takes no such manifest). oneOf: - type: 'null' - type: object + required: [manifest] + additionalProperties: false + properties: + manifest: { type: string } + - type: object required: [document] additionalProperties: false properties: diff --git a/docs/remakes.md b/docs/remakes.md index b8e0fa6..fc938c7 100644 --- a/docs/remakes.md +++ b/docs/remakes.md @@ -9,8 +9,11 @@ A remake moves the whole swarm to a new document, the next *epoch*. Use one to: * **import** (`import`): new content from an Automerge document, e.g. a backup made with `GET /admin/document`. Unlike `replace`, Automerge types survive (text, counters, bytes, timestamps, floats). +* **strict** (`strict`): the same as `compact`, turning the swarm strict, keeping only + the signed values an operator's manifest names ([`access.md`](access.md), Turning a + swarm strict). -Everything else is the same for all three kinds. All endpoints need the node's basic +Everything else is the same for all the kinds. All endpoints need the node's basic auth; examples leave it out. ## How a remake runs |
