Traefik Authentication Middleware¶
This document provides comprehensive information about Traefik middleware configurations for authentication, focusing on the integration with Authentik and the dual-route authentication strategy.
Overview¶
Traefik middleware provides the routing and authentication layer that integrates with Authentik to secure services while maintaining API accessibility. The middleware system implements a priority-based routing strategy that differentiates between browser and API access patterns.
Middleware Types¶
1. Authentication Middleware¶
authentik¶
The primary forward authentication middleware that communicates with the Authentik proxy outpost.
# /srv/dockerdata/traefik/dynamic/authentik.yml
http:
middlewares:
authentik:
forwardAuth:
address: http://authentik-proxy-1:9000/outpost.goauthentik.io/auth/traefik
trustForwardHeader: true
authResponseHeaders:
- X-authentik-username
- X-authentik-groups
- X-authentik-email
- X-authentik-name
- X-authentik-uid
- X-authentik-jwt
- X-authentik-meta-jwks
- X-authentik-meta-outpost
- X-authentik-meta-provider
- X-authentik-meta-app
- X-authentik-meta-version
Key Configuration: - address: Internal endpoint for Authentik proxy outpost - trustForwardHeader: Allows forwarded authentication headers - authResponseHeaders: User context headers passed to services
authentik-secured¶
Chained middleware that combines HTTPS redirect with Authentik authentication.
2. API Access Middleware¶
api-access¶
Middleware chain for API endpoints that bypasses authentication while maintaining security headers.
# /srv/dockerdata/traefik/dynamic/api-middleware.yml
http:
middlewares:
api-access:
chain:
middlewares:
- redirect-to-https
- security-headers
api-key-auth¶
Optional API key validation middleware for services that support it.
3. Utility Middleware¶
redirect-to-https¶
Forces HTTPS for all connections.
# /srv/dockerdata/traefik/dynamic/middlewares.yml
redirect-to-https:
redirectScheme:
scheme: https
permanent: true
security-headers¶
Applies security headers to all responses.
security-headers:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
forceSTSHeader: true
contentTypeNosniff: true
browserXssFilter: true
referrerPolicy: "strict-origin-when-cross-origin"
permissionsPolicy: "camera=(), microphone=(), geolocation=()"
customFrameOptionsValue: "SAMEORIGIN"
Router Configuration Patterns¶
Dual-Route Pattern (Browser + API)¶
For services that need both authenticated browser access and unauthenticated API access:
services:
myservice:
labels:
# Browser access (protected by Authentik)
- "traefik.http.routers.myservice.rule=Host(`myservice.rbnk.uk`)"
- "traefik.http.routers.myservice.entrypoints=websecure"
- "traefik.http.routers.myservice.tls.certresolver=cf"
- "traefik.http.routers.myservice.middlewares=authentik-secured@file"
- "traefik.http.routers.myservice.service=myservice"
# API access (no authentication, higher priority)
- "traefik.http.routers.myservice-api.rule=Host(`myservice.rbnk.uk`) && PathPrefix(`/api/`)"
- "traefik.http.routers.myservice-api.entrypoints=websecure"
- "traefik.http.routers.myservice-api.tls.certresolver=cf"
- "traefik.http.routers.myservice-api.middlewares=api-access@file"
- "traefik.http.routers.myservice-api.priority=100"
- "traefik.http.routers.myservice-api.service=myservice"
# HTTP to HTTPS redirect
- "traefik.http.routers.myservice-http.rule=Host(`myservice.rbnk.uk`)"
- "traefik.http.routers.myservice-http.entrypoints=web"
- "traefik.http.routers.myservice-http.middlewares=redirect-to-https@file"
# Service definition
- "traefik.http.services.myservice.loadbalancer.server.port=8080"
Browser-Only Pattern¶
For services that only need web interface protection:
services:
myservice:
labels:
# Browser access (protected by Authentik)
- "traefik.http.routers.myservice.rule=Host(`myservice.rbnk.uk`)"
- "traefik.http.routers.myservice.entrypoints=websecure"
- "traefik.http.routers.myservice.tls.certresolver=cf"
- "traefik.http.routers.myservice.middlewares=authentik-secured@file"
- "traefik.http.routers.myservice.service=myservice"
# HTTP to HTTPS redirect
- "traefik.http.routers.myservice-http.rule=Host(`myservice.rbnk.uk`)"
- "traefik.http.routers.myservice-http.entrypoints=web"
- "traefik.http.routers.myservice-http.middlewares=redirect-to-https@file"
# Service definition
- "traefik.http.services.myservice.loadbalancer.server.port=8080"
API-Only Pattern¶
For services that only provide API endpoints without web interfaces:
services:
myservice:
labels:
# API access (no authentication)
- "traefik.http.routers.myservice.rule=Host(`myservice.rbnk.uk`)"
- "traefik.http.routers.myservice.entrypoints=websecure"
- "traefik.http.routers.myservice.tls.certresolver=cf"
- "traefik.http.routers.myservice.middlewares=api-access@file"
- "traefik.http.routers.myservice.service=myservice"
# HTTP to HTTPS redirect
- "traefik.http.routers.myservice-http.rule=Host(`myservice.rbnk.uk`)"
- "traefik.http.routers.myservice-http.entrypoints=web"
- "traefik.http.routers.myservice-http.middlewares=redirect-to-https@file"
# Service definition
- "traefik.http.services.myservice.loadbalancer.server.port=8080"
Service-Specific Examples¶
Prometheus Configuration¶
labels:
# Browser access (web UI) - protected by Authentik
- "traefik.http.routers.prometheus.rule=Host(`prometheus.rbnk.uk`)"
- "traefik.http.routers.prometheus.middlewares=authentik-secured@file"
# API access route - no Authentik protection
- "traefik.http.routers.prometheus-api.rule=Host(`prometheus.rbnk.uk`) && (PathPrefix(`/api/`) || PathPrefix(`/metrics`))"
- "traefik.http.routers.prometheus-api.middlewares=api-access@file"
- "traefik.http.routers.prometheus-api.priority=100"
Rationale:
- Web UI requires human authentication for security
- /metrics endpoint must be accessible for Prometheus scrapers
- /api/ endpoints used by Grafana and other monitoring tools
LiteLLM Configuration¶
labels:
# Browser access (management UI) - protected by Authentik
- "traefik.http.routers.litellm.middlewares=authentik-secured@file"
# API access route - no Authentik protection
- "traefik.http.routers.litellm-api.rule=Host(`llm.rbnk.uk`) && (PathPrefix(`/v1/`) || PathPrefix(`/chat/`) || PathPrefix(`/completions`) || PathPrefix(`/models`) || PathPrefix(`/health`))"
- "traefik.http.routers.litellm-api.middlewares=api-access@file"
- "traefik.http.routers.litellm-api.priority=100"
Rationale: - Management UI for human configuration requires authentication - OpenAI-compatible API endpoints use API key authentication - Health checks need to be accessible for monitoring
Apprise Configuration¶
labels:
# Browser access (web UI) - protected by Authentik
- "traefik.http.routers.apprise.middlewares=authentik-secured@file"
# API access route - no Authentik protection
- "traefik.http.routers.apprise-api.rule=Host(`apprise.rbnk.uk`) && (PathPrefix(`/notify/`) || PathPrefix(`/json/`) || PathPrefix(`/get/`) || PathPrefix(`/add/`) || PathPrefix(`/del/`) || PathPrefix(`/form/`))"
- "traefik.http.routers.apprise-api.middlewares=api-access@file"
- "traefik.http.routers.apprise-api.priority=100"
Rationale: - Configuration UI requires authentication to prevent abuse - Notification API endpoints must be accessible for automated alerts - Form endpoints allow programmatic configuration management
Portainer Configuration¶
labels:
# Browser-only access - protected by Authentik
- "traefik.http.routers.portainer.middlewares=authentik-secured@file"
Rationale: - Docker management is purely web-based interface - No API access required (Portainer has its own API authentication) - High security requirement for infrastructure management
Priority System¶
Router Priority Rules¶
Traefik evaluates routes based on: 1. Priority value (higher numbers first) 2. Rule complexity (more specific rules first) 3. Order of definition (first match wins for same priority)
Priority Assignments¶
- API Routes: Priority 100 (highest)
- Specific Path Routes: Priority 50-99
- Host-Only Routes: Default priority (0)
Example Priority Configuration¶
# API route - evaluated first
- "traefik.http.routers.service-api.priority=100"
- "traefik.http.routers.service-api.rule=Host(`service.rbnk.uk`) && PathPrefix(`/api/`)"
# Admin interface - evaluated second
- "traefik.http.routers.service-admin.priority=50"
- "traefik.http.routers.service-admin.rule=Host(`service.rbnk.uk`) && PathPrefix(`/admin/`)"
# Default route - evaluated last
- "traefik.http.routers.service.rule=Host(`service.rbnk.uk`)"
Authentication Headers¶
Headers Provided by Authentik¶
When a request passes through Authentik authentication, the following headers are available to services:
X-authentik-username: [email protected]
X-authentik-groups: admin,users,editors
X-authentik-email: [email protected]
X-authentik-name: John Doe
X-authentik-uid: 12345678-1234-1234-1234-123456789012
X-authentik-jwt: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...
X-authentik-meta-jwks: https://authentik.rbnk.uk/application/o/...
X-authentik-meta-outpost: authentik-proxy
X-authentik-meta-provider: my-service-provider
X-authentik-meta-app: my-service
X-authentik-meta-version: 2025.6.4
Using Headers in Applications¶
Services can use these headers for:
- User identification: X-authentik-username or X-authentik-uid
- Authorization: X-authentik-groups for role-based access
- User context: X-authentik-name and X-authentik-email
- Token validation: X-authentik-jwt for JWT-based authentication
Example application code:
# Flask example
@app.route('/api/user-info')
def user_info():
username = request.headers.get('X-authentik-username', 'anonymous')
groups = request.headers.get('X-authentik-groups', '').split(',')
return {
'username': username,
'groups': groups,
'is_admin': 'admin' in groups
}
Debugging and Troubleshooting¶
Traefik Dashboard¶
Access the Traefik dashboard at http://localhost:8080 (internal only) to:
- View active routers and their rules
- Check middleware chains
- Monitor service health
- Debug routing issues
Common Issues¶
Router Priority Problems¶
- Symptom: API requests being authenticated instead of bypassed
- Solution: Verify API router has higher priority (100+)
- Debug: Check router order in Traefik dashboard
# Check router configuration
curl http://localhost:8080/api/http/routers | jq '.[] | select(.rule | contains("myservice"))'
Middleware Chain Errors¶
- Symptom: Services returning 500 errors or authentication loops
- Solution: Verify middleware exists and is properly chained
- Debug: Check Traefik logs for middleware errors
Authentication Header Issues¶
- Symptom: Services not receiving user context
- Solution: Verify
authResponseHeadersconfiguration in authentik middleware - Debug: Check request headers reaching the service
# Test headers with authenticated request
curl -H "Cookie: authentik_session=..." -H "X-Debug: true" https://service.rbnk.uk/debug
Testing Configurations¶
Test Authentication Flow¶
# Should redirect to Authentik (302)
curl -I https://prometheus.rbnk.uk
# Should access directly (200)
curl -I https://prometheus.rbnk.uk/metrics
# Should return service response
curl -I https://llm.rbnk.uk/v1/models
Test Middleware Chains¶
# Verify HTTPS redirect
curl -I http://service.rbnk.uk
# Verify security headers
curl -I https://service.rbnk.uk
# Verify authentication headers (with valid session)
curl -H "Cookie: authentik_session=valid_session" -v https://service.rbnk.uk
Configuration Management¶
File Organization¶
traefik/
├── dynamic/
│ ├── authentik.yml # Authentik middleware definitions
│ ├── middlewares.yml # Basic middleware (redirects, headers)
│ ├── api-middleware.yml # API-specific middleware
│ └── token-auth-middleware.yml # Token-based authentication (if used)
├── traefik.yml # Main Traefik configuration
└── docker-compose.yml # Traefik service definition
Dynamic Configuration Reloading¶
Traefik automatically reloads configuration files when they change:
# Modify middleware configuration
nano /srv/dockerdata/traefik/dynamic/authentik.yml
# Configuration reloads automatically (no restart needed)
# Check logs for reload confirmation
docker compose -f traefik/docker-compose.yml logs -f
Version Control¶
All middleware configurations are version controlled:
# Commit middleware changes
git add traefik/dynamic/
git commit -m "feat: update authentication middleware"
git push origin main
Security Considerations¶
Middleware Security¶
- Forward Authentication Security:
- Authentik proxy validates all authentication
- TrustForwardHeader only accepts headers from proxy
-
Internal communication secured by Docker networks
-
API Endpoint Security:
- API routes bypass Authentik but maintain HTTPS
- Services implement their own API authentication
-
Security headers applied to all responses
-
Header Security:
- Authentication headers only added by Authentik
- Headers cannot be spoofed from external requests
- Services should validate headers for additional security
Best Practices¶
- Always use HTTPS: All middleware chains include
redirect-to-https - Minimize API exposure: Only expose necessary API endpoints
- Apply security headers: Use
security-headersmiddleware on all routes - Monitor authentication: Log and monitor authentication patterns
- Regular updates: Keep Traefik and Authentik updated
Performance Considerations¶
Middleware Overhead¶
- Authentication Middleware: Adds ~10-50ms per request for forward auth
- Security Headers: Minimal overhead (~1ms)
- HTTPS Redirect: Adds one redirect for HTTP requests
Optimization Strategies¶
- Cache authentication results: Authentik includes session caching
- Minimize middleware chains: Only include necessary middleware
- Use appropriate priorities: Ensure API routes are matched first
- Monitor response times: Track authentication latency
Load Balancing¶
For high-traffic deployments:
# Multiple Authentik proxy instances
services:
authentik-proxy-1:
# ... configuration ...
authentik-proxy-2:
# ... configuration ...
# Load balanced middleware
middlewares:
authentik-lb:
forwardAuth:
address: http://authentik-proxy:9000/outpost.goauthentik.io/auth/traefik
# Traefik will load balance between healthy instances
Integration Examples¶
Adding Authentication to New Service¶
- Determine Access Pattern:
- Browser-only: Use
authentik-secured - Browser + API: Use dual-route pattern
-
API-only: Use
api-access -
Add Labels to Docker Compose:
-
Configure Authentik Provider:
- Create proxy provider in Authentik UI
-
Set external host and skip path regex
-
Test Configuration:
- Verify browser access requires authentication
- Confirm API access works without authentication
- Check headers are properly forwarded
Migrating from Basic Auth¶
Replace basic authentication with Authentik:
# Old configuration
labels:
- "traefik.http.routers.service.middlewares=basic-auth@file"
# New configuration
labels:
- "traefik.http.routers.service.middlewares=authentik-secured@file"
Remember to: 1. Remove basic auth middleware definitions 2. Create Authentik provider for the service 3. Update documentation for users 4. Test authentication flow thoroughly
Future Enhancements¶
Planned Improvements¶
- Advanced Authorization: Role-based access control via Authentik groups
- API Key Management: Centralized API key authentication middleware
- Rate Limiting: Request rate limiting middleware integration
- Geographic Restrictions: IP-based access control middleware
- Advanced Monitoring: Authentication and authorization metrics
Experimental Features¶
- WebAssembly Middleware: Custom authentication logic via WASM
- External Authorization: Integration with external authorization services
- Dynamic Policies: Runtime policy evaluation and enforcement
- Zero-Trust Architecture: Enhanced security model implementation