docs: refresh tailscale auth rate limit refs

This commit is contained in:
Peter Steinberger
2026-04-04 14:30:02 +01:00
parent 7d22a16adb
commit 114496871d
7 changed files with 20 additions and 0 deletions

View File

@@ -2702,6 +2702,7 @@ See [Plugins](/tools/plugin).
- `gateway.auth.mode: "trusted-proxy"`: delegate auth to an identity-aware reverse proxy and trust identity headers from `gateway.trustedProxies` (see [Trusted Proxy Auth](/gateway/trusted-proxy-auth)). This mode expects a **non-loopback** proxy source; same-host loopback reverse proxies do not satisfy trusted-proxy auth.
- `gateway.auth.allowTailscale`: when `true`, Tailscale Serve identity headers can satisfy Control UI/WebSocket auth (verified via `tailscale whois`). HTTP API endpoints do **not** use that Tailscale header auth; they follow the gateway's normal HTTP auth mode instead. This tokenless flow assumes the gateway host is trusted. Defaults to `true` when `tailscale.mode = "serve"`.
- `gateway.auth.rateLimit`: optional failed-auth limiter. Applies per client IP and per auth scope (shared-secret and device-token are tracked independently). Blocked attempts return `429` + `Retry-After`.
- On the async Tailscale Serve Control UI path, failed attempts for the same `{scope, clientIp}` are serialized before the failure write. Concurrent bad attempts from the same client can therefore trip the limiter on the second request instead of both racing through as plain mismatches.
- `gateway.auth.rateLimit.exemptLoopback` defaults to `true`; set `false` when you intentionally want localhost traffic rate-limited too (for test setups or strict proxy deployments).
- Browser-origin WS auth attempts are always throttled with loopback exemption disabled (defense-in-depth against browser-based localhost brute force).
- On loopback, those browser-origin lockouts are isolated per normalized `Origin`

View File

@@ -920,6 +920,10 @@ UI/WebSocket authentication. OpenClaw verifies the identity by resolving the
and matching it to the header. This only triggers for requests that hit loopback
and include `x-forwarded-for`, `x-forwarded-proto`, and `x-forwarded-host` as
injected by Tailscale.
For this async identity check path, failed attempts for the same `{scope, ip}`
are serialized before the limiter records the failure. Concurrent bad retries
from one Serve client can therefore lock out the second attempt immediately
instead of racing through as two plain mismatches.
HTTP API endpoints (for example `/v1/*`, `/tools/invoke`, and `/api/channels/*`)
do **not** use Tailscale identity-header auth. They still follow the gateway's
configured HTTP auth mode.

View File

@@ -120,6 +120,10 @@ Common signatures:
- That cached-token retry reuses the cached scope set stored with the paired
device token. Explicit `deviceToken` / explicit `scopes` callers keep their
requested scope set instead.
- On the async Tailscale Serve Control UI path, failed attempts for the same
`{scope, ip}` are serialized before the limiter records the failure. Two bad
concurrent retries from the same client can therefore surface `retry later`
on the second attempt instead of two plain mismatches.
- `too many failed authentication attempts (retry later)` from a browser-origin
loopback client → repeated failures from that same normalized `Origin` are
locked out temporarily; another localhost origin uses a separate bucket.

View File

@@ -168,6 +168,7 @@ Quick answers plus deeper troubleshooting for real-world setups (local dev, VPS,
**Not on localhost:**
- **Tailscale Serve** (recommended): keep bind loopback, run `openclaw gateway --tailscale serve`, open `https://<magicdns>/`. If `gateway.auth.allowTailscale` is `true`, identity headers satisfy Control UI/WebSocket auth (no pasted shared secret, assumes trusted gateway host); HTTP APIs still require shared-secret auth unless you deliberately use private-ingress `none` or trusted-proxy HTTP auth.
Bad concurrent Serve auth attempts from the same client are serialized before the failed-auth limiter records them, so the second bad retry can already show `retry later`.
- **Tailnet bind**: run `openclaw gateway --bind tailnet --token "<token>"` (or configure password auth), open `http://<tailscale-ip>:18789/`, then paste the matching shared secret in dashboard settings.
- **Identity-aware reverse proxy**: keep the Gateway behind a non-loopback trusted proxy, configure `gateway.auth.mode: "trusted-proxy"`, then open the proxy URL.
- **SSH tunnel**: `ssh -N -L 18789:127.0.0.1:18789 user@host` then open `http://127.0.0.1:18789/`. Shared-secret auth still applies over the tunnel; paste the configured token or password if prompted.

View File

@@ -142,6 +142,9 @@ flowchart TD
- That cached-token retry reuses the cached scope set stored with the paired
device token. Explicit `deviceToken` / explicit `scopes` callers keep
their requested scope set instead.
- On the async Tailscale Serve Control UI path, failed attempts for the same
`{scope, ip}` are serialized before the limiter records the failure, so a
second concurrent bad retry can already show `retry later`.
- `too many failed authentication attempts (retry later)` from a localhost
browser origin → repeated failures from that same `Origin` are temporarily
locked out; another localhost origin uses a separate bucket.

View File

@@ -146,6 +146,10 @@ request hits loopback with Tailscales `x-forwarded-*` headers. Set
`gateway.auth.allowTailscale: false` if you want to require explicit shared-secret
credentials even for Serve traffic. Then use `gateway.auth.mode: "token"` or
`"password"`.
For that async Serve identity path, failed auth attempts for the same client IP
and auth scope are serialized before rate-limit writes. Concurrent bad retries
from the same browser can therefore show `retry later` on the second request
instead of two plain mismatches racing in parallel.
Tokenless Serve auth assumes the gateway host is trusted. If untrusted local
code may run on that host, require token/password auth.

View File

@@ -77,6 +77,9 @@ Prefer localhost, Tailscale Serve, or an SSH tunnel.
- Ensure the gateway is reachable (local: `openclaw status`; remote: SSH tunnel `ssh -N -L 18789:127.0.0.1:18789 user@host` then open `http://127.0.0.1:18789/`).
- For `AUTH_TOKEN_MISMATCH`, clients may do one trusted retry with a cached device token when the gateway returns retry hints. That cached-token retry reuses the token's cached approved scopes; explicit `deviceToken` / explicit `scopes` callers keep their requested scope set. If auth still fails after that retry, resolve token drift manually.
- On the async Tailscale Serve Control UI path, failed attempts for the same
`{scope, ip}` are serialized before the failed-auth limiter records them, so
the second concurrent bad retry can already show `retry later`.
- For token drift repair steps, follow [Token drift recovery checklist](/cli/devices#token-drift-recovery-checklist).
- Retrieve or supply the shared secret from the gateway host:
- Token: `openclaw config get gateway.auth.token`