Skip to content

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.

authentik-secured:
  chain:
    middlewares:
      - redirect-to-https
      - authentik

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.

api-key-auth:
  headers:
    customRequestHeaders:
      X-API-Access: "true"

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
# Check middleware configuration
curl http://localhost:8080/api/http/middlewares

Authentication Header Issues

  • Symptom: Services not receiving user context
  • Solution: Verify authResponseHeaders configuration 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

  1. Forward Authentication Security:
  2. Authentik proxy validates all authentication
  3. TrustForwardHeader only accepts headers from proxy
  4. Internal communication secured by Docker networks

  5. API Endpoint Security:

  6. API routes bypass Authentik but maintain HTTPS
  7. Services implement their own API authentication
  8. Security headers applied to all responses

  9. Header Security:

  10. Authentication headers only added by Authentik
  11. Headers cannot be spoofed from external requests
  12. Services should validate headers for additional security

Best Practices

  1. Always use HTTPS: All middleware chains include redirect-to-https
  2. Minimize API exposure: Only expose necessary API endpoints
  3. Apply security headers: Use security-headers middleware on all routes
  4. Monitor authentication: Log and monitor authentication patterns
  5. 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

  1. Cache authentication results: Authentik includes session caching
  2. Minimize middleware chains: Only include necessary middleware
  3. Use appropriate priorities: Ensure API routes are matched first
  4. 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

  1. Determine Access Pattern:
  2. Browser-only: Use authentik-secured
  3. Browser + API: Use dual-route pattern
  4. API-only: Use api-access

  5. Add Labels to Docker Compose:

    services:
      newservice:
        labels:
          # Choose appropriate pattern from examples above
    

  6. Configure Authentik Provider:

  7. Create proxy provider in Authentik UI
  8. Set external host and skip path regex

  9. Test Configuration:

  10. Verify browser access requires authentication
  11. Confirm API access works without authentication
  12. 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

  1. Advanced Authorization: Role-based access control via Authentik groups
  2. API Key Management: Centralized API key authentication middleware
  3. Rate Limiting: Request rate limiting middleware integration
  4. Geographic Restrictions: IP-based access control middleware
  5. Advanced Monitoring: Authentication and authorization metrics

Experimental Features

  1. WebAssembly Middleware: Custom authentication logic via WASM
  2. External Authorization: Integration with external authorization services
  3. Dynamic Policies: Runtime policy evaluation and enforcement
  4. Zero-Trust Architecture: Enhanced security model implementation