mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-12 04:04:26 +00:00
Add redis support for distributed caching (#83)
* Add redis support for distributed caching * Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! fixup! fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! fixup! fixup! fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * ... and another all nighter. * fixup! ... and another all nighter. * fixup! fixup! ... and another all nighter. * fixup! fixup! fixup! ... and another all nighter. * Resolve issue #85 by adding ability to set custom claims in JWT tokens * Remove redundant validation in auth middleware ( issue #89 ) * Add ability to set cookie prefix for session cookies ( #87 ) * fixup! Add ability to set cookie prefix for session cookies ( #87 ) * Add ability to set cookie max age - issue #91 * Potential fix for code scanning alert no. 10: Size computation for allocation may overflow Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fixup! Merge main into 0.8.0-redis: resolve conflicts --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
parent
5fcbd54955
commit
e64fc7f730
+381
-7
@@ -31,6 +31,7 @@ summary: |
|
||||
- Flexible configuration with multiple deployment scenarios
|
||||
- Memory-efficient operation with automatic cleanup
|
||||
- Extensive logging and debugging capabilities
|
||||
- Redis cache support for multi-replica deployments with automatic failover
|
||||
It supports various authentication scenarios including:
|
||||
|
||||
- Basic authentication with customizable callback and logout URLs
|
||||
@@ -73,6 +74,10 @@ testData:
|
||||
- admin
|
||||
- developer
|
||||
|
||||
# Custom claim names for Auth0 and other providers with namespaced claims
|
||||
roleClaimName: roles # JWT claim name for extracting user roles (default: "roles")
|
||||
groupClaimName: groups # JWT claim name for extracting user groups (default: "groups")
|
||||
|
||||
# ⚠️ CRITICAL for TLS termination scenarios (AWS ALB, Cloud Load Balancers, etc.)
|
||||
# When NOT specified in config: defaults to FALSE (Go zero value)
|
||||
# When running behind load balancer that terminates TLS: MUST set to TRUE
|
||||
@@ -104,6 +109,8 @@ testData:
|
||||
oidcEndSessionURL: https://accounts.google.com/logout # Provider's end session endpoint
|
||||
enablePKCE: false # Enables PKCE (Proof Key for Code Exchange) for additional security
|
||||
cookieDomain: "" # Explicit domain for session cookies (e.g., ".example.com" for multi-subdomain setups)
|
||||
cookiePrefix: "" # Custom prefix for cookie names (e.g., "_oidc_myapp_" for session isolation between middleware instances)
|
||||
sessionMaxAge: 86400 # Maximum session age in seconds (default: 86400 = 24 hours, 0 = use default)
|
||||
overrideScopes: false # When true, replaces default scopes instead of appending (default: false)
|
||||
refreshGracePeriodSeconds: 60 # Seconds before token expiry to attempt proactive refresh (default: 60)
|
||||
|
||||
@@ -137,6 +144,42 @@ testData:
|
||||
X-Custom-Header: "production"
|
||||
X-API-Version: "v1"
|
||||
|
||||
# Example with Redis cache for multi-replica deployments
|
||||
testDataWithRedis:
|
||||
# Required OIDC parameters (same as standard configuration)
|
||||
providerURL: https://auth.example.com
|
||||
clientID: your-client-id
|
||||
clientSecret: your-client-secret
|
||||
callbackURL: /oauth2/callback
|
||||
sessionEncryptionKey: your-64-character-encryption-key-at-least-32-bytes
|
||||
|
||||
# Standard optional parameters
|
||||
logLevel: info
|
||||
allowedUserDomains:
|
||||
- company.com
|
||||
|
||||
# Redis cache configuration for multi-replica support
|
||||
redis:
|
||||
enabled: true # Enable Redis caching
|
||||
address: "redis:6379" # Redis server address
|
||||
password: "redis-password" # Redis authentication password
|
||||
db: 0 # Redis database number (0-15)
|
||||
keyPrefix: "traefikoidc:" # Prefix for all Redis keys
|
||||
cacheMode: "hybrid" # Cache mode: redis, hybrid, or memory
|
||||
poolSize: 20 # Maximum number of connections
|
||||
connectTimeout: 5 # Connection timeout in seconds
|
||||
readTimeout: 3 # Read operation timeout
|
||||
writeTimeout: 3 # Write operation timeout
|
||||
enableTLS: false # Use TLS for Redis connection
|
||||
tlsSkipVerify: false # Skip TLS certificate verification
|
||||
hybridL1Size: 500 # L1 cache size for hybrid mode
|
||||
hybridL1MemoryMB: 10 # L1 memory limit for hybrid mode
|
||||
enableCircuitBreaker: true # Enable circuit breaker
|
||||
circuitBreakerThreshold: 5 # Failures before opening circuit
|
||||
circuitBreakerTimeout: 60 # Timeout before retry (seconds)
|
||||
enableHealthCheck: true # Enable periodic health checks
|
||||
healthCheckInterval: 30 # Health check interval (seconds)
|
||||
|
||||
# --- Common Configuration Examples ---
|
||||
#
|
||||
# 🔒 HIGH-SECURITY CONFIGURATION
|
||||
@@ -595,28 +638,101 @@ configuration:
|
||||
cookieDomain:
|
||||
type: string
|
||||
description: |
|
||||
Explicit domain for session cookies. This is important for multi-subdomain setups
|
||||
Explicit domain for session cookies. This is important for multi-subdomain setups
|
||||
and reverse proxy deployments to ensure consistent cookie handling.
|
||||
|
||||
|
||||
When set, all session cookies will use this domain. When not set, the domain
|
||||
is auto-detected from the request headers (X-Forwarded-Host or Host).
|
||||
|
||||
|
||||
Use a leading dot for subdomain-wide cookies (e.g., ".example.com" allows
|
||||
cookies to be shared between app.example.com, api.example.com, etc.).
|
||||
|
||||
|
||||
Use a specific domain for host-only cookies (e.g., "app.example.com" restricts
|
||||
cookies to that exact domain).
|
||||
|
||||
|
||||
This setting is crucial to prevent authentication issues like "CSRF token missing
|
||||
in session" errors that can occur when cookies are created with inconsistent domains.
|
||||
|
||||
|
||||
Examples:
|
||||
- ".example.com" - Allows all subdomains to share cookies
|
||||
- "app.example.com" - Restricts cookies to this specific host
|
||||
|
||||
|
||||
Default: "" (auto-detected from request headers)
|
||||
required: false
|
||||
|
||||
cookiePrefix:
|
||||
type: string
|
||||
description: |
|
||||
Custom prefix for session cookie names. This is essential for running multiple
|
||||
middleware instances with different authorization requirements on the same domain.
|
||||
|
||||
By default, all middleware instances use the same cookie names (_oidc_raczylo_m,
|
||||
_oidc_raczylo_a, etc.), which means they share session state. When you have
|
||||
multiple instances with different access restrictions (e.g., one for general users
|
||||
and one for admins), this session sharing can lead to authorization bypass issues.
|
||||
|
||||
Setting a unique cookiePrefix for each middleware instance ensures complete
|
||||
session isolation, preventing users authenticated via one middleware from
|
||||
automatically gaining access to routes protected by a different middleware.
|
||||
|
||||
The prefix is prepended to all session cookie names:
|
||||
- Main session cookie: {prefix}m
|
||||
- Access token cookie: {prefix}a
|
||||
- Refresh token cookie: {prefix}r
|
||||
- ID token cookie: {prefix}id
|
||||
|
||||
Examples:
|
||||
- "_oidc_userauth_" - For general user authentication middleware
|
||||
- "_oidc_adminauth_" - For admin-only authentication middleware
|
||||
- "_oidc_api_" - For API-specific authentication middleware
|
||||
|
||||
Security Note: Use different cookie prefixes AND different sessionEncryptionKey
|
||||
values for each middleware instance to ensure complete isolation.
|
||||
|
||||
Default: "_oidc_raczylo_" (standard prefix for backward compatibility)
|
||||
|
||||
See: https://github.com/lukaszraczylo/traefikoidc/issues/87
|
||||
required: false
|
||||
|
||||
sessionMaxAge:
|
||||
type: integer
|
||||
description: |
|
||||
Maximum session age in seconds before requiring re-authentication.
|
||||
|
||||
This setting controls how long a user's authentication session remains valid
|
||||
before they must authenticate again through the OIDC provider. The session
|
||||
age is tracked from the initial authentication time (created_at).
|
||||
|
||||
When a session exceeds this age:
|
||||
- The session is cleared and invalidated
|
||||
- The user is redirected to re-authenticate
|
||||
- All session cookies are removed
|
||||
|
||||
Use Cases:
|
||||
- High-security applications: Use shorter durations (e.g., 3600 = 1 hour)
|
||||
- Standard applications: Default 24 hours balances security and UX
|
||||
- Long-lived sessions: Extend for applications accessed infrequently
|
||||
(e.g., 604800 = 7 days, 2592000 = 30 days)
|
||||
|
||||
Security Considerations:
|
||||
- Shorter sessions provide better security but require more frequent logins
|
||||
- Longer sessions improve user experience but increase security risk
|
||||
- Consider your application's security requirements and user access patterns
|
||||
- This is independent of token refresh - tokens can be refreshed during the session
|
||||
|
||||
Common Values:
|
||||
- 3600 (1 hour) - High security applications
|
||||
- 28800 (8 hours) - Working day session
|
||||
- 86400 (24 hours) - Default, balances security and convenience
|
||||
- 604800 (7 days) - Weekly session for less frequently accessed apps
|
||||
- 2592000 (30 days) - Monthly session for infrequently used applications
|
||||
|
||||
Default: 86400 (24 hours)
|
||||
Minimum: 0 (uses default of 24 hours)
|
||||
|
||||
See: https://github.com/lukaszraczylo/traefikoidc/issues/91
|
||||
required: false
|
||||
|
||||
overrideScopes:
|
||||
type: boolean
|
||||
description: |
|
||||
@@ -1138,3 +1254,261 @@ configuration:
|
||||
|
||||
Prevents your resources from being embedded on other sites.
|
||||
required: false
|
||||
|
||||
redis:
|
||||
type: object
|
||||
description: |
|
||||
Optional Redis cache configuration for multi-replica deployments.
|
||||
|
||||
When running multiple Traefik instances, Redis provides shared caching to:
|
||||
- Prevent JTI replay detection false positives across replicas
|
||||
- Share token verification results between instances
|
||||
- Maintain consistent session state across the cluster
|
||||
- Improve performance by reducing redundant OIDC provider calls
|
||||
|
||||
Features:
|
||||
- Automatic failover to memory-only mode when Redis is unavailable
|
||||
- Circuit breaker pattern for resilience against Redis failures
|
||||
- Health checking with automatic recovery
|
||||
- Multiple cache modes: redis-only, hybrid (L1 memory + L2 Redis), memory-only
|
||||
- Configurable timeouts and connection pooling
|
||||
- TLS support for secure Redis connections
|
||||
|
||||
The middleware gracefully handles Redis failures by falling back to in-memory
|
||||
caching, ensuring your authentication flow continues even during Redis outages.
|
||||
|
||||
Example configuration:
|
||||
```yaml
|
||||
redis:
|
||||
enabled: true
|
||||
address: "redis:6379"
|
||||
cacheMode: "hybrid"
|
||||
enableCircuitBreaker: true
|
||||
```
|
||||
required: false
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
description: |
|
||||
Enable Redis caching for distributed session and token management.
|
||||
When enabled, the middleware will attempt to connect to Redis and use it
|
||||
for shared state across multiple Traefik instances.
|
||||
|
||||
Default: false
|
||||
required: false
|
||||
|
||||
address:
|
||||
type: string
|
||||
description: |
|
||||
Redis server address in host:port format.
|
||||
|
||||
Examples:
|
||||
- "redis:6379" (Docker/Kubernetes service)
|
||||
- "localhost:6379" (local Redis)
|
||||
- "redis.example.com:6380" (custom host/port)
|
||||
- "redis-cluster.default.svc.cluster.local:6379" (Kubernetes)
|
||||
|
||||
Required when Redis is enabled.
|
||||
required: false
|
||||
|
||||
password:
|
||||
type: string
|
||||
description: |
|
||||
Password for Redis authentication.
|
||||
Leave empty if Redis doesn't require authentication.
|
||||
|
||||
For Kubernetes deployments, you can use secret references:
|
||||
urn:k8s:secret:namespace:secret-name:key
|
||||
|
||||
Default: "" (no authentication)
|
||||
required: false
|
||||
|
||||
db:
|
||||
type: integer
|
||||
description: |
|
||||
Redis database number to use (0-15).
|
||||
Different databases can be used to isolate data between environments.
|
||||
|
||||
Default: 0
|
||||
required: false
|
||||
|
||||
keyPrefix:
|
||||
type: string
|
||||
description: |
|
||||
Prefix for all Redis keys created by this middleware.
|
||||
Useful for:
|
||||
- Avoiding key collisions with other applications
|
||||
- Identifying keys for monitoring/debugging
|
||||
- Supporting multiple environments in the same Redis instance
|
||||
|
||||
Default: "traefikoidc:"
|
||||
required: false
|
||||
|
||||
cacheMode:
|
||||
type: string
|
||||
description: |
|
||||
Determines the caching strategy:
|
||||
|
||||
- "redis": Redis-only caching. All cache operations go directly to Redis.
|
||||
Best for: Consistent state across all replicas, minimal memory usage.
|
||||
|
||||
- "hybrid": Two-tier caching with in-memory L1 and Redis L2.
|
||||
Best for: High performance with shared state, reduced Redis load.
|
||||
L1 provides fast local cache, L2 provides shared state.
|
||||
|
||||
- "memory": Memory-only caching (Redis disabled even if configured).
|
||||
Best for: Single instance deployments, development/testing.
|
||||
|
||||
Default: "redis" (when Redis is enabled)
|
||||
required: false
|
||||
enum:
|
||||
- redis
|
||||
- hybrid
|
||||
- memory
|
||||
|
||||
poolSize:
|
||||
type: integer
|
||||
description: |
|
||||
Maximum number of socket connections to Redis.
|
||||
Higher values allow more concurrent operations but consume more resources.
|
||||
|
||||
Recommendations:
|
||||
- Small deployments: 10-20
|
||||
- Medium deployments: 20-50
|
||||
- Large deployments: 50-100
|
||||
|
||||
Default: 10
|
||||
required: false
|
||||
|
||||
connectTimeout:
|
||||
type: integer
|
||||
description: |
|
||||
Timeout in seconds for establishing new connections to Redis.
|
||||
Should be higher than network latency but low enough to fail fast.
|
||||
|
||||
Default: 5 seconds
|
||||
required: false
|
||||
|
||||
readTimeout:
|
||||
type: integer
|
||||
description: |
|
||||
Timeout in seconds for Redis read operations.
|
||||
Includes the time to send the command, wait for Redis to process it,
|
||||
and receive the response.
|
||||
|
||||
Default: 3 seconds
|
||||
required: false
|
||||
|
||||
writeTimeout:
|
||||
type: integer
|
||||
description: |
|
||||
Timeout in seconds for Redis write operations.
|
||||
Should account for network latency and Redis persistence settings.
|
||||
|
||||
Default: 3 seconds
|
||||
required: false
|
||||
|
||||
enableTLS:
|
||||
type: boolean
|
||||
description: |
|
||||
Enable TLS encryption for Redis connections.
|
||||
Required when connecting to Redis instances that enforce TLS,
|
||||
such as AWS ElastiCache with encryption in transit.
|
||||
|
||||
Default: false
|
||||
required: false
|
||||
|
||||
tlsSkipVerify:
|
||||
type: boolean
|
||||
description: |
|
||||
Skip TLS certificate verification for Redis connections.
|
||||
|
||||
⚠️ WARNING: Only use in development environments.
|
||||
This option bypasses certificate validation and should never be used
|
||||
in production as it's vulnerable to man-in-the-middle attacks.
|
||||
|
||||
Default: false
|
||||
required: false
|
||||
|
||||
hybridL1Size:
|
||||
type: integer
|
||||
description: |
|
||||
Maximum number of items in the L1 (in-memory) cache for hybrid mode.
|
||||
Controls how many cache entries are kept in local memory before eviction.
|
||||
|
||||
Only applies when cacheMode is "hybrid".
|
||||
|
||||
Default: 500
|
||||
required: false
|
||||
|
||||
hybridL1MemoryMB:
|
||||
type: integer
|
||||
description: |
|
||||
Maximum memory in megabytes for L1 cache in hybrid mode.
|
||||
The cache will start evicting items when this limit is approached.
|
||||
|
||||
Only applies when cacheMode is "hybrid".
|
||||
|
||||
Default: 10 MB
|
||||
required: false
|
||||
|
||||
enableCircuitBreaker:
|
||||
type: boolean
|
||||
description: |
|
||||
Enable circuit breaker pattern for Redis connection failures.
|
||||
|
||||
When enabled, the middleware will:
|
||||
1. Track Redis operation failures
|
||||
2. Open the circuit after threshold failures (stop trying Redis)
|
||||
3. Fall back to in-memory caching
|
||||
4. Periodically attempt to reconnect (half-open state)
|
||||
5. Resume Redis operations when connection recovers
|
||||
|
||||
This prevents cascading failures and improves resilience.
|
||||
|
||||
Default: true
|
||||
required: false
|
||||
|
||||
circuitBreakerThreshold:
|
||||
type: integer
|
||||
description: |
|
||||
Number of consecutive Redis failures before opening the circuit.
|
||||
Lower values make the system more sensitive to Redis issues,
|
||||
higher values tolerate more failures before switching to fallback.
|
||||
|
||||
Default: 5
|
||||
required: false
|
||||
|
||||
circuitBreakerTimeout:
|
||||
type: integer
|
||||
description: |
|
||||
Time in seconds to wait before attempting to close the circuit.
|
||||
After this timeout, the circuit breaker will allow one test request
|
||||
to Redis. If successful, normal operations resume.
|
||||
|
||||
Default: 60 seconds
|
||||
required: false
|
||||
|
||||
enableHealthCheck:
|
||||
type: boolean
|
||||
description: |
|
||||
Enable periodic health checks for Redis connection.
|
||||
|
||||
Health checks:
|
||||
- Run in the background at regular intervals
|
||||
- Detect Redis availability without affecting request processing
|
||||
- Automatically reconnect when Redis becomes available
|
||||
- Update circuit breaker state based on health status
|
||||
|
||||
Default: true
|
||||
required: false
|
||||
|
||||
healthCheckInterval:
|
||||
type: integer
|
||||
description: |
|
||||
Interval in seconds between Redis health checks.
|
||||
Lower values detect issues faster but increase Redis load.
|
||||
Higher values reduce overhead but delay failure detection.
|
||||
|
||||
Default: 30 seconds
|
||||
required: false
|
||||
|
||||
Reference in New Issue
Block a user