aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/access.md37
-rw-r--r--docs/example.toml10
-rw-r--r--docs/openapi.yaml34
-rw-r--r--docs/remakes.md5
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