ForwardAuth Middleware
The ForwardAuth middleware delegates authentication and authorization decisions to an external service, enabling centralized access control for your applications. This pattern is particularly useful for implementing Single Sign-On (SSO) and centralized authentication across multiple services.
Overview
The middleware intercepts incoming requests and forwards them to a designated authentication service. Based on the authentication service's response, it either allows the request to proceed or blocks it with an appropriate error or redirect response.
Authentication Flow
- Request Interception: The middleware captures incoming requests matching configured paths (all paths of the route when
pathsis omitted) - Forward to Auth Service: Sends a
GETrequest toauthUrlcarrying the original request's details (see Automatically Forwarded Headers) - Decision Based on Response:
- 200 OK: Request is authenticated and forwarded to the backend. Cookies set by the auth service are added to the client response (see
addAuthCookiesToResponse) - 401: Redirects to
authSignInwith302 Foundwhen it is set; otherwise responds401 - 403: Responds
403 - Other codes: Responds
401 - Auth service unreachable: Responds
500
- 200 OK: Request is authenticated and forwarded to the backend. Cookies set by the auth service are added to the client response (see
A WWW-Authenticate header returned by the auth service is relayed to the client
on a denied request.
Configuration
Basic Configuration
middlewares:
- name: forward-auth
type: forwardAuth
paths:
- /admin
rule:
authUrl: http://auth-service:8080/verify
Configuration Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
authUrl | string | Yes | - | URL of the authentication service endpoint |
authSignIn | string | No | - | Redirect URL for unauthenticated users (401 responses). If the URL contains a ? (e.g. ?rd=), the URL-encoded current request URL is appended to it |
insecureSkipVerify | boolean | No | false | Skip SSL certificate verification for auth service |
forwardHostHeaders | boolean | No | false | Send the auth request with the original request's Host instead of the authUrl host |
authRequestHeaders | array | No | [] | Additional request headers to copy to the auth request (Authorization and all cookies are always copied) |
addAuthCookiesToResponse | array | No | - | Names of the cookies from the auth service's 200 response to add to the client response. When empty or omitted, every cookie is added |
authResponseHeaders | array | No | [] | Auth response headers to copy onto the upstream request |
authResponseHeadersAsParams | array | No | [] | Auth response headers to copy onto the upstream request as query parameters |
enableHostForwarding and skipInsecureVerify were removed in v1.0; use
forwardHostHeaders and insecureSkipVerify.
Path Configuration
paths entries are regular expressions matched from the start of the path, for
example /admin, /admin/.* or /api/v[0-9]+/.*. See
Path patterns.
Automatically Forwarded Headers
The middleware automatically includes these headers in authentication requests:
X-Forwarded-Host- Original request hostX-Forwarded-Method- HTTP method of original requestX-Forwarded-Proto- Protocol (http/https) of original requestX-Forwarded-For- Client IP address chainX-Real-IP- Real client IP addressUser-Agent- Client user agent stringX-Original-URL- Complete original request URLX-Forwarded-URI- Complete original request URL (same value asX-Original-URL)Authorization- When present on the original request- All cookies of the original request
Advanced Configuration Examples
Complete ForwardAuth Setup
middlewares:
- name: comprehensive-auth
type: forwardAuth
paths:
- /admin/.*
- /api/private/.*
rule:
authUrl: http://auth-service:8080/auth/verify
# Redirect URL - current URL automatically appended to 'redirect=' parameter
authSignIn: http://auth-service:8080/login?redirect=
insecureSkipVerify: false
forwardHostHeaders: true
# Include specific headers in auth requests
authRequestHeaders:
- Authorization
- X-API-Key
- X-Client-Version
# Map auth service headers to request headers
authResponseHeaders:
- "x-user-id: X-Auth-User-ID" # Custom mapping
- "x-user-roles: X-Auth-Roles" # Custom mapping
- X-Auth-Email # Direct mapping
# Add auth headers as request parameters
authResponseHeadersAsParams:
- "x-user-id: userId" # Custom parameter name
- "x-user-roles: userRoles" # Custom parameter name
- X-Auth-Email # Direct mapping
Authentik Integration Example
version: 2
gateway:
routes:
# Protected application route
- path: /
name: protected-app
backends:
- endpoint: https://internal-app.example.com
middlewares:
- authentik-forward-auth
# Authentik outpost route (must be unprotected)
- path: /outpost.goauthentik.io
name: authentik-outpost
backends:
- endpoint: http://authentik-outpost:9000
middlewares: [] # No auth middleware for outpost endpoints
middlewares:
- name: authentik-forward-auth
type: forwardAuth
rule:
authUrl: http://authentik:9000/outpost.goauthentik.io/auth/nginx
# Public sign-in URL; the current URL is appended to 'rd='
authSignIn: https://app.example.com/outpost.goauthentik.io/start?rd=
forwardHostHeaders: true
insecureSkipVerify: false
# Include Authentik user information in requests
authResponseHeaders:
- X-authentik-username
- X-authentik-groups
- X-authentik-email
- X-authentik-name
- X-authentik-uid
- X-authentik-jwt
middlewares is a top-level key, not a child of gateway.
Development Environment Setup
middlewares:
- name: dev-auth
type: forwardAuth
paths:
- /admin/.*
rule:
authUrl: https://dev-auth.local:8443/verify
authSignIn: https://dev-auth.local:8443/login?next=
insecureSkipVerify: true # OK for development only
forwardHostHeaders: true
authRequestHeaders:
- Authorization
- X-Debug-User
authResponseHeaders:
- "x-dev-user: X-Auth-User"
- X-Auth-Roles
Header Mapping Syntax
Direct Mapping
When no custom mapping is specified, headers are passed through directly:
authResponseHeaders:
- X-User-ID # Auth service header X-User-ID → Request header X-User-ID
- X-User-Roles # Auth service header X-User-Roles → Request header X-User-Roles
Custom Mapping
Use colon syntax to map auth service headers to different request header names:
authResponseHeaders:
- "auth-user-id: X-Current-User" # auth-user-id → X-Current-User
- "auth-permissions: X-User-Perms" # auth-permissions → X-User-Perms
Parameter Mapping
Similar syntax applies to parameter mappings:
authResponseHeadersAsParams:
- "X-User-ID: currentUserId" # Header X-User-ID → Parameter currentUserId
- "X-User-Roles: roles" # Header X-User-Roles → Parameter roles
- X-User-Email # Header X-User-Email → Parameter X-User-Email
Authentication Service Requirements
Response Codes
Your authentication service should return:
- 200 OK: User is authenticated and authorized (other 2xx codes are treated as a denial)
- 401 Unauthorized: User is not authenticated (triggers redirect if
authSignInconfigured) - 403 Forbidden: User is authenticated but not authorized for this resource
- Other codes: Access denied with
401
Expected Headers
The auth service receives forwarded headers and can use them for decision-making:
- Use
X-Original-URLfor path-based authorization - Use
X-Forwarded-Methodfor method-based rules - Use custom headers specified in
authRequestHeaders
Response Headers
The auth service can include headers in responses that will be:
- Mapped to request headers via
authResponseHeaders - Added as request parameters via
authResponseHeadersAsParams - Set as cookies on the client response (the
Set-Cookies of a200response, filtered byaddAuthCookiesToResponse)
Security Considerations
SSL/TLS Configuration
- Always use HTTPS for production authentication services
- Set
insecureSkipVerify: falsein production environments - Use proper SSL certificates to prevent man-in-the-middle attacks
Header Security
- Every header named in
authResponseHeadersand every parameter named inauthResponseHeadersAsParamsis removed from the incoming request on all paths of the route, so a client cannot supply its own identity headers - Validate and sanitize headers in your authentication service
- Be cautious about which headers you forward to backend services
- Consider header injection risks when mapping auth response headers
Redirect Security
- Validate redirect URLs to prevent open redirect vulnerabilities
- Use allowlisted domains for
authSignInURLs - Consider implementing CSRF protection for authentication flows
Troubleshooting
Common Issues
Authentication loops or repeated redirects
- Check that auth service endpoints are excluded from protection
- Verify
authSignInURL is accessible without authentication - Ensure auth service doesn't redirect authenticated requests
Headers not being forwarded
- Header names are case-insensitive; query parameter names are case-sensitive
- Check that auth service is returning expected headers
- Confirm header mapping syntax is correct
SSL/Certificate errors
- Verify SSL certificates are valid and trusted
- Check if
insecureSkipVerifyshould be enabled temporarily for debugging - Ensure auth service is accessible at the configured URL