Forward auth
atreoAGENT runs a forward-auth endpoint on port 9091 that external reverse proxies can use to authenticate requests. This lets you use your preferred proxy (Caddy, Traefik, nginx) while still getting per-member ACL enforcement.
How it works
Section titled “How it works”- A client makes a request to your reverse proxy.
- Your proxy sends a subrequest to
http://<agent-ip>:9091/auth. - The agent checks the source IP and requested hostname against the ACL.
- On success (200), the proxy forwards the original request to the app.
- On failure (403), the proxy returns an access denied error.
Endpoint
Section titled “Endpoint”GET http://<agent-ip>:9091/authRequest headers
Section titled “Request headers”The agent reads these headers from the proxy’s subrequest:
| Header | Purpose |
|---|---|
X-Forwarded-For or X-Real-IP | Client’s tunnel IP — honoured only when the caller is in trusted_proxies (see below). Falls back to the TCP source address otherwise. |
X-Forwarded-Host or Host | The requested hostname (e.g. jellyfin.alice.atreo.link). X-Forwarded-Host is honoured only when the caller is in trusted_proxies. |
Trusting your reverse proxy
Section titled “Trusting your reverse proxy”The forward-auth endpoint listens on the WireGuard tunnel IP, so every tunnel peer can reach it. If the agent blindly trusted X-Forwarded-For and X-Forwarded-Host, any peer could claim another member’s IP and inherit their permissions. By default these headers are ignored.
To trust them, list the source IP of your external proxy in proxy.trusted_proxies:
proxy: enabled: false trusted_proxies: - "100.64.0.1/32" # external proxy bound to the WG tunnel IP - "192.168.1.10/32" # external proxy on a LAN hostOr via environment variable (comma-separated CIDRs):
PROXY_TRUSTED_PROXIES=100.64.0.1/32,192.168.1.10/32Without trusted_proxies, every forward-auth request is evaluated against the calling proxy’s own TCP source address — which means the ACL check sees the proxy’s IP, not the client’s, and returns 403 for everything that isn’t itself a member.
Response (200 OK)
Section titled “Response (200 OK)”When access is granted, the agent returns these headers for your proxy to pass downstream:
| Header | Example | Description |
|---|---|---|
X-Auth-User | john or local | Member name (or “local” for trusted networks) |
X-Auth-Member-ID | uuid | Member’s unique identifier |
X-Auth-Role | admin or member | Member’s role |
Response (403 Forbidden)
Section titled “Response (403 Forbidden)”Returned when the client’s IP is not authorised to access the requested app.
Trusted network bypass
Section titled “Trusted network bypass”If the source IP matches a trusted network, the request is always allowed and the response headers will show:
X-Auth-User: localX-Auth-Role: adminIntegration guides
Section titled “Integration guides”See the specific integration guides for your proxy:
© 2026 atreoLABS. All rights reserved.
WireGuard is a registered trademark of Jason A. Donenfeld.

