Authentik Forward Auth Patterns¶
Guide for integrating third-party applications with Authentik SSO using forward authentication.
Authentication Pattern Categories¶
| Pattern | When to Use | Complexity |
|---|---|---|
| Native OIDC/OAuth2 | App has OIDC support | Low - configure in app |
| Standard Forward Auth | App reads X-Remote-User headers |
Medium - proxy provider |
| Custom Headers Forward Auth | App needs specific headers | High - property mappings |
| No SSO | App has no external auth | N/A - use app's native auth |
Decision Tree¶
Does the app support OIDC/OAuth2?
├── YES → Use Native OIDC (preferred)
└── NO → Does it support proxy/header auth?
├── YES → Does it use standard headers (X-Remote-User)?
│ ├── YES → Use Standard Forward Auth
│ └── NO → Use Custom Headers Forward Auth
└── NO → No SSO available, use native auth
Pattern 1: Native OIDC/OAuth2 (Preferred)¶
Examples: Grafana, Paperless-ngx, WikiJS, Gitea, Portainer
How it works: App directly communicates with Authentik using OAuth2/OIDC protocol.
Authentik Setup¶
- Create OAuth2/OpenID Provider
- Provider type:
OAuth2/OpenID Connect - Client type:
Confidential - Redirect URIs:
https://app.bogocat.com/callback(app-specific) - Signing Key: Select or create
-
Scopes:
openid,profile,email -
Create Application
- Name:
App Name - Slug:
app-slug -
Provider: Select the OAuth2 provider
-
Configure App
- Client ID: From provider
- Client Secret: From provider
- Issuer URL:
https://auth.bogocat.com/application/o/app-slug/
No Ingress Auth Annotations Needed¶
Standard ingress without forward auth:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app
spec:
rules:
- host: app.bogocat.com
http:
paths:
- path: /
backend:
service:
name: app
port:
number: 80
Pattern 2: Standard Forward Auth¶
Examples: Most apps with "trusted proxy" or "remote user" settings
How it works: Authentik intercepts requests, authenticates user, passes standard headers.
Default Headers Sent by Authentik¶
| Header | Value |
|---|---|
X-authentik-username |
Username |
X-authentik-uid |
User ID |
X-authentik-email |
Email address |
X-authentik-name |
Display name |
X-authentik-groups |
Comma-separated groups |
Many apps also accept these as:
- X-Remote-User / Remote-User
- X-Forwarded-User
- X-Forwarded-Email
Authentik Setup¶
- Create Proxy Provider
- Provider type:
Proxy Provider - Authorization flow:
default-provider-authorization-implicit-consent - Forward auth mode:
Forward auth (single application) -
External host:
https://app.bogocat.com -
Create Application
- Name:
App Name - Slug:
app-slug -
Provider: Select the proxy provider
-
Assign to Outpost
- Go to Outposts →
authentik Embedded Outpost - Add application to the list
Ingress Configuration¶
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app
annotations:
nginx.ingress.kubernetes.io/auth-url: "http://authentik-server.authentik.svc.cluster.local/outpost.goauthentik.io/auth/nginx"
nginx.ingress.kubernetes.io/auth-signin: "https://app.bogocat.com/outpost.goauthentik.io/start?rd=https://$http_host$request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-uid"
spec:
rules:
- host: app.bogocat.com
Pattern 3: Custom Headers Forward Auth¶
Examples: OtterWiki (x-otterwiki-*), legacy apps with non-standard headers
How it works: Authentik sends default headers, property mappings translate to app-specific headers.
Step 1: Create Property Mapping¶
In Authentik → Customization → Property Mappings → Create → Scope Mapping
Name: otterwiki-headers
Scope name: otterwiki
Expression:
return {
"ak_proxy": {
"user_attributes": {
"additionalHeaders": {
"x-otterwiki-name": request.user.username,
"x-otterwiki-email": request.user.email,
"x-otterwiki-permissions": "READ,WRITE,UPLOAD,ADMIN"
}
}
}
}
Step 2: Create Proxy Provider with Mapping¶
- Create Proxy Provider (same as Pattern 2)
- In "Advanced protocol settings" → Property mappings
- Add the custom scope mapping (
otterwiki-headers)
Step 3: Configure App¶
Configure the app to use proxy header authentication:
Known Apps Requiring Custom Headers¶
| App | Headers Required | Mapping Expression |
|---|---|---|
| OtterWiki | x-otterwiki-name, x-otterwiki-email, x-otterwiki-permissions |
See above |
| Apache Guacamole | REMOTE_USER |
{"REMOTE_USER": request.user.username} |
Proxy Provider Variables Reference¶
Required Settings¶
| Setting | Value | Notes |
|---|---|---|
| Name | app-proxy |
Convention: {app}-proxy |
| Authorization flow | default-provider-authorization-implicit-consent |
Or explicit consent |
| Forward auth mode | Forward auth (single application) |
For single-domain apps |
| External host | https://app.bogocat.com |
Must match ingress host |
Optional Settings¶
| Setting | Default | When to Change |
|---|---|---|
| Token validity | 24 hours | Increase for long sessions |
| Intercept header auth | Enabled | Disable if app sends own auth headers |
| Basic auth | Disabled | Enable for API/CLI access |
| Property mappings | None | Add for custom headers |
Application Variables Reference¶
Required Settings¶
| Setting | Value | Notes |
|---|---|---|
| Name | App Name |
Display name |
| Slug | app-slug |
URL-safe, lowercase |
| Provider | app-proxy |
Must match provider name |
Optional Settings¶
| Setting | Default | When to Change |
|---|---|---|
| Launch URL | Auto | Override if app has specific entry point |
| Icon | None | Upload for app library |
| Policy bindings | None | Add for group-based access control |
Outpost Assignment¶
Critical: Apps only work after being assigned to an outpost.
Using Embedded Outpost¶
- Applications → Outposts →
authentik Embedded Outpost - Click Edit
- In "Applications" multi-select, add your app
- Click Update
Verifying Assignment¶
# Check if outpost knows about the app
curl -s http://auth.internal/outpost.goauthentik.io/auth/nginx \
-H "Host: app.bogocat.com" | head -5
# Should return 401 (not 404)
Troubleshooting¶
404 on auth request¶
- App not assigned to outpost
- External host doesn't match ingress hostname
500 Internal Server Error¶
- Ingress auth-url can't reach Authentik
- Check:
kubectl get svc -n authentik
Redirect loop¶
- External host protocol mismatch (http vs https)
- X-Forwarded-Proto not set correctly
User info not passed to app¶
- Check auth-response-headers includes needed headers
- For custom headers, verify property mapping is assigned to provider