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 Fased behind an identity-aware proxy such as Pomerium, Caddy +
OAuth, nginx + oauth2-proxy, or 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 cannot
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 is any path to the Gateway that bypasses the proxy, such as firewall
holes or 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 plus
loopback for a simpler setup
How It Works
- Your reverse proxy authenticates users (OAuth, OIDC, SAML, etc.)
- Proxy adds a header with the authenticated user identity, for example
x-forwarded-user: [email protected].
- Fased checks that the request came from a trusted proxy IP configured in
gateway.trustedProxies.
- Fased extracts the user identity from the configured header
- If everything checks out, the request is authorized
Control UI Pairing Behavior
When gateway.auth.mode = "trusted-proxy" is active and the request passes
trusted-proxy checks, Control UI WebSocket sessions can connect without device
pairing identity.
Implications:
- Pairing is no longer the primary gate for Control UI access in this mode.
- Your reverse proxy auth policy and
allowUsers become the effective access
control.
- Keep gateway ingress locked to trusted proxy IPs only:
gateway.trustedProxies plus firewall.
Configuration
Current startup rejects gateway.auth.mode: "trusted-proxy" with
gateway.bind: "loopback". Use bind: "lan" or bind: "custom" and firewall
the Gateway port so only the proxy can reach it. For same-host proxy setups
where you want to keep Fased on loopback, use token/password auth behind the
proxy instead.
Configuration Reference
gateway.trustedProxies (required): proxy IP addresses to trust. Requests
from other IPs are rejected.
gateway.auth.mode (required): must be "trusted-proxy".
gateway.auth.trustedProxy.userHeader (required): header containing the
authenticated user identity.
gateway.auth.trustedProxy.requiredHeaders (optional): extra headers that
must be present for the request to be trusted.
gateway.auth.trustedProxy.allowUsers (optional): allowlist of user
identities. Empty means all authenticated users are allowed.
TLS termination and HSTS
Use one TLS termination point and apply HSTS there.
Recommended pattern: proxy TLS termination
When your reverse proxy handles HTTPS for https://control.example.com, set
Strict-Transport-Security at the proxy for that domain.
- Good fit for internet-facing deployments.
- Keeps certificate + HTTP hardening policy in one place.
- Fased should stay reachable only from the proxy. With
trusted-proxy auth,
use bind: "lan" or bind: "custom" plus firewall rules. If you keep Fased
on loopback HTTP behind a same-host proxy, use token/password auth instead.
Example header value:
Gateway TLS termination
If Fased itself serves HTTPS directly (no TLS-terminating proxy), set:
strictTransportSecurity accepts a string header value, or false to disable explicitly.
Rollout guidance
- Start with a short max age first (for example
max-age=300) while validating traffic.
- Increase to long-lived values (for example
max-age=31536000) only after confidence is high.
- Add
includeSubDomains only if every subdomain is HTTPS-ready.
- Use preload only if you intentionally meet preload requirements for your full domain set.
- Loopback-only local development does not benefit from HSTS.
Proxy Setup Examples
Pomerium
Pomerium passes identity in x-pomerium-claim-email (or other claim headers) and a JWT in x-pomerium-jwt-assertion.
Pomerium config snippet:
Caddy with OAuth
Caddy with the caddy-security plugin can authenticate users and pass identity headers.
Caddyfile snippet:
nginx + oauth2-proxy
oauth2-proxy authenticates users and passes identity in x-auth-request-email.
nginx config snippet:
Traefik with Forward Auth
Security Checklist
Before enabling trusted-proxy auth, verify:
Security Audit
fased security audit flags trusted-proxy auth with a critical severity
finding. That is intentional: this mode delegates 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?
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.
WebSocket Still Failing
Make sure your proxy:
- Supports WebSocket upgrades (
Upgrade: websocket, Connection: upgrade)
- Passes the identity headers on WebSocket upgrade requests (not just HTTP)
- Doesn’t have a separate auth path for WebSocket connections
Migration from Token Auth
If you’re moving from token auth to trusted-proxy:
- Configure your proxy to authenticate users and pass headers
- Test the proxy setup independently (curl with headers)
- Update Fased config with trusted-proxy auth
- Restart the Gateway
- Test WebSocket connections from the Control UI
- Run
fased security audit and review findings