3.2 KiB
Forward-Auth Proxy Guides
/auth/api/forward · Trusted headers
These guides show how to protect a backend application with Paskia using the forward-auth (also called "external authentication") mechanism. The reverse proxy asks Paskia whether a request is allowed before forwarding it to the protected service.
For details about the endpoint the proxy calls, see /auth/api/forward. For the headers your backend receives on successful requests, see Trusted Headers.
Available guides
- Caddy — fully supported with ready-to-use snippets (
auth/setupandauth/require). - Nginx — using the
auth_requestmodule. - Traefik — using the
ForwardAuthmiddleware. - Apache APISIX — using the
forward-authplugin. - Envoy — using the
ext_authzHTTP filter. - HAProxy — using a Lua auth request.
Common requirements
No matter which proxy you use, the auth subrequest must:
- Be sent to
GET /auth/api/forwardon the Paskia backend. By default Paskia listens onlocalhost:4401; set theAUTH_UPSTREAMenvironment variable in our Caddy snippets, or point your proxy at wherever Paskia is running. - Include the query parameters Paskia needs for access control:
perm— required permission scope, repeatable (e.g.perm=myapp:login). See perm argument.max_age— how recently the user must have authenticated (e.g.max_age=5min). See max_age argument.
- Forward these request headers from the original client request:
Host— the site the user is visiting.Cookie— the session cookie, normally__Host-paskia.X-Forwarded-Method— the original HTTP method (e.g.GET,POST).X-Forwarded-Uri— the original path and query string (e.g./reports?foo=bar).Accept— decides whether a 401/403 response should be HTML (browser) or JSON (API/fetch).
- Strip hop-by-hop headers (
Connection,Upgrade,Transfer-Encoding,Keep-Alive,Proxy-Connection,TE) from the auth subrequest. The auth check is a plain HTTP request and must not carry WebSocket/body framing headers. - On a
204 No Contentresponse, copy theRemote-*response headers to the request that is forwarded to the protected backend. The headers are the whole point of the auth check. - On a 401/403 response, send Paskia's response back to the client without contacting the protected backend.
- Also proxy the
/auth/path prefix to Paskia so the login/profile UI, API endpoints, and WebSockets are reachable. Paskia's WebSocket endpoints needUpgradeandConnectionheaders passed through for that path.
Backend usage
After the proxy forwards the request, your backend can read the trusted headers. For example, in Python/FastAPI:
user_id = request.headers.get("Remote-User")
org_id = request.headers.get("Remote-Org")
permissions = request.headers.get("Remote-Groups", "").split(",")
Only trust headers that come from the proxy; never trust Remote-* headers that arrive directly from the internet. Your proxy configuration should strip any client-supplied Remote-* headers before the auth check.