Add owner-rooted node management

This commit is contained in:
Eric Wendland 2026-05-21 11:29:29 +02:00
commit b941037652
9 changed files with 1001 additions and 52 deletions

View file

@ -0,0 +1,42 @@
# ADR 0016: Owner-Rooted Node Enrollment
## Status
Accepted.
## Context
Geth needs a practical device-management flow: initialize a mesh with an
admin/owner identity, bind local daemon instances to named nodes/devices, list
devices by name, grant resource capabilities, and revoke devices. This must not
be a mutable device table because the project needs to evolve toward replicated
local-first authorization.
## Decision
Owner and node management is represented as signed keychain operations. `geth
init --admin-key <pub> --signing-key <key> --node-name <name>` records
`KeychainInit`, `AdminKeyAdd`, `UserAdd`, `DeviceAdd`, `NodeAdd`, and
`AgentBind` operations. When owner setup options are used, both `--admin-key`
and `--signing-key` are required. Geth signs canonical keychain payloads with
OpenSSH using the `geth.keychain.v1@geth.local` namespace.
The active device list is the reduced keychain view, surfaced through `geth node
list`. Renames and revocations are additional keychain operations. Resource
permissions remain resource-scoped auth operations and can be managed with
`geth node grant` and `geth node revoke-grant`.
`geth keychain sync <node>` pulls keychain operations and signatures over Iroh
from an imported peer. The receiver imports only operations with valid OpenSSH
signatures from currently trusted admin keys over the canonical keychain
payload. Discovery and peer cards still grant no trust by themselves.
## Consequences
Node names are convenience labels over stable node IDs. Endpoint rotation should
add or revoke endpoint bindings without replacing the node identity.
The current sync model is a pull-based signed operation log. It is not yet a
Keyhive-style convergent authority, does not implement advanced group
cryptography, and does not yet sign/verify replicated auth operations. Those are
future roadmap items.

View file

@ -275,15 +275,18 @@ The identity plane is `geth-keychain`: admin keys, users, devices, nodes, agents
and endpoint bindings. Endpoint rotation must not destroy higher-level node
identity. Keychain operations reduce into an active view containing current
admin keys, users, devices, node records, agent bindings, and endpoint-to-node
bindings. Revoked identity subtrees are excluded from that active view. The
daemon persists local keychain init/admin-key operations and `keychain status`
reports the reduced local view. `keychain init --signing-key <path>` writes the
canonical keychain signing payloads, runs `ssh-keygen -Y sign` with the explicit
`geth.keychain.v1@geth.local` namespace, and stores the resulting OpenSSH
signatures in local SQLite. `keychain status` reports the stored signature
count and verifies stored signatures against their canonical payloads with
OpenSSH when possible. Rejection of unsigned or invalid replicated keychain
operations is still future work.
bindings. Revoked identity subtrees are excluded from that active view. `geth
init --admin-key <pub> --signing-key <key> --node-name <name>` records an
owner/admin key, user, device, node, and agent binding as keychain operations
and signs them with OpenSSH under `geth.keychain.v1@geth.local`. Both keys are
required when owner setup options are used, so the node does not create unsigned
owner statements by accident. `geth node list` shows the active reduced node
view. `geth node rename` and `geth node revoke` record signed keychain
operations and require `--signing-key`. `geth keychain sync <node>` pulls
keychain operations and signatures from an imported peer over Iroh and imports
only operations with a valid OpenSSH signature from a currently trusted admin key
over the canonical payload. This is currently a pull-based signed operation log,
not a CRDT or Keyhive-style convergent authority.
The authorization plane is `geth-auth`: resource-local signed operation logs,
grants, revocations, groups, and `auth explain`. Auth operations reduce into a

View file

@ -182,8 +182,12 @@ resource-scoped capability decisions.
- `[x]` Tests cover signed keychain init with a generated local OpenSSH key
when `ssh-keygen` is available.
- `[x]` Tests cover local OpenSSH verification of stored keychain signatures.
- `[ ]` Future completion verifies signatures before accepting replicated
keychain ops.
- `[x]` `geth init --admin-key --signing-key --node-name` records signed
owner/user/device/node/agent binding operations.
- `[x]` `geth node list/rename/revoke` operate on the reduced keychain view.
- `[x]` `geth node rename/revoke` require an admin signing key.
- `[x]` `geth keychain sync <node>` verifies signatures from currently
trusted admin keys before accepting keychain ops.
- `[x]` Keychain operation reducer.
Acceptance criteria:
@ -192,6 +196,17 @@ resource-scoped capability decisions.
- Revoked keys/devices/nodes are excluded from active views.
- Tests cover add, rename, revoke, and endpoint rotation.
- `[~]` Node capability management.
Acceptance criteria:
- `[x]` `geth node grant <node> <resource> <capability>` records a
resource-scoped capability grant for a known node.
- `[x]` `geth node revoke-grant <resource> <grant-id>` records grant
revocation.
- `[x]` Node names can be used for management commands where the keychain view
has a unique active node name.
- `[ ]` Future completion signs auth ops and verifies signed auth ops before
accepting replicated permission changes.
- `[x]` Resource auth operation reducer.
Acceptance criteria:
- Resource create, authority set, grants, revocations, and groups reduce into