mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:40:44 +00:00
docs: Control UI identity + gateway pairing hardening + release verification
This commit is contained in:
@@ -280,6 +280,21 @@ Recreate after changing any of these:
|
||||
openclaw sandbox recreate --all
|
||||
```
|
||||
|
||||
## Security hardening
|
||||
|
||||
OpenShell sandbox helpers that read remote workspace files use a pinned file
|
||||
descriptor for the workspace root and walk ancestors from that pinned fd
|
||||
instead of re-resolving the path for each read. Combined with an identity
|
||||
recheck on every operation, this prevents a mid-turn symlink swap or a
|
||||
hot-swapped workspace mount from redirecting reads outside the intended
|
||||
remote workspace.
|
||||
|
||||
- Workspace root is opened once and pinned; later reads reuse that fd.
|
||||
- Ancestor walks traverse relative entries from the pinned fd so they cannot
|
||||
be redirected by a replacement directory higher in the path.
|
||||
- The sandbox identity is rechecked before each read, so a recreated or
|
||||
reassigned sandbox cannot silently serve files from a different workspace.
|
||||
|
||||
## Current limitations
|
||||
|
||||
- Sandbox browser is not supported on the OpenShell backend.
|
||||
|
||||
@@ -117,6 +117,33 @@ The macOS app can optionally attempt a **silent approval** when:
|
||||
|
||||
If silent approval fails, it falls back to the normal “Approve/Reject” prompt.
|
||||
|
||||
## Metadata-upgrade auto-approval
|
||||
|
||||
When an already paired device reconnects with only non-sensitive metadata
|
||||
changes (for example, display name or client platform hints), OpenClaw treats
|
||||
that as a `metadata-upgrade` and auto-approves the reconnect without
|
||||
prompting. Scope upgrades (read to write/admin) and public key changes are
|
||||
**not** eligible for metadata-upgrade auto-approval — they stay as explicit
|
||||
re-approval requests.
|
||||
|
||||
## QR pairing helpers
|
||||
|
||||
`/pair qr` renders the pairing payload as structured media so mobile and
|
||||
browser clients can scan it directly. Device deletion now also sweeps stale
|
||||
pending pairing requests for the same device id, so `nodes pending` no longer
|
||||
shows orphaned rows after a revoke.
|
||||
|
||||
## Locality and forwarded headers
|
||||
|
||||
Gateway pairing treats a connection as loopback only when both the raw socket
|
||||
and any upstream proxy evidence agree. If a request arrives on loopback but
|
||||
carries `X-Forwarded-For` / `X-Forwarded-Host` / `X-Forwarded-Proto` headers
|
||||
that point at a non-local origin, that forwarded-header evidence disqualifies
|
||||
the loopback locality claim. The pairing path then requires explicit approval
|
||||
instead of silently treating the request as a same-host connect. See
|
||||
[Trusted Proxy Auth](/gateway/trusted-proxy-auth) for the equivalent rule on
|
||||
operator auth.
|
||||
|
||||
## Storage (local, private)
|
||||
|
||||
Pairing state is stored under the Gateway state directory (default `~/.openclaw`):
|
||||
|
||||
@@ -941,6 +941,15 @@ Local device pairing:
|
||||
trusted shared-secret helper flows.
|
||||
- Tailnet and LAN connects, including same-host tailnet binds, are treated as
|
||||
remote for pairing and still need approval.
|
||||
- **Forwarded-header evidence disqualifies loopback locality.** If a request
|
||||
arrives on loopback but carries `X-Forwarded-For` / `X-Forwarded-Host` /
|
||||
`X-Forwarded-Proto` headers pointing at a non-local origin, the request is
|
||||
treated as remote for pairing, trusted-proxy auth, and Control UI device
|
||||
identity gating — it no longer qualifies for loopback auto-approval.
|
||||
- **Metadata-upgrade auto-approval** applies only to non-sensitive reconnect
|
||||
deltas on already paired devices (display name, client platform hints).
|
||||
Scope upgrades (read to write/admin) and public key changes still require
|
||||
explicit re-approval and are never silently upgraded.
|
||||
|
||||
Auth modes:
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ Important runtime rule:
|
||||
- Same-host loopback reverse proxies do **not** satisfy trusted-proxy auth.
|
||||
- For same-host loopback proxy setups, use token/password auth instead, or route through a non-loopback trusted proxy address that OpenClaw can verify.
|
||||
- Non-loopback Control UI deployments still need explicit `gateway.controlUi.allowedOrigins`.
|
||||
- **Forwarded-header evidence overrides loopback locality.** If a request arrives on loopback but carries `X-Forwarded-For` / `X-Forwarded-Host` / `X-Forwarded-Proto` headers pointing at a non-local origin, that evidence disqualifies the loopback locality claim. The request is treated as remote for pairing, trusted-proxy auth, and Control UI device-identity gating. This prevents a same-host loopback proxy from laundering forwarded-header identity into trusted-proxy auth.
|
||||
|
||||
### Configuration Reference
|
||||
|
||||
|
||||
@@ -112,6 +112,11 @@ OpenClaw has three public release lanes:
|
||||
- npm release preflight fails closed unless the tarball includes both
|
||||
`dist/control-ui/index.html` and a non-empty `dist/control-ui/assets/` payload
|
||||
so we do not ship an empty browser dashboard again
|
||||
- Post-publish verification also checks that the published registry install
|
||||
contains non-empty bundled plugin runtime deps under the root `dist/*`
|
||||
layout. A release that ships with missing or empty bundled plugin
|
||||
dependency payloads fails the postpublish verifier and cannot be promoted
|
||||
to `latest`.
|
||||
- `pnpm test:install:smoke` also enforces the npm pack `unpackedSize` budget on
|
||||
the candidate update tarball, so installer e2e catches accidental pack bloat
|
||||
before the release publish path
|
||||
|
||||
@@ -76,6 +76,31 @@ you revoke it with `openclaw devices revoke --device <id> --role <role>`. See
|
||||
- Each browser profile generates a unique device ID, so switching browsers or
|
||||
clearing browser data will require re-pairing.
|
||||
|
||||
## Personal identity (browser-local)
|
||||
|
||||
The Control UI supports a per-browser personal identity — a display name and
|
||||
avatar that are attached to outgoing messages for attribution in shared
|
||||
sessions. This identity lives in browser storage, is scoped to the current
|
||||
browser profile, and does not leave the gateway host unless you explicitly
|
||||
submit it with a request.
|
||||
|
||||
- Identity is **browser-local only**. It is not synced to other devices and is
|
||||
not part of the gateway config file.
|
||||
- Clearing site data or switching browsers resets the identity to empty; the
|
||||
Control UI does not try to reconstruct one from server state.
|
||||
- Nothing about the personal identity is persisted server-side beyond the
|
||||
normal transcript authorship metadata on messages you actually send.
|
||||
|
||||
## Runtime config endpoint
|
||||
|
||||
The Control UI fetches its runtime settings from
|
||||
`/__openclaw/control-ui-config.json`. That endpoint is gated by the same
|
||||
gateway auth as the rest of the HTTP surface: unauthenticated browsers cannot
|
||||
fetch it, and a successful fetch requires either an already valid gateway
|
||||
token/password, Tailscale Serve identity, or a trusted-proxy identity. This
|
||||
keeps Control UI feature flags and endpoint metadata from leaking to
|
||||
unauthenticated scanners on shared hosts.
|
||||
|
||||
## Language support
|
||||
|
||||
The Control UI can localize itself on first load based on your browser locale.
|
||||
@@ -109,6 +134,7 @@ locale picker lives in the Gateway Access card, not under Appearance.
|
||||
plus plugin + channel schemas when available); Raw JSON editor is
|
||||
available only when the snapshot has a safe raw round-trip
|
||||
- If a snapshot cannot safely round-trip raw text, Control UI forces Form mode and disables Raw mode for that snapshot
|
||||
- Raw JSON editor "Reset to saved" preserves the raw-authored shape (formatting, comments, `$include` layout) instead of re-rendering a flattened snapshot, so external edits survive a reset when the snapshot can safely round-trip
|
||||
- Structured SecretRef object values are rendered read-only in form text inputs to prevent accidental object-to-string corruption
|
||||
- Debug: status/health/models snapshots + event log + manual RPC calls (`status`, `health`, `models.list`)
|
||||
- Logs: live tail of gateway file logs with filter/export (`logs.tail`)
|
||||
|
||||
Reference in New Issue
Block a user