summary: "Delegate gateway authentication to a trusted reverse proxy (Pomerium, Caddy, nginx + OAuth)"
read_when:
- Running OpenClaw behind an identity-aware proxy
- Setting up Pomerium, Caddy, or nginx with OAuth in front of OpenClaw
- Fixing WebSocket 1008 unauthorized errors with reverse proxy setups
---
# Trusted Proxy Auth
> ⚠️ **Security-sensitive feature.** This mode delegates authentication entirely to your reverse proxy. Misconfiguration can expose your Gateway to unauthorized access. Read this page carefully before enabling.
## When to Use
Use `trusted-proxy` auth mode when:
- You run OpenClaw behind an **identity-aware proxy** (Pomerium, Caddy + OAuth, nginx + oauth2-proxy, Traefik + forward auth)
- Your proxy handles all authentication and passes user identity via headers
- You're in a Kubernetes or container environment where the proxy is the only path to the Gateway
- You're hitting WebSocket `1008 unauthorized` errors because browsers can't pass tokens in WS payloads
## When NOT to Use
- If your proxy doesn't authenticate users (just a TLS terminator or load balancer)
- If there's any path to the Gateway that bypasses the proxy (firewall holes, internal network access)
- If you're unsure whether your proxy correctly strips/overwrites forwarded headers
- If you only need personal single-user access (consider Tailscale Serve + loopback for simpler setup)
## How It Works
1. Your reverse proxy authenticates users (OAuth, OIDC, SAML, etc.)
2. Proxy adds a header with the authenticated user identity (e.g., `x-forwarded-user: nick@example.com`)
3. OpenClaw checks that the request came from a **trusted proxy IP** (configured in `gateway.trustedProxies`)
4. OpenClaw extracts the user identity from the configured header
5. If everything checks out, the request is authorized
trustedProxies: ["172.17.0.1"], // Traefik container IP
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
},
},
},
}
```
## Security Checklist
Before enabling trusted-proxy auth, verify:
- [ ]**Proxy is the only path**: The Gateway port is firewalled from everything except your proxy
- [ ]**trustedProxies is minimal**: Only your actual proxy IPs, not entire subnets
- [ ]**Proxy strips headers**: Your proxy overwrites (not appends) `x-forwarded-*` headers from clients
- [ ]**TLS termination**: Your proxy handles TLS; users connect via HTTPS
- [ ]**allowUsers is set** (recommended): Restrict to known users rather than allowing anyone authenticated
## Security Audit
`openclaw security audit` will flag trusted-proxy auth with a **critical** severity finding. This is intentional — it's a reminder that you're delegating security to your proxy setup.
The audit checks for:
- Missing `trustedProxies` configuration
- Missing `userHeader` configuration
- Empty `allowUsers` (allows any authenticated user)
## Troubleshooting
### "trusted_proxy_untrusted_source"
The request didn't come from an IP in `gateway.trustedProxies`. Check:
- Is the proxy IP correct? (Docker container IPs can change)
- Is there a load balancer in front of your proxy?
- Use `docker inspect` or `kubectl get pods -o wide` to find actual IPs
### "trusted_proxy_user_missing"
The user header was empty or missing. Check:
- Is your proxy configured to pass identity headers?
- Is the header name correct? (case-insensitive, but spelling matters)
- Is the user actually authenticated at the proxy?
### "trusted*proxy_missing_header*\*"
A required header wasn't present. Check:
- Your proxy configuration for those specific headers
- Whether headers are being stripped somewhere in the chain
### "trusted_proxy_user_not_allowed"
The user is authenticated but not in `allowUsers`. Either add them or remove the allowlist.