docs(node): clarify headless identity and pairing state (#103964)

* docs(node): clarify headless identity storage

* docs: refresh node identity heading map
This commit is contained in:
Peter Steinberger
2026-07-10 22:55:45 +01:00
committed by GitHub
parent 6f6c802ea5
commit 42c80df6f5
3 changed files with 62 additions and 9 deletions
+42 -5
View File
@@ -62,7 +62,7 @@ Options:
- `--tls`: Use TLS for the gateway connection
- `--no-tls`: Force a plaintext Gateway connection even when the local Gateway config enables TLS
- `--tls-fingerprint <sha256>`: Expected TLS certificate fingerprint (sha256)
- `--node-id <id>`: Override node id (clears pairing token)
- `--node-id <id>`: Override the legacy client instance ID stored in `node.json` (does not reset pairing)
- `--display-name <name>`: Override the node display name
## Gateway auth for node host
@@ -101,7 +101,7 @@ Options:
- `--context-path <path>`: Gateway WebSocket context path (e.g. `/openclaw-gw`). Appended to the WebSocket URL.
- `--tls`: Use TLS for the gateway connection
- `--tls-fingerprint <sha256>`: Expected TLS certificate fingerprint (sha256)
- `--node-id <id>`: Override node id (clears pairing token)
- `--node-id <id>`: Override the legacy client instance ID stored in `node.json` (does not reset pairing)
- `--display-name <name>`: Override the node display name
- `--runtime <runtime>`: Service runtime (`node` or `bun`)
- `--force`: Reinstall/overwrite if already installed
@@ -160,9 +160,46 @@ If the node retries pairing with changed auth details (role/scopes/public key),
the previous pending request is superseded and a new `requestId` is created.
Run `openclaw devices list` again before approval.
The node host stores its node id, token, display name, and gateway connection
info in `node.json` in the OpenClaw state directory (`~/.openclaw` by default,
or `$OPENCLAW_STATE_DIR` when set).
### Identity and pairing state
The headless node separates its legacy client instance ID from the signed device
identity that the Gateway uses for pairing and routing. These files live in the
OpenClaw state directory (`~/.openclaw` by default, or `$OPENCLAW_STATE_DIR`
when set):
| File | Purpose |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `node.json` | Client instance ID under the legacy `nodeId` key, display name, and Gateway connection metadata. The client sends this value as `instanceId`. |
| `identity/device.json` | Signed Ed25519 keypair and derived device ID. For signed connections, this device ID is the routed node ID and pairing identity. |
| `identity/device-auth.json` | Paired device tokens, keyed by cryptographic device ID and role. |
`--node-id` changes only the client instance ID in `node.json`. It does not
change the cryptographic device ID or clear pairing auth. Deleting only
`node.json` likewise does not reset pairing. To revoke and re-pair a node:
1. On the Gateway, run `openclaw nodes remove --node <id|name|ip>`.
2. On the node, restart the installed service with `openclaw node restart`, or
stop and rerun the foreground `openclaw node run` command. This starts the
device-pairing flow. If `openclaw devices list` does not show a request
and the node reports `AUTH_DEVICE_TOKEN_MISMATCH`, restart or rerun it once
more. The rejected attempt clears the now-revoked local token; the next
attempt can request pairing.
3. On the Gateway, run `openclaw devices list`, then
`openclaw devices approve <deviceRequestId>`.
4. Restart or rerun the node again. A client paused for pairing does not resume
automatically after approval; this reconnect creates the separate
command-surface request.
5. On the Gateway, run `openclaw nodes pending`, then
`openclaw nodes approve <nodeRequestId>`.
The two request IDs are distinct. An applicable trusted-CIDR policy can
auto-approve the first-time device-pairing step; command-surface approval remains
a separate check.
Older OpenClaw releases could leave a legacy `token` field in `node.json`.
Current OpenClaw does not use that field and removes it the next time the node
host saves the file. Keep both files under `identity/` private; they contain the
device keypair and auth tokens.
## Exec approvals
+2
View File
@@ -1715,6 +1715,7 @@ Do not edit it by hand; run `pnpm docs:map:gen`.
- H2: Gateway auth for node host
- H2: Service (background)
- H2: Pairing
- H3: Identity and pairing state
- H2: Exec approvals
- H2: Related
@@ -4723,6 +4724,7 @@ Do not edit it by hand; run `pnpm docs:map:gen`.
- H3: Remote gateway via SSH tunnel (loopback bind)
- H3: Start a node host (service)
- H3: Pair + name
- H3: Headless identity state
- H3: Allowlist the commands
- H3: Point exec at the node
- H3: Local model inference
+18 -4
View File
@@ -82,7 +82,7 @@ On the node machine:
openclaw node run --host <gateway-host> --port 18789 --display-name "Build Node"
```
`node run` also accepts `--context-path` (Gateway WS context path), `--tls`, `--tls-fingerprint <sha256>`, and `--node-id` (override the generated node instance id).
`node run` also accepts `--context-path` (Gateway WS context path), `--tls`, `--tls-fingerprint <sha256>`, and `--node-id` (override the legacy client instance ID; this does not reset pairing).
### Remote gateway via SSH tunnel (loopback bind)
@@ -117,7 +117,7 @@ openclaw node start
openclaw node restart
```
`node install` also accepts `--context-path`, `--tls`, `--tls-fingerprint`, `--node-id`, `--runtime <node|bun>` (default: node), and `--force` to reinstall. `node status`, `node stop`, and `node uninstall` are also available.
`node install` also accepts `--context-path`, `--tls`, `--tls-fingerprint`, `--node-id` (legacy client instance ID only), `--runtime <node|bun>` (default: node), and `--force` to reinstall. `node status`, `node stop`, and `node uninstall` are also available.
### Pair + name
@@ -133,9 +133,23 @@ If the node retries with changed auth details, re-run `openclaw devices list` an
Naming options:
- `--display-name` on `openclaw node run` / `openclaw node install` (persists in `~/.openclaw/node.json` on the node, alongside the node id, token, and gateway connection info).
- `--display-name` on `openclaw node run` / `openclaw node install` (persists in `~/.openclaw/node.json` on the node, alongside the client instance ID and Gateway connection metadata).
- `openclaw nodes rename --node <id|name|ip> --name "Build Node"` (gateway override).
### Headless identity state
The headless node keeps three separate state files:
- `~/.openclaw/node.json`: the legacy client instance ID (stored as `nodeId`), display name, and Gateway connection metadata.
- `~/.openclaw/identity/device.json`: the signed device keypair and derived cryptographic device ID.
- `~/.openclaw/identity/device-auth.json`: paired device auth tokens keyed by cryptographic device ID and role.
For a signed node, the Gateway uses the cryptographic device ID for pairing and
node routing. The client instance ID is only connection metadata. Changing
`--node-id` or deleting only `node.json` therefore does not reset pairing. See
[Identity and pairing state](/cli/node#identity-and-pairing-state) for the
supported revoke-and-re-pair flow and upgrade notes.
### Allowlist the commands
Exec approvals are **per node host**. Add allowlist entries from the gateway:
@@ -504,7 +518,7 @@ openclaw node run --host <gateway-host> --port 18789
Notes:
- Pairing is still required (the Gateway will show a device pairing prompt).
- The node host stores its node id, token, display name, and gateway connection info in `~/.openclaw/node.json`.
- Client instance metadata, signed device identity, and pairing auth use separate files; see [Headless identity state](#headless-identity-state).
- Exec approvals are enforced locally via `~/.openclaw/exec-approvals.json` (see [Exec approvals](/tools/exec-approvals)).
- On macOS, the headless node host executes `system.run` locally by default. Set `OPENCLAW_NODE_EXEC_HOST=app` to route `system.run` through the companion app exec host; add `OPENCLAW_NODE_EXEC_FALLBACK=0` to require the app host and fail closed if it is unavailable.
- Add `--tls` / `--tls-fingerprint` when the Gateway WS uses TLS.