Release 0.7.5 (#70)

* Resolve issue with opaque tokens not being parsed correctly

* Increase test coverage

* Further improvements to test coverage and code quality

* Add new providers.

* fixup! Add new providers.

* Cleanup.

* fixup! Cleanup.

* fixup! fixup! Cleanup.

* fixup! fixup! fixup! Cleanup.

* fixup! fixup! fixup! fixup! Cleanup.

* Memory management optimisation

24 bytes per Put < 256-4096 bytes per buffer allocation avoided (10-170x difference)

* Pooling cleanup.
This commit is contained in:
2025-10-01 12:13:10 +01:00
committed by GitHub
parent 3bbc6a1608
commit c3f23cb99b
93 changed files with 26767 additions and 4230 deletions
+448 -26
View File
@@ -4,24 +4,46 @@ type: middleware
import: github.com/lukaszraczylo/traefikoidc
summary: |
Middleware adding OpenID Connect (OIDC) authentication to Traefik routes.
Universal OpenID Connect (OIDC) authentication middleware for Traefik.
This middleware replaces the need for forward-auth and oauth2-proxy when using Traefik as a reverse proxy.
It provides a complete OIDC authentication solution with features like domain restrictions,
role-based access control, token caching, and more.
It provides a complete OIDC authentication solution with features including domain restrictions,
role-based access control, session management, comprehensive security headers, automatic token refresh,
and support for all major OIDC providers with automatic configuration.
The middleware has been tested with Auth0, Logto, Google, and other standard OIDC providers.
It includes special handling for Google's OAuth implementation to ensure compatibility.
🎯 SUPPORTED PROVIDERS (Auto-Detection):
✅ Google - Full OIDC, auto-configured for Workspace
✅ Azure AD - Enterprise OIDC with tenant/group support
✅ Auth0 - Flexible OIDC with custom claims
✅ Okta - Enterprise SSO with MFA support
✅ Keycloak - Self-hosted OIDC with full customization
✅ AWS Cognito - Managed OIDC with regional endpoints
✅ GitLab - Both GitLab.com and self-hosted instances
⚠️ GitHub - OAuth 2.0 only (limited: API access, no user claims)
✅ Generic OIDC - Any RFC-compliant OIDC provider
🔧 KEY FEATURES:
- Automatic provider detection and configuration
- Comprehensive security headers (CSP, HSTS, CORS, custom profiles)
- Domain restrictions and role-based access control
- Automatic token refresh and session management
- Rate limiting and brute force protection
- Flexible configuration with multiple deployment scenarios
- Memory-efficient operation with automatic cleanup
- Extensive logging and debugging capabilities
It supports various authentication scenarios including:
- Basic authentication with customizable callback and logout URLs
- Email domain restrictions to limit access to specific organizations
- Role and group-based access control
- Public URLs that bypass authentication
- Rate limiting to prevent brute force attacks
- Custom post-logout redirect behavior
- Role and group-based access control based on OIDC claims
- Public URLs that bypass authentication (excluded paths)
- Secure session management with encrypted cookies
- Automatic token validation and refresh
- Comprehensive security headers with multiple security profiles
- Rate limiting to prevent brute force attacks
- Custom headers using templated values from OIDC claims
- Flexible CORS configuration for API endpoints
- Configurable logging levels for debugging and monitoring
testData:
# Required parameters
@@ -80,16 +102,96 @@ testData:
cookieDomain: "" # Explicit domain for session cookies (e.g., ".example.com" for multi-subdomain setups)
overrideScopes: false # When true, replaces default scopes instead of appending (default: false)
refreshGracePeriodSeconds: 60 # Seconds before token expiry to attempt proactive refresh (default: 60)
# Security Headers Configuration (enabled by default with 'default' profile)
securityHeaders:
enabled: true
profile: "default" # Options: default, strict, development, api, custom
# CORS configuration for API endpoints
corsEnabled: false
corsAllowedOrigins:
- "https://your-frontend.com"
- "https://*.example.com"
corsAllowCredentials: true
# Custom headers
customHeaders:
X-Custom-Header: "production"
X-API-Version: "v1"
# --- Common Configuration Examples ---
#
# 🔒 HIGH-SECURITY CONFIGURATION
# testDataHighSecurity:
# providerURL: https://login.microsoftonline.com/your-tenant-id/v2.0
# clientID: your-azure-client-id
# clientSecret: your-azure-client-secret
# callbackURL: /oauth2/callback
# sessionEncryptionKey: "maximum-security-key-at-least-32-bytes-long"
# rateLimit: 50 # Restrictive rate limiting
# allowedUserDomains: ["company.com"] # Domain restriction
# allowedRolesAndGroups: ["admin", "security-team"] # Role restriction
# securityHeaders:
# enabled: true
# profile: "strict" # Maximum security headers
# corsEnabled: false # No CORS in high-security mode
# logLevel: info
# 🧑‍💻 DEVELOPMENT CONFIGURATION
# testDataDevelopment:
# providerURL: https://your-dev-provider.com
# clientID: dev-client-id
# clientSecret: dev-client-secret
# callbackURL: /oauth2/callback
# sessionEncryptionKey: "development-key-at-least-32-bytes-long"
# forceHTTPS: false # Allow HTTP in development
# excludedURLs: ["/health", "/metrics", "/debug"]
# securityHeaders:
# enabled: true
# profile: "development" # Relaxed security for development
# corsEnabled: true
# corsAllowedOrigins: ["http://localhost:*", "http://127.0.0.1:*"]
# logLevel: debug
# 🌐 API CONFIGURATION
# testDataAPI:
# providerURL: https://your-auth0-domain.auth0.com
# clientID: api-client-id
# clientSecret: api-client-secret
# callbackURL: /oauth2/callback
# sessionEncryptionKey: "api-gateway-key-at-least-32-bytes-long"
# refreshGracePeriodSeconds: 120
# securityHeaders:
# enabled: true
# profile: "api"
# corsEnabled: true
# corsAllowedOrigins: ["https://app.example.com"]
# corsAllowedMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
# corsAllowedHeaders: ["Authorization", "Content-Type", "X-API-Key"]
# headers: # Custom headers with OIDC claims
# - name: "X-User-Email"
# value: "{{.Claims.email}}"
# - name: "X-User-ID"
# value: "{{.Claims.sub}}"
# --- Provider Specific Configuration Examples ---
#
# Below are example configurations tailored for specific OIDC providers.
# Uncomment and adapt the relevant section for your provider.
# Remember to replace placeholder values (like client IDs, secrets, domains)
# with your actual credentials and settings.
# This middleware supports 9+ OIDC providers with automatic detection:
# ✅ Google - Full OIDC with auto-configuration
# ✅ Azure AD - Enterprise OIDC with tenant support
# ✅ Auth0 - Flexible OIDC with custom claims
# ✅ Okta - Enterprise OIDC with MFA support
# ✅ Keycloak - Self-hosted OIDC with full customization
# ✅ AWS Cognito - Managed OIDC with regional endpoints
# ✅ GitLab - Both GitLab.com and self-hosted
# ⚠️ GitHub - OAuth 2.0 only (not OIDC, limited functionality)
# ✅ Generic OIDC - Any RFC-compliant OIDC provider
#
# Uncomment and adapt the relevant section for your provider.
# Remember to replace placeholder values with your actual credentials.
# For all providers, ensure claims like email, roles, and groups are
# configured to be included in the ID TOKEN. This plugin validates ID tokens.
# configured to be included in the ID TOKEN (this plugin validates ID tokens).
# --- Keycloak Example ---
# testDataKeycloak:
@@ -127,18 +229,81 @@ testData:
# --- Google Workspace / Google Cloud Identity Example ---
# testDataGoogle:
# providerURL: https://accounts.google.com # This is standard for Google
# providerURL: https://accounts.google.com # Standard Google OIDC endpoint
# clientID: your-google-client-id.apps.googleusercontent.com
# clientSecret: your-google-client-secret # Store securely
# callbackURL: /oauth2/callback
# sessionEncryptionKey: "a-very-secure-key-at-least-32-bytes-long-for-google"
# scopes: # Defaults ["openid", "profile", "email"] are handled. Plugin manages Google-specifics.
# # Do NOT add 'offline_access' - plugin handles this.
# allowedUserDomains: # Useful for Google Workspace users
# scopes: # Auto-detects Google and applies proper configuration
# # Do NOT add 'offline_access' - plugin automatically handles Google-specific parameters
# allowedUserDomains: # Useful for Google Workspace domain restriction
# - your-gsuite-domain.com
# # Google includes 'hd' (hosted domain) claim which can be used with allowedUserDomains.
# # Other claims like 'email', 'sub', 'name' are standard.
# # See README.md "Provider Configuration Recommendations" for Google.
# refreshGracePeriodSeconds: 300 # Optional: Refresh 5 min before expiry
# # Google auto-config: Uses access_type=offline, prompt=consent, filters unsupported scopes
# # Available claims: email, sub, name, given_name, family_name, picture, hd (hosted domain)
# --- Okta Example ---
# testDataOkta:
# providerURL: https://your-tenant.okta.com/oauth2/default # Use your Okta domain and auth server
# clientID: your-okta-client-id
# clientSecret: your-okta-client-secret # Store securely
# callbackURL: /oauth2/callback
# sessionEncryptionKey: "a-very-secure-key-at-least-32-bytes-long-for-okta"
# scopes:
# - groups # Include for group-based access control
# allowedRolesAndGroups:
# - admin
# - developer
# - "Everyone" # Default Okta group
# # Okta config: Create OIDC Web App in admin console, configure Groups claim
# # Available claims: email, sub, name, groups, custom attributes
# --- AWS Cognito Example ---
# testDataCognito:
# providerURL: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_YourUserPool # Regional endpoint
# clientID: your-cognito-client-id
# clientSecret: your-cognito-client-secret # Store securely
# callbackURL: /oauth2/callback
# sessionEncryptionKey: "a-very-secure-key-at-least-32-bytes-long-for-cognito"
# scopes:
# - aws.cognito.signin.user.admin # Cognito-specific scope
# allowedRolesAndGroups:
# - admin
# - user
# # Cognito config: Create User Pool, App Client with authorization code grant
# # Available claims: email, sub, cognito:username, cognito:groups, custom attributes
# --- GitLab Example ---
# testDataGitLab:
# providerURL: https://gitlab.com # For GitLab.com, or use your self-hosted URL
# clientID: your-gitlab-client-id
# clientSecret: your-gitlab-client-secret # Store securely
# callbackURL: /oauth2/callback
# sessionEncryptionKey: "a-very-secure-key-at-least-32-bytes-long-for-gitlab"
# scopes:
# - read_user
# - read_api # For GitLab API access
# allowedUserDomains:
# - yourcompany.com # Optional domain restriction
# # GitLab config: Create application in GitLab Admin Area > Applications
# # Available claims: email, sub, name, nickname, preferred_username
# --- GitHub OAuth 2.0 Example (⚠️ Limited Functionality) ---
# testDataGitHub:
# providerURL: https://github.com/login/oauth # GitHub OAuth endpoint (NOT OIDC)
# clientID: your-github-client-id
# clientSecret: your-github-client-secret # Store securely
# callbackURL: /oauth2/callback
# sessionEncryptionKey: "a-very-secure-key-at-least-32-bytes-long-for-github"
# scopes:
# - user:email
# - read:user
# # ⚠️ IMPORTANT: GitHub uses OAuth 2.0, NOT OpenID Connect
# # - No ID tokens available (access tokens only)
# # - No refresh tokens (users must re-authenticate when tokens expire)
# # - No standard OIDC claims
# # - Use only for GitHub API access, not for user authentication with claims
# # GitHub config: Create OAuth App in GitHub Settings > Developer settings
# --- Auth0 Example ---
# testDataAuth0:
@@ -182,11 +347,16 @@ configuration:
The base URL of the OIDC provider. This is the issuer URL that will be used to discover
OIDC endpoints like authorization, token, and JWKS URIs.
Examples:
- https://accounts.google.com
- https://login.microsoftonline.com/tenant-id/v2.0
- https://your-auth0-domain.auth0.com
- https://your-logto-instance.com/oidc
Supported providers (auto-detected from URL):
- https://accounts.google.com (Google)
- https://login.microsoftonline.com/tenant-id/v2.0 (Azure AD)
- https://your-auth0-domain.auth0.com (Auth0)
- https://your-tenant.okta.com/oauth2/default (Okta)
- https://your-keycloak/auth/realms/your-realm (Keycloak)
- https://cognito-idp.region.amazonaws.com/pool-id (AWS Cognito)
- https://gitlab.com (GitLab)
- https://github.com/login/oauth (GitHub - OAuth 2.0 only)
- Any RFC-compliant OIDC provider (Generic)
required: true
clientID:
@@ -477,3 +647,255 @@ configuration:
value:
type: string
description: Template string for the header value
securityHeaders:
type: object
description: |
Configuration for security headers to protect against common web vulnerabilities.
Security headers are applied to all authenticated responses.
The middleware includes comprehensive security headers support with multiple profiles:
- default: Balanced security for standard web applications
- strict: Maximum security for high-security applications
- development: Relaxed policies for local development
- api: API-friendly configuration with CORS support
- custom: Full control over all security header settings
Security features include:
- Content Security Policy (CSP) to prevent XSS attacks
- HTTP Strict Transport Security (HSTS) to enforce HTTPS
- Frame Options to prevent clickjacking
- XSS Protection for browser-level filtering
- Content Type Options to prevent MIME sniffing
- CORS headers for cross-origin resource sharing
- Custom headers for additional security requirements
Example configurations:
Basic security (recommended):
securityHeaders:
enabled: true
profile: "default"
API with CORS:
securityHeaders:
enabled: true
profile: "api"
corsEnabled: true
corsAllowedOrigins: ["https://app.example.com"]
Custom configuration:
securityHeaders:
enabled: true
profile: "custom"
contentSecurityPolicy: "default-src 'self'"
corsEnabled: true
corsAllowedOrigins: ["https://*.example.com"]
customHeaders:
X-Security-Level: "high"
required: false
properties:
enabled:
type: boolean
description: |
Enable or disable security headers.
When disabled, only basic fallback headers are applied.
Default: true
required: false
profile:
type: string
description: |
Security profile to use. Each profile provides a different balance of security and functionality:
- default: Balanced security suitable for most web applications
- strict: Maximum security with very restrictive policies
- development: Relaxed policies for local development (enables localhost CORS)
- api: API-friendly configuration with configurable CORS
- custom: No defaults, use only explicitly configured settings
Default: "default"
required: false
enum:
- default
- strict
- development
- api
- custom
contentSecurityPolicy:
type: string
description: |
Content Security Policy header value to prevent XSS and code injection attacks.
Only applied when using "custom" profile or to override profile defaults.
Examples:
- "default-src 'self'" (strict)
- "default-src 'self'; script-src 'self' 'unsafe-inline'" (moderate)
- "default-src 'self' 'unsafe-inline' 'unsafe-eval'" (permissive)
required: false
strictTransportSecurity:
type: boolean
description: |
Enable HTTP Strict Transport Security (HSTS) to force HTTPS connections.
Only applied when HTTPS is detected (via TLS or X-Forwarded-Proto header).
Default: true
required: false
strictTransportSecurityMaxAge:
type: integer
description: |
HSTS max-age value in seconds. Determines how long browsers should enforce HTTPS.
Common values:
- 31536000 (1 year) - recommended for production
- 86400 (1 day) - for testing
Default: 31536000
required: false
strictTransportSecuritySubdomains:
type: boolean
description: |
Include subdomains in HSTS policy.
When true, HSTS applies to all subdomains of the current domain.
Default: true
required: false
strictTransportSecurityPreload:
type: boolean
description: |
Enable HSTS preload list eligibility.
Allows the domain to be included in browser HSTS preload lists.
Default: true
required: false
frameOptions:
type: string
description: |
X-Frame-Options header value to prevent clickjacking attacks.
Options:
- DENY: Prevents framing completely
- SAMEORIGIN: Allows framing only from the same origin
- ALLOW-FROM uri: Allows framing from specific URI
Default: "DENY"
required: false
contentTypeOptions:
type: string
description: |
X-Content-Type-Options header value to prevent MIME type sniffing.
Should typically be set to "nosniff".
Default: "nosniff"
required: false
xssProtection:
type: string
description: |
X-XSS-Protection header value for browser XSS filtering.
Recommended value: "1; mode=block"
Default: "1; mode=block"
required: false
referrerPolicy:
type: string
description: |
Referrer-Policy header value to control referrer information sharing.
Common values:
- strict-origin-when-cross-origin (recommended)
- no-referrer (most restrictive)
- same-origin (moderate)
Default: "strict-origin-when-cross-origin"
required: false
corsEnabled:
type: boolean
description: |
Enable Cross-Origin Resource Sharing (CORS) headers.
Essential for API endpoints that need to be accessed from web browsers.
Default: false
required: false
corsAllowedOrigins:
type: array
description: |
List of allowed origins for CORS requests.
Supports wildcards for flexible origin matching:
- "https://example.com" (exact match)
- "https://*.example.com" (subdomain wildcard)
- "http://localhost:*" (port wildcard, useful for development)
- "*" (allow all origins - not recommended for production)
Examples: ["https://app.example.com", "https://*.api.example.com"]
required: false
items:
type: string
corsAllowedMethods:
type: array
description: |
HTTP methods allowed for CORS requests.
Default: ["GET", "POST", "OPTIONS"]
Common additions: ["PUT", "DELETE", "PATCH"]
required: false
items:
type: string
corsAllowedHeaders:
type: array
description: |
HTTP headers allowed for CORS requests.
Default: ["Authorization", "Content-Type"]
Common additions: ["X-Requested-With", "X-API-Key"]
required: false
items:
type: string
corsAllowCredentials:
type: boolean
description: |
Allow credentials (cookies, authorization headers) in CORS requests.
Required for authenticated API requests from browsers.
Default: false
required: false
corsMaxAge:
type: integer
description: |
Maximum age in seconds for CORS preflight cache.
Reduces preflight request frequency for better performance.
Default: 86400 (24 hours)
required: false
customHeaders:
type: object
description: |
Additional custom headers to include in responses.
Useful for application-specific security requirements.
Examples:
X-Security-Level: "high"
X-API-Version: "v1"
X-Environment: "production"
required: false
disableServerHeader:
type: boolean
description: |
Remove the Server header to hide server information.
Recommended for security through obscurity.
Default: true
required: false
disablePoweredByHeader:
type: boolean
description: |
Remove the X-Powered-By header to hide technology stack information.
Default: true
required: false