traefikoidc

package module
v1.0.33 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: MIT Imports: 57 Imported by: 0

README

Traefik OIDC Middleware

OpenID Connect authentication middleware for Traefik. Replaces forward-auth + oauth2-proxy. Auto-detects all major OIDC providers, validates ID tokens, manages sessions, and forwards user identity to downstream services.

This repository is maintained at orangeboyChen/traefikoidc and is based on lukaszraczylo/traefikoidc.

Documentation

Provider support

Provider OIDC Refresh Auto-detected by
Google Full Yes accounts.google.com
Azure AD Full Yes login.microsoftonline.com, sts.windows.net
Auth0 Full Yes *.auth0.com
Okta Full Yes *.okta.com, *.oktapreview.com, *.okta-emea.com
Keycloak Full Yes host containing keycloak, or /realms/ in path (covers KC <17 /auth/realms/ and 17+ /realms/)
AWS Cognito Full Yes cognito-idp.*.amazonaws.com
GitLab Full Yes gitlab.com
GitHub OAuth 2.0 only — no ID token, no refresh No github.com
Generic Full Yes any RFC-compliant .well-known/openid-configuration

Authentication and claim extraction use the ID token. Ensure your provider includes required claims (email, roles, groups) in the ID token, not just the access token or UserInfo endpoint.

Install

Enable the plugin in Traefik's static configuration:

# traefik.yml
experimental:
  plugins:
    traefikoidc:
      moduleName: github.com/orangeboyChen/traefikoidc
      version: v1.0.33

Then attach the middleware in your dynamic configuration (see Quickstart below).

This middleware tracks the current Traefik helm chart release. If it fails to load, update Traefik first.

Verify release signatures

Release checksums are signed with cosign keyless signing:

cosign verify-blob \
  --certificate-identity-regexp "https://github.com/lukaszraczylo/traefikoidc/.*" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  --bundle "traefikoidc_v<version>_checksums.txt.sigstore.json" \
  traefikoidc_v<version>_checksums.txt

Quickstart

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc-auth
  namespace: traefik
spec:
  plugin:
    traefikoidc:
      providerURL: https://accounts.google.com
      clientID: 1234567890.apps.googleusercontent.com
      clientSecret: urn:k8s:secret:traefik-oidc:CLIENT_SECRET
      sessionEncryptionKey: urn:k8s:secret:traefik-oidc:SESSION_KEY
      callbackURL: /oauth2/callback
      logoutURL: /oauth2/logout
      postLogoutRedirectURI: /
      # forceHTTPS defaults to true (secure-by-default). Only set false if you
      # serve OIDC over plaintext HTTP for local dev.
      allowedUserDomains: [company.com]
      allowedRolesAndGroups: [admin, developer]
      excludedURLs: [/health, /metrics]

More example configs in examples/.

Required parameters

Parameter Description
providerURL Issuer URL (used for OIDC discovery).
clientID OAuth 2.0 client ID.
clientSecret OAuth 2.0 client secret. Supports urn:k8s:secret:ns:name:key. Required when clientAuthMethod is unset, client_secret_post, or client_secret_basic; optional with private_key_jwt.
sessionEncryptionKey Cookie encryption key, min 32 bytes.
callbackURL Callback path, e.g. /oauth2/callback.

Common optional parameters

Full reference in docs/CONFIGURATION.md.

Parameter Default Purpose
forceHTTPS true Forces https:// in redirect URIs. Leave at default behind any TLS-terminating LB (AWS ALB, GCP LB, Azure App Gateway). Set false only for plaintext HTTP local dev.
logoutURL callbackURL + "/logout" RP-initiated logout path.
postLogoutRedirectURI / Where to send users after logout.
scopes appended to openid profile email Extra OAuth scopes. Set overrideScopes: true to replace defaults.
extraAuthParams none Map of extra query parameters appended to the authorization request (e.g. screen_hint: signup, login_hint, ui_locales, prompt). Plugin-managed params (client_id, state, nonce, redirect_uri, code_challenge, scope, response_type, …) cannot be overridden.
excludedURLs none Paths that bypass auth, matched at a path-segment or file-extension boundary (e.g. /public matches /public, /public/sub and /public.json, but not /publicsecret).
bypassSourceRanges none CIDRs whose transport-level source IP bypasses OIDC. The plugin ignores X-Forwarded-For to prevent spoofing.
allowedUserDomains none Restrict to email domains.
allowedUsers none Restrict to specific addresses (or claim values when userIdentifierClaim != email).
allowedRolesAndGroups none Require any of these roles/groups from ID-token claims.
roleClaimName / groupClaimName roles / groups For namespaced claims (Auth0).
userIdentifierClaim email Use sub, oid, upn, or preferred_username for users without email.
enablePKCE false PKCE on the auth code flow.
cookieDomain auto Set explicitly for multi-subdomain setups (.example.com).
cookiePrefix _oidc_raczylo_ Unique prefix per middleware instance to isolate sessions.
cookiePath / Restrict cookies to a path prefix. Set to the middleware's path (e.g. /app) to prevent the browser from sending OIDC cookies to unprotected paths, avoiding 431 "Request Header Or Cookie Too Large" errors on mixed-use domains.
sessionMaxAge 86400 Session lifetime in seconds.
refreshGracePeriodSeconds 60 Proactively refresh tokens this many seconds before expiry.
maxRefreshTokenAgeSeconds 21600 Heuristic max stored refresh-token lifetime (6h). Past this, the plugin treats the RT as expired without contacting the IdP — returns 401 to AJAX, full re-auth on navigations. Set 0 to disable. Tune to match your IdP's RT TTL.
rateLimit 100 Requests/sec. Min 10.
logLevel info debug, info, error.
audience clientID Custom access-token audience (Auth0 custom APIs).
strictAudienceValidation false Reject mismatched audiences. Set true in production.
allowOpaqueTokens / requireTokenIntrospection false Accept opaque access tokens via RFC 7662.
disableReplayDetection false Disable JTI cache. Use Redis instead for multi-replica.
allowPrivateIPAddresses false Permit private-IP providerURL (internal Keycloak, etc.).
minimalHeaders false Reduce forwarded headers (mitigates HTTP 431).
stripAuthCookies false Strip OIDC cookies from backend hop (mitigates HTTP 431).
caCertPath / caCertPEM none Trust an internal CA for the provider's TLS.
insecureSkipVerify false Local dev only. Disables TLS verification, logs a security warning.
clientAuthMethod client_secret_post Client auth method. Set private_key_jwt for RFC 7523 JWT assertions (Entra ID, Okta, Auth0, Keycloak). See Client authentication via private key JWT.
clientAssertionPrivateKey none Inline PEM private key for private_key_jwt. Mutually exclusive with clientAssertionKeyPath.
clientAssertionKeyPath none File path to PEM private key for private_key_jwt.
clientAssertionKeyID none JWS kid header. Required when clientAuthMethod=private_key_jwt; must match the public key registered with the IdP.
clientAssertionAlg RS256 JWS alg for private_key_jwt. Supported: RS256/384/512, PS256/384/512, ES256/384/512.
enableBackchannelLogout / backchannelLogoutURL false / none OIDC Back-Channel Logout (server-to-server).
enableFrontchannelLogout / frontchannelLogoutURL false / none OIDC Front-Channel Logout (iframe).
redis disabled See docs/REDIS.md.
dynamicClientRegistration disabled See docs/DCR.md.

Production gotchas

Upgrading from an earlier release
  • Sessions are re-issued once. Session cookies are now AES-256 encrypted (previously signed only) and their cryptographic lifetime tracks sessionMaxAge (previously a fixed 30 days). Existing cookies become invalid on upgrade, so users re-authenticate one time.
  • Invalid configuration now fails closed at startup instead of being silently accepted: a sessionEncryptionKey shorter than 32 bytes, a rateLimit below 10, a missing callbackURL, or a non-HTTPS remote providerURL are rejected. Plaintext HTTP is permitted only for loopback hosts (local development).
TLS termination at a load balancer

forceHTTPS defaults to true, so redirect URIs always use https://. This is the right default behind AWS ALB, GCP LB, Azure App Gateway, or any LB that terminates TLS — X-Forwarded-Proto is unreliable (ALB may overwrite it).

Only set forceHTTPS: false when you actually serve OIDC over plaintext HTTP (local dev). See issue #82.

Multi-replica deployments

Each replica keeps its own in-memory JTI cache → false positive "token replay detected" when the same token hits different replicas. Two options:

  1. Set disableReplayDetection: true (loses replay protection).
  2. Enable Redis for shared state (recommended) — see docs/REDIS.md.

For IdP-initiated logout (back/front-channel) in multi-replica setups, Redis is required so a logout on one instance invalidates sessions on the others. Front-channel logout requests must include a matching iss query parameter; requests that omit it are rejected with 400.

Multiple middleware instances on the same host

Each instance must use a unique cookiePrefix and sessionEncryptionKey, otherwise a session minted by one instance can grant access through another. See issue #87.

Bearer-token (M2M) authentication

Opt-in path for API clients that present Authorization: Bearer <jwt> instead of logging in via the browser flow. Default off. When enabled, the middleware validates the bearer JWT against the configured OIDC provider (signature, issuer, audience, expiry) and forwards the request downstream with the principal headers — no cookie session is created.

enableBearerAuth: true
audience: https://api.example.com   # REQUIRED when bearer is enabled
# optional, defaults shown:
bearerIdentifierClaim: sub          # claim used as X-Forwarded-User
stripAuthorizationHeader: true      # drop the raw token before forwarding
bearerEmitWWWAuthenticate: true     # RFC 6750 hint on 401s
bearerOverridesCookie: false        # cookie wins when both are present (safer)
maxTokenAgeSeconds: 86400           # 24h cap on iat
bearerFailureThreshold: 20          # consecutive 401s/IP before 429 throttle

Hardening built in by default:

  • Audience required. Startup fails if enableBearerAuth=true and audience is unset. Eliminates the "token issued for service B accepted by A" confusion vector.
  • ID tokens explicitly rejected. Bearer is access-token-only. ID tokens (detected via nonce, typ: at+jwt, token_use, scope, or audience shape) return 401.
  • alg and kid pinned at the entrypoint. Asymmetric-only allowlist (RS256/384/512, PS256/384/512, ES256/384/512); kid length and charset capped — both checked before any JWKS fetch so attacker noise can't amplify into upstream calls.
  • Identifier sanitised. Default identifier source is sub; email is rejected unless explicitly opted in (which the middleware still refuses to avoid the unverified-email spoofing footgun). Control characters, bidi- override codepoints, and the delimiters , ; = are all rejected before the value reaches X-Forwarded-User.
  • Multi-audience tokens require azp. When aud is an array of more than one element, the token must carry azp == clientID.
  • iat upper-age bound. Tokens older than maxTokenAgeSeconds are rejected even if exp is far in the future.
  • Per-IP 401 throttle. After bearerFailureThreshold consecutive 401s from one source IP, further bearer requests from that IP are rejected with 429 Too Many Requests + Retry-After.
  • Cookie-wins by default. When both a session cookie and an Authorization: Bearer header arrive on the same request, the cookie path runs (safer against browser/extension/proxy bearer injection). Set bearerOverridesCookie: true for the AWS/GCP/Kubernetes convention.
  • Replay protection preserved. The bearer path skips the JTI Set (so the same token can be reused) but the Get stays active — RevokeToken still terminates a bearer token immediately.
  • Excluded URLs strip Authorization. When enableBearerAuth=true, excluded paths (e.g. /health, /metrics) get the Authorization header removed before forwarding so the token can't leak into public endpoint logs.
  • Optional real-time revocation. Set requireTokenIntrospection: true to call RFC 7662 introspection on every cache miss; revoked tokens fail immediately. Introspection endpoint failures return 503 (distinguishes infra outage from credential rejection).

Obtaining bearer tokens — minting is the IdP's job, not the middleware's. The canonical M2M flow is OAuth 2.0 client_credentials (RFC 6749 §4.4); Google requires JWT bearer assertion (RFC 7523) instead. Minimal Auth0-shape request:

curl -s -X POST https://issuer.example.com/oauth/token \
  -H 'Content-Type: application/json' \
  -d '{
    "grant_type":    "client_credentials",
    "client_id":     "your-m2m-client-id",
    "client_secret": "your-m2m-client-secret",
    "audience":      "https://api.example.com",
    "scope":         "api:read api:write"
  }'

The audience you request from the IdP must match the audience you configured on the middleware. Per-provider endpoints, parameter names, and gotchas (Entra v2 endpoint, Cognito Resource Servers, Keycloak audience mappers, Google's opaque-token quirk) are documented in docs/BEARER_AUTH.md.

Full threat model, configuration matrix, and follow-up gaps in docs/BEARER_AUTH.md.

SSE and WebSocket endpoints

Browser clients cannot follow an OIDC 302 redirect on an SSE stream or a WebSocket upgrade. The middleware handles this automatically:

  • SSE (Accept: text/event-stream) and WebSocket (Upgrade: websocket) requests skip the OIDC redirect.
  • They are not unauthenticated — a valid encrypted session cookie is required, otherwise the request is rejected. The session must already exist (i.e. the user logged in via a normal HTTP page first).
  • X-Forwarded-User is forwarded from the session.
  • Validation is cookie-only (no JWK fetch), so streaming keeps working during brief IdP outages.

No configuration needed — this is implicit behavior.

HTTP 431 from backends

Either the ID token or the chunked OIDC cookies overflow your backend's header buffer. Combine these as needed:

minimalHeaders: true     # drop X-Auth-Request-Token et al.
stripAuthCookies: true   # strip _oidc_raczylo_* cookies on the backend hop

Cookies remain in the browser; only the Traefik→backend hop is affected. See #64, #122.

Internal CA for the provider

If the provider's TLS cert is signed by a private CA (self-hosted GitLab, internal Keycloak, ADFS):

caCertPath: /etc/ssl/certs/internal-ca.pem
# or, inline:
caCertPEM: |
  -----BEGIN CERTIFICATE-----
  ...
  -----END CERTIFICATE-----

Both can be combined. An unparseable bundle fails the plugin at startup. See #125.

Client authentication via private key JWT

Use when your IdP enforces short-lived secrets or pushes secretless client auth — Microsoft Entra ID / Azure AD, Okta, Auth0, Keycloak. Instead of sending a static clientSecret, the plugin signs a short-lived JWT and submits it as client_assertion per RFC 7523.

Minimal config:

clientAuthMethod: private_key_jwt
clientAssertionKeyPath: /etc/traefik/oidc/client-key.pem
clientAssertionKeyID: my-key-2026
# clientAssertionAlg: RS256   # default; or PS256/384/512, ES256/384/512

Or inline:

clientAuthMethod: private_key_jwt
clientAssertionPrivateKey: |
  -----BEGIN PRIVATE KEY-----
  ...
  -----END PRIVATE KEY-----
clientAssertionKeyID: my-key-2026

Accepted PEM forms: PKCS#8 (PRIVATE KEY), PKCS#1 (RSA PRIVATE KEY), SEC1 (EC PRIVATE KEY). The assertion uses iss=sub=clientID, aud=tokenURL, 60s lifetime, random hex jti per request. Sent on /token (auth-code + refresh) and /revoke. The kid must match the public key registered with the IdP.

clientSecret becomes optional with private_key_jwt. Existing client_secret_post setups are unaffected. Keys are parsed once at startup — rotation requires a Traefik reload.

See issue #135.

Environment variable names containing API

Traefik reserves TRAEFIK_API_*. User vars whose name contains API (e.g. OIDC_ENCRYPTION_SECRET_API) make the plugin fail with invalid handler type: <nil>. Rename to anything without the literal API substring. See #98.

Templated headers

Forward identity to backends via Go templates over ID-token claims and tokens:

headers:
  - name: X-User-Email
    value: "{{.Claims.email}}"
  - name: Authorization
    value: "Bearer {{.AccessToken}}"
  - name: X-User-Roles
    value: "{{range $i, $e := .Claims.roles}}{{if $i}},{{end}}{{$e}}{{end}}"

Available bindings: .Claims.<field>, .AccessToken, .IdToken (or .IDToken), .RefreshToken. Names are case-sensitive (.Claims, not .claims).

Header templates are validated at startup (a failing template stops the middleware from loading). Only a fixed set of claim fields may be emitted — standard OIDC claims plus common provider claims (email, name, given_name, family_name, preferred_username, sub, groups, roles, realm_access, resource_access, oid, tid, upn, hd, picture, locale, email_verified, and a few more; see safeClaimsFields in template_validation.go). To emit a claim not on that list, add it to allowedClaims:

allowedClaims:
  - employee_id
headers:
  - name: X-Employee-Id
    value: "{{.Claims.employee_id}}"

Rendering the whole context ({{.}}, {{$}}), the whole claims map ({{.Claims}}), or any non-listed claim is rejected — this prevents a template from accidentally forwarding raw tokens or unlisted claims. range/with must target a specific listed claim (e.g. {{range .Claims.groups}}); get/default are the only functions allowed.

File-provider users: escape the braces. Traefik's file provider runs every dynamic configuration file through Go templating before the plugin sees it. Plain {{.AccessToken}} then fails with can't evaluate field AccessToken in type bool. Wrap the expression in a raw string so the file provider emits it literally: value: "{{`{{.Claims.email}}`}}". All other providers (Kubernetes CRD, Docker labels, Consul, ...) pass the value through untouched — use the plain form there. Quadruple braces ({{{{ }}}}) do not work anywhere: the file provider fails to parse them, and every other path hands them to the plugin verbatim, where template validation rejects them (issues #149, #151).

Default downstream headers

When a request is authenticated, the middleware sets:

Header Notes
X-Forwarded-User User's email (always).
X-User-Groups Comma-separated.
X-User-Roles Comma-separated.
X-Auth-Request-User User's email.
X-Auth-Request-Redirect Original request URI.
X-Auth-Request-Token Full ID token — the largest header; suppressed by minimalHeaders.

Plus security headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy) controlled by the securityHeaders section — see docs/CONFIGURATION.md.

Common errors

Symptom Cause
Token verification failed Wrong/unreachable providerURL, or clock skew.
Session encryption key too short sessionEncryptionKey is < 32 bytes.
No matching public key found JWKS endpoint down, or kid mismatch.
Access denied: Your email domain is not allowed User's domain not in allowedUserDomains.
Access denied: You do not have any of the allowed roles or groups Claims missing or not in allowedRolesAndGroups.
can't evaluate field AccessToken in type bool File provider templated your header value — escape it: "{{`{{.AccessToken}}`}}" (see "Templated headers").
tls: failed to verify certificate: x509: certificate signed by unknown authority Internal CA — set caCertPath / caCertPEM.
invalid handler type: <nil> Env var name contains API — rename it.
false positive replay detected Multi-replica without Redis — see Multi-replica deployments.
Google sessions expire after ~1h Consent screen still in "Testing" mode. Do not add offline_access — Google rejects it; the middleware sets access_type=offline automatically.

Provider-specific issues (Keycloak mappers, Azure AD group overage, Auth0 namespaced claims, Cognito regions, GitLab self-hosted) live in docs/PROVIDERS.md.

Set logLevel: debug to surface detail.

Telemetry

On first plugin instantiation this middleware sends a single anonymous adoption ping — project name, version, timestamp; no identifiers, no request data, no token contents. Fire-and-forget with a 2-second timeout; cannot block plugin load or panic.

Local source: telemetry.go. Disclosure mirrors oss-telemetry — Disabling telemetry.

Quick opt-out: set any of DO_NOT_TRACK=1, OSS_TELEMETRY_DISABLED=1, or TRAEFIKOIDC_DISABLE_TELEMETRY=1.

License

See LICENSE.

Documentation

Overview

Package traefikoidc — bearer-token (M2M) authentication path.

Disabled by default. When enabled via Config.EnableBearerAuth, requests presenting "Authorization: Bearer <jwt>" are validated against the configured OIDC provider (signature, issuer, audience, exp, replay-Get) and the request is forwarded downstream without creating a cookie session.

Design rules (kept here in code as the single source of truth):

  • Access tokens only. ID tokens are rejected via detectTokenType.
  • Audience is mandatory (enforced at startup in main.go).
  • alg + kid pinned BEFORE JWKS fetch to deny amplification probes.
  • iat upper-age cap bounds clock-skew / forever-token abuse.
  • Multi-audience tokens require matching azp.
  • Per-IP 401 throttle returns 429 + Retry-After after a threshold.
  • JTI Set is suppressed (skipReplayMarking) but JTI Get stays — revoked tokens (RevokeToken adds to blacklist) are still rejected.
  • Identifier is read from BearerIdentifierClaim (default "sub"), never from UserIdentifierClaim, to avoid the unverified-email spoofing path.
  • Identifier is sanitized: length cap, control chars, bidi-override, delimiter chars (, ; =) rejected.
  • On excluded URLs the Authorization header is stripped before forwarding.

See docs/superpowers/specs/2026-05-18-bearer-token-auth-design.md and docs/BEARER_AUTH.md for the full threat model.

Package traefikoidc provides OIDC authentication middleware for Traefik

Package traefikoidc provides OIDC authentication middleware for Traefik

Package traefikoidc provides OIDC authentication middleware for Traefik. This file implements OIDC Backchannel Logout (OpenID Connect Back-Channel Logout 1.0) and Front-Channel Logout (OpenID Connect Front-Channel Logout 1.0) functionality.

Package traefikoidc provides OIDC authentication middleware for Traefik. It supports multiple OIDC providers including Google, Azure AD, and generic OIDC providers with features like token refresh, session management, and provider-specific optimizations.

Package traefikoidc provides OIDC authentication middleware for Traefik. This file contains the core HTTP middleware functionality for request processing and authentication flow management.

Package traefikoidc — principal abstraction for the shared post-auth pipeline. A principal carries the resolved identity + tokens + claims produced by EITHER the cookie session path or the bearer-token path, so downstream header injection / roles checks / forwarding can be implemented once and reused.

Package traefikoidc provides OIDC authentication middleware for Traefik. requestState bundles read-mostly fields for a single ServeHTTP call.

Package traefikoidc provides OIDC authentication middleware for Traefik. This file implements OAuth 2.0 Token Introspection (RFC 7662) for opaque token validation.

Package traefikoidc provides OIDC authentication middleware for Traefik. This file contains token management functionality including verification, caching, refresh, and provider-specific validation logic.

Package traefikoidc provides OIDC authentication middleware for Traefik. This file contains requestState-aware variants of the token validation functions. They read session field values from the captured snapshot in *requestState instead of calling session.GetX(), eliminating ~21 RLock acquisitions on sd.sessionMutex per request through the validation path (validateStandardTokens reads 17, validateAzureTokens reads 10, validateTokenExpiry reads 4 — and many are the SAME field). Under Yaegi each RLock costs ~1-5ms of interpreter dispatch.

The non-RS variants are retained for paths that don't have a captured snapshot (tests that drive the validators directly, the Azure/Google path when reached without rs threading, etc).

Package traefikoidc provides OIDC authentication middleware for Traefik.

Package traefikoidc provides OIDC authentication middleware for Traefik. This file contains URL-related helper methods for building, validating, and processing URLs used in the OIDC authentication flow.

Package traefikoidc provides OIDC authentication middleware for Traefik. This file contains utility/helper methods extracted from main.go for better code organization.

Index

Constants

View Source
const (
	DefaultMemoryMonitorInterval = 60 * time.Second
	MinMemoryMonitorInterval     = 30 * time.Second
)

Default and minimum interval values. The minimum exists because runtime.ReadMemStats is stop-the-world and hammering it on a hot loop causes noticeable latency spikes, especially under yaegi.

View Source
const (
	// DefaultRateLimit defines the default rate limit for requests per second
	DefaultRateLimit = 100

	// MinRateLimit defines the minimum allowed rate limit to prevent DOS
	MinRateLimit = 10

	// DefaultLogLevel defines the default logging level
	DefaultLogLevel = "info"

	// MinSessionEncryptionKeyLength defines the minimum length for session encryption key
	MinSessionEncryptionKeyLength = 32
)
View Source
const (
	ConstSessionTimeout = 86400
)
View Source
const REDACTED = "[REDACTED]"

REDACTED is the placeholder value for sensitive information

Variables

View Source
var (
	AccessTokenConfig = TokenConfig{
		Type:              "access",
		MinLength:         5,
		MaxLength:         100 * 1024,
		MaxChunks:         25,
		MaxChunkSize:      maxCookieSize,
		AllowOpaqueTokens: true,
		RequireJWTFormat:  false,
	}

	RefreshTokenConfig = TokenConfig{
		Type:              "refresh",
		MinLength:         5,
		MaxLength:         50 * 1024,
		MaxChunks:         15,
		MaxChunkSize:      maxCookieSize,
		AllowOpaqueTokens: true,
		RequireJWTFormat:  false,
	}

	IDTokenConfig = TokenConfig{
		Type:              "id",
		MinLength:         5,
		MaxLength:         75 * 1024,
		MaxChunks:         20,
		MaxChunkSize:      maxCookieSize,
		AllowOpaqueTokens: false,
		RequireJWTFormat:  true,
	}
)

Predefined configurations for each token type

View Source
var ClockSkewTolerance = ClockSkewToleranceFuture

ClockSkewTolerance is an alias for ClockSkewToleranceFuture for backward compatibility.

View Source
var ClockSkewToleranceFuture = 2 * time.Minute

ClockSkewToleranceFuture defines the maximum allowable clock skew for future time validation. Tokens are considered valid for an additional 2 minutes past their expiration time.

View Source
var ClockSkewTolerancePast = 10 * time.Second

ClockSkewTolerancePast defines the maximum allowable clock skew for past time validation. Tokens are considered valid if issued up to 10 seconds in the future.

View Source
var ErrShutdownTimeout = &shutdownTimeoutError{}

ErrShutdownTimeout is returned when shutdown times out

Functions

func BuildLogoutURL

func BuildLogoutURL(endSessionURL, idToken, postLogoutRedirectURI string) (string, error)

BuildLogoutURL constructs a logout URL for the OIDC provider's end session endpoint. It includes the ID token hint and post-logout redirect URI according to OIDC specifications. Parameters:

  • endSessionURL: The provider's logout/end session endpoint
  • idToken: The ID token to include as a hint
  • postLogoutRedirectURI: Where to redirect after logout

Returns:

  • The complete logout URL with query parameters
  • An error if the provided endSessionURL is invalid

func CheckGoroutineLeaks

func CheckGoroutineLeaks(t *testing.T, initialCount int)

CheckGoroutineLeaks detects and reports goroutine leaks

func CleanupGlobalCacheManager

func CleanupGlobalCacheManager() error

CleanupGlobalCacheManager cleans up the global cache manager

func CleanupIdleConnections

func CleanupIdleConnections(client *http.Client, interval time.Duration, stopChan <-chan struct{})

CleanupIdleConnections periodically closes idle HTTP connections to prevent memory leaks. Runs in a background goroutine and can be stopped via the stop channel. This is crucial for long-running applications to prevent connection pool exhaustion.

func CompressTokenOptimized

func CompressTokenOptimized(token string) (string, error)

CompressTokenOptimized compresses a token using pooled resources

func CreateDefaultHTTPClient

func CreateDefaultHTTPClient() *http.Client

CreateDefaultHTTPClient creates a default HTTP client using the global factory

func CreateHTTPClientWithConfig

func CreateHTTPClientWithConfig(config HTTPClientConfig) *http.Client

CreateHTTPClientWithConfig creates an HTTP client with the given configuration using the global factory instance

func CreatePooledHTTPClient

func CreatePooledHTTPClient(config HTTPClientConfig) *http.Client

CreatePooledHTTPClient creates an HTTP client using the shared transport pool

func CreateTokenHTTPClient

func CreateTokenHTTPClient() *http.Client

CreateTokenHTTPClient creates a token HTTP client using the global factory

func DecompressTokenOptimized

func DecompressTokenOptimized(compressed string) (string, error)

DecompressTokenOptimized decompresses a token using pooled resources

func ForceGoroutineCleanup

func ForceGoroutineCleanup()

ForceGoroutineCleanup aggressively tries to clean up leaked goroutines

func GetTestDuration

func GetTestDuration(normal time.Duration) time.Duration

GetTestDuration returns an appropriate duration based on test mode

func New

func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error)

New creates a new TraefikOidc middleware instance. It initializes all components including caches, HTTP clients, session management, templates, and starts background processes for metadata discovery. Parameters:

  • ctx: The context for the middleware lifecycle.
  • next: The next HTTP handler in the middleware chain.
  • config: The OIDC configuration containing provider details, client credentials, etc.
  • name: The name of the middleware instance.

Returns:

  • The configured TraefikOidc handler ready to process requests.
  • An error if essential configuration is missing or invalid (e.g., short encryption key).

func ResetGlobalMemoryMonitor

func ResetGlobalMemoryMonitor()

ResetGlobalMemoryMonitor resets the global memory monitor for testing This should only be used in tests to prevent state pollution between tests

func ResetGlobalMemoryOptimizations

func ResetGlobalMemoryOptimizations()

ResetGlobalMemoryOptimizations resets the global memory optimizations for testing

func ResetGlobalSessionCounters

func ResetGlobalSessionCounters()

ResetGlobalSessionCounters resets global session tracking for testing

func ResetGlobalTaskRegistry

func ResetGlobalTaskRegistry()

ResetGlobalTaskRegistry resets the global task registry for testing This should only be used in tests to prevent task exhaustion

func ResetSingletonNoOpLogger

func ResetSingletonNoOpLogger()

ResetSingletonNoOpLogger resets the singleton instance (mainly for testing)

func ResetUniversalCacheManagerForTesting

func ResetUniversalCacheManagerForTesting()

ResetUniversalCacheManagerForTesting resets the singleton for testing purposes only This should only be called in test code to ensure proper cleanup between tests

func SetTestConfig

func SetTestConfig(config *TestConfig)

SetTestConfig sets the global test configuration (useful for testing)

func ShutdownAllTasks

func ShutdownAllTasks()

ShutdownAllTasks gracefully shuts down all background tasks CRITICAL FIX: Ensures proper termination of all goroutines in production

func TestCleanupHelper

func TestCleanupHelper(t *testing.T)

TestCleanupHelper provides automatic cleanup for tests with goroutine leak detection

Types

type BackgroundTask

type BackgroundTask struct {
	// contains filtered or unexported fields
}

BackgroundTask provides a robust framework for running periodic background tasks with proper lifecycle management, graceful shutdown, and logging capabilities. It supports both internal and external WaitGroup coordination for complex cleanup scenarios.

func NewBackgroundTask

func NewBackgroundTask(name string, interval time.Duration, taskFunc func(), logger *Logger, wg ...*sync.WaitGroup) *BackgroundTask

NewBackgroundTask creates a new background task with the specified configuration. The task will execute taskFunc immediately when started, then at the specified interval. Parameters:

  • name: Human-readable name for the task (used in logging)
  • interval: How often to execute the task function
  • taskFunc: The function to execute periodically
  • logger: Logger for task events (can be nil)
  • wg: Optional external WaitGroup for coordinated shutdown

Returns:

  • A configured BackgroundTask ready to be started

func (*BackgroundTask) Start

func (bt *BackgroundTask) Start()

Start begins executing the background task in a separate goroutine. The task function is executed immediately, then at the configured interval. The task runs immediately upon start and then at the specified interval. This method is safe to call multiple times - only the first call will start the task.

func (*BackgroundTask) Stop

func (bt *BackgroundTask) Stop()

Stop gracefully shuts down the background task and waits for completion. It signals the task to stop and waits for the goroutine to finish. This method is safe to call multiple times.

type BaseRecoveryMechanism

type BaseRecoveryMechanism struct {
	// contains filtered or unexported fields
}

BaseRecoveryMechanism provides common functionality and metrics tracking for all error recovery mechanisms. It handles request/failure/success counting, timing information, and logging capabilities for derived recovery mechanisms.

func NewBaseRecoveryMechanism

func NewBaseRecoveryMechanism(name string, logger *Logger) *BaseRecoveryMechanism

NewBaseRecoveryMechanism creates a new base recovery mechanism with the given name and logger. This serves as the foundation for specific recovery mechanism implementations. Parameters:

  • name: Identifier for this recovery mechanism instance
  • logger: Logger for debugging and monitoring (nil creates no-op logger)

Returns:

  • A configured BaseRecoveryMechanism instance

func (*BaseRecoveryMechanism) GetBaseMetrics

func (b *BaseRecoveryMechanism) GetBaseMetrics() map[string]interface{}

GetBaseMetrics returns comprehensive metrics about the recovery mechanism. Includes request counts, success/failure rates, timing information, and uptime statistics that are common to all recovery mechanisms.

func (*BaseRecoveryMechanism) LogDebug

func (b *BaseRecoveryMechanism) LogDebug(format string, args ...interface{})

LogDebug logs a debug message with the mechanism name as prefix. Used for detailed debugging information about recovery mechanism operations.

func (*BaseRecoveryMechanism) LogError

func (b *BaseRecoveryMechanism) LogError(format string, args ...interface{})

LogError logs an error message with the mechanism name as prefix. Used for reporting failures and error conditions in recovery mechanisms.

func (*BaseRecoveryMechanism) LogInfo

func (b *BaseRecoveryMechanism) LogInfo(format string, args ...interface{})

LogInfo logs an informational message with the mechanism name as prefix. Provides consistent logging format across all recovery mechanisms.

func (*BaseRecoveryMechanism) RecordFailure

func (b *BaseRecoveryMechanism) RecordFailure()

RecordFailure increments the failure counter and updates the last failure timestamp. This method is thread-safe using atomic operations for counters and mutex protection for timestamp updates.

func (*BaseRecoveryMechanism) RecordRequest

func (b *BaseRecoveryMechanism) RecordRequest()

RecordRequest increments the total request counter. This method is thread-safe using atomic operations.

func (*BaseRecoveryMechanism) RecordSuccess

func (b *BaseRecoveryMechanism) RecordSuccess()

RecordSuccess increments the success counter and updates the last success timestamp. This method is thread-safe using atomic operations for counters and mutex protection for timestamp updates.

type BoundedCache

type BoundedCache = CacheInterfaceWrapper

BoundedCache is an alias for compatibility

type BoundedCacheAdapter

type BoundedCacheAdapter = CacheInterfaceWrapper

BoundedCacheAdapter is an alias for compatibility

type BufferPool

type BufferPool struct {
	// contains filtered or unexported fields
}

BufferPool manages a pool of byte buffers

func NewBufferPool

func NewBufferPool(maxSize int) *BufferPool

NewBufferPool creates a new buffer pool

func (*BufferPool) Get

func (p *BufferPool) Get() *bytes.Buffer

Get retrieves a buffer from the pool

func (*BufferPool) Put

func (p *BufferPool) Put(buf *bytes.Buffer)

Put returns a buffer to the pool

type Cache

type Cache = CacheInterfaceWrapper

Cache is an alias for backward compatibility

type CacheAdapter

type CacheAdapter = CacheInterfaceWrapper

CacheAdapter wraps UniversalCache for backward compatibility

type CacheEntry

type CacheEntry struct {
	ExpiresAt time.Time
	Value     interface{}
	Key       string
}

CacheEntry for backward compatibility

type CacheInterface

type CacheInterface interface {
	Set(key string, value any, ttl time.Duration)
	Get(key string) (any, bool)
	Delete(key string)
	SetMaxSize(size int)
	Size() int
	Clear()
	Cleanup()
	Close()
	GetStats() map[string]any // For testing and monitoring
}

CacheInterface defines the common cache operations

func NewBoundedCache

func NewBoundedCache(maxSize int) CacheInterface

NewBoundedCache creates a bounded cache with specified max size

func NewCache

func NewCache() CacheInterface

NewCache creates a general purpose cache

func NewLazyCache

func NewLazyCache() CacheInterface

NewLazyCache creates a cache with delayed cleanup initialization. Uses the default no-op logger and defers cleanup task creation.

func NewLazyCacheWithLogger

func NewLazyCacheWithLogger(logger *Logger) CacheInterface

NewLazyCacheWithLogger creates a cache that doesn't start cleanup until first use. This reduces memory overhead by avoiding unnecessary cleanup goroutines for caches that may remain empty or be used infrequently.

type CacheInterfaceWrapper

type CacheInterfaceWrapper struct {
	// contains filtered or unexported fields
}

CacheInterfaceWrapper wraps UniversalCache to implement CacheInterface

func NewCacheAdapter

func NewCacheAdapter(cache interface{}) *CacheInterfaceWrapper

NewCacheAdapter creates a cache adapter

func NewOptimizedCache

func NewOptimizedCache() *CacheInterfaceWrapper

NewOptimizedCache creates an optimized cache

func NewOptimizedCacheWithConfig

func NewOptimizedCacheWithConfig(config OptimizedCacheConfig) *CacheInterfaceWrapper

NewOptimizedCacheWithConfig creates cache with config

func (*CacheInterfaceWrapper) Cleanup

func (c *CacheInterfaceWrapper) Cleanup()

Cleanup triggers immediate cleanup of expired items

func (*CacheInterfaceWrapper) Clear

func (c *CacheInterfaceWrapper) Clear()

Clear removes all items

func (*CacheInterfaceWrapper) Close

func (c *CacheInterfaceWrapper) Close()

Close shuts down the cache if it's not managed globally. For managed caches (from UniversalCacheManager), this is a no-op to prevent log flooding when multiple plugin instances are closed during Traefik configuration reloads.

func (*CacheInterfaceWrapper) Delete

func (c *CacheInterfaceWrapper) Delete(key string)

Delete removes a key

func (*CacheInterfaceWrapper) Get

func (c *CacheInterfaceWrapper) Get(key string) (interface{}, bool)

Get retrieves a value

func (*CacheInterfaceWrapper) GetStats

func (c *CacheInterfaceWrapper) GetStats() map[string]interface{}

GetStats returns cache statistics

func (*CacheInterfaceWrapper) Set

func (c *CacheInterfaceWrapper) Set(key string, value interface{}, ttl time.Duration)

Set stores a value

func (*CacheInterfaceWrapper) SetMaxMemory

func (c *CacheInterfaceWrapper) SetMaxMemory(bytes int64)

SetMaxMemory sets the maximum memory limit

func (*CacheInterfaceWrapper) SetMaxSize

func (c *CacheInterfaceWrapper) SetMaxSize(size int)

SetMaxSize updates the max size

func (*CacheInterfaceWrapper) Size

func (c *CacheInterfaceWrapper) Size() int

Size returns the number of items

type CacheItem

type CacheItem struct {
	ExpiresAt    time.Time
	LastAccessed time.Time
	Value        interface{}
	Metadata     map[string]interface{}

	Key         string
	CacheType   CacheType
	Size        int64
	AccessCount int64
	// contains filtered or unexported fields
}

CacheItem represents a single cache entry

type CacheManager

type CacheManager struct {
	// contains filtered or unexported fields
}

CacheManager manages all caching components using the universal cache

func GetGlobalCacheManager deprecated

func GetGlobalCacheManager(wg *sync.WaitGroup) *CacheManager

GetGlobalCacheManager returns a singleton CacheManager instance.

Deprecated: Use GetGlobalCacheManagerWithConfig instead.

func GetGlobalCacheManagerWithConfig

func GetGlobalCacheManagerWithConfig(wg *sync.WaitGroup, config *Config) *CacheManager

GetGlobalCacheManagerWithConfig returns a singleton CacheManager instance with optional Redis configuration

func (*CacheManager) Close

func (cm *CacheManager) Close() error

Close gracefully shuts down all cache components

func (*CacheManager) GetSharedIntrospectionCache

func (cm *CacheManager) GetSharedIntrospectionCache() CacheInterface

GetSharedIntrospectionCache returns the shared token introspection cache for caching OAuth 2.0 Token Introspection (RFC 7662) results

func (*CacheManager) GetSharedJWKCache

func (cm *CacheManager) GetSharedJWKCache() JWKCacheInterface

GetSharedJWKCache returns the shared JWK cache

func (*CacheManager) GetSharedMetadataCache

func (cm *CacheManager) GetSharedMetadataCache() *MetadataCache

GetSharedMetadataCache returns the shared metadata cache

func (*CacheManager) GetSharedRefreshResultCache

func (cm *CacheManager) GetSharedRefreshResultCache() CacheInterface

GetSharedRefreshResultCache returns the short-lived refresh-result cache used by the refresh path to coalesce grants across Traefik replicas via Redis.

func (*CacheManager) GetSharedSessionInvalidationCache

func (cm *CacheManager) GetSharedSessionInvalidationCache() CacheInterface

GetSharedSessionInvalidationCache returns the shared session invalidation cache for backchannel and front-channel logout (IdP-initiated logout)

func (*CacheManager) GetSharedTokenBlacklist

func (cm *CacheManager) GetSharedTokenBlacklist() CacheInterface

GetSharedTokenBlacklist returns the shared token blacklist cache

func (*CacheManager) GetSharedTokenCache

func (cm *CacheManager) GetSharedTokenCache() *TokenCache

GetSharedTokenCache returns the shared token cache

func (*CacheManager) GetSharedTokenTypeCache

func (cm *CacheManager) GetSharedTokenTypeCache() CacheInterface

GetSharedTokenTypeCache returns the shared token type cache for caching token type detection results to improve performance

type CacheMemoryProfiler

type CacheMemoryProfiler struct {
	// contains filtered or unexported fields
}

CacheMemoryProfiler monitors cache memory usage

func NewCacheMemoryProfiler

func NewCacheMemoryProfiler(cache CacheInterface, logger *Logger) *CacheMemoryProfiler

NewCacheMemoryProfiler creates a new cache memory profiler

func (*CacheMemoryProfiler) AnalyzeLeaks

func (cmp *CacheMemoryProfiler) AnalyzeLeaks(baseline, current *MemorySnapshot) *LeakAnalysis

AnalyzeLeaks analyzes cache for memory leaks

func (*CacheMemoryProfiler) GetCurrentStats

func (cmp *CacheMemoryProfiler) GetCurrentStats() *runtime.MemStats

GetCurrentStats returns current memory statistics

func (*CacheMemoryProfiler) StartProfiling

func (cmp *CacheMemoryProfiler) StartProfiling(config ProfilingConfig) error

StartProfiling begins profiling (no-op for cache)

func (*CacheMemoryProfiler) StopProfiling

func (cmp *CacheMemoryProfiler) StopProfiling() (*MemorySnapshot, error)

StopProfiling ends profiling

func (*CacheMemoryProfiler) TakeSnapshot

func (cmp *CacheMemoryProfiler) TakeSnapshot() (*MemorySnapshot, error)

TakeSnapshot captures cache memory statistics

type CacheStrategy

type CacheStrategy interface {
	Name() string
	ShouldEvict(item interface{}, now time.Time) bool
	OnAccess(key string, item interface{})
	OnRemove(key string)
	EstimateSize(item interface{}) int64
	GetEvictionCandidate() (key string, found bool)
}

CacheStrategy interface for backward compatibility

func NewLRUStrategy

func NewLRUStrategy(maxSize int) CacheStrategy

type CacheType

type CacheType string

CacheType defines the type of cache for optimized behavior

const (
	CacheTypeToken    CacheType = "token"
	CacheTypeMetadata CacheType = "metadata"
	CacheTypeJWK      CacheType = "jwk"
	CacheTypeSession  CacheType = "session"
	CacheTypeGeneral  CacheType = "general"
)

type ChunkManager

type ChunkManager struct {
	// contains filtered or unexported fields
}

ChunkManager handles the complex logic of storing and retrieving large tokens across multiple HTTP cookies. It provides comprehensive validation, security checks, and error handling to ensure data integrity and prevent security vulnerabilities throughout the process.

func NewChunkManager

func NewChunkManager(logger *Logger) *ChunkManager

NewChunkManager creates a new ChunkManager instance with proper initialization. It sets up logging and synchronization primitives for safe concurrent access. Parameters:

  • logger: Logger instance for debugging and error reporting (nil creates no-op logger).

Returns:

  • A new ChunkManager instance ready for use.

func (*ChunkManager) CanCreateSession

func (cm *ChunkManager) CanCreateSession() (bool, error)

CanCreateSession checks if a new session can be created within limits

func (*ChunkManager) CleanupExpiredSessions

func (cm *ChunkManager) CleanupExpiredSessions(force ...bool)

CleanupExpiredSessions removes expired sessions to prevent memory leaks. This is called periodically to maintain memory efficiency and prevent unbounded growth. It can be called with force=true to bypass time restrictions for testing.

func (*ChunkManager) EmergencyCleanup

func (cm *ChunkManager) EmergencyCleanup()

EmergencyCleanup performs aggressive session cleanup when approaching limits

func (*ChunkManager) GetMemoryStats

func (cm *ChunkManager) GetMemoryStats() map[string]interface{}

GetMemoryStats returns memory usage statistics for monitoring

func (*ChunkManager) GetSessionCount

func (cm *ChunkManager) GetSessionCount() int

GetSessionCount returns the current number of active sessions (for monitoring)

func (*ChunkManager) GetToken

func (cm *ChunkManager) GetToken(
	singleToken string,
	compressed bool,
	chunks map[int]*sessions.Session,
	config TokenConfig,
) TokenRetrievalResult

GetToken retrieves and validates a token from either single-cookie or chunked storage. It handles decompression, validates format and content, and performs comprehensive security checks before returning the token. Parameters:

  • singleToken: Token stored in a single cookie (empty if using chunks).
  • compressed: Whether the token data is gzip-compressed.
  • chunks: Map of chunk sessions for tokens split across multiple cookies.
  • config: Token configuration specifying validation rules and limits.

Returns:

  • TokenRetrievalResult containing the token or an error.

func (*ChunkManager) Shutdown

func (cm *ChunkManager) Shutdown()

Shutdown gracefully shuts down the ChunkManager

type CircuitBreaker

type CircuitBreaker struct {
	// BaseRecoveryMechanism provides common functionality
	*BaseRecoveryMechanism
	// contains filtered or unexported fields
}

CircuitBreaker implements the circuit breaker pattern for external service calls. It monitors failure rates and automatically opens the circuit when failures exceed the threshold, preventing further requests until the service recovers.

func NewCircuitBreaker

func NewCircuitBreaker(config CircuitBreakerConfig, logger *Logger) *CircuitBreaker

NewCircuitBreaker creates a new circuit breaker with the specified configuration. The circuit breaker starts in the closed state, allowing all requests through.

func (*CircuitBreaker) Execute

func (cb *CircuitBreaker) Execute(fn func() error) error

Execute executes a function through the circuit breaker without context. This is provided for backward compatibility with existing code.

func (*CircuitBreaker) ExecuteWithContext

func (cb *CircuitBreaker) ExecuteWithContext(ctx context.Context, fn func() error) error

ExecuteWithContext executes a function through the circuit breaker with context. It checks if requests are allowed, executes the function, and updates the circuit state based on the result. Implements the ErrorRecoveryMechanism interface.

func (*CircuitBreaker) GetMetrics

func (cb *CircuitBreaker) GetMetrics() map[string]interface{}

GetMetrics returns comprehensive metrics about the circuit breaker. Includes state information, failure counts, configuration, and base metrics.

func (*CircuitBreaker) GetState

func (cb *CircuitBreaker) GetState() CircuitBreakerState

GetState returns the current state of the circuit breaker. Thread-safe method for monitoring circuit breaker status.

func (*CircuitBreaker) IsAvailable

func (cb *CircuitBreaker) IsAvailable() bool

IsAvailable returns whether the circuit breaker is currently allowing requests. This provides a quick way to check if the service is available.

func (*CircuitBreaker) Reset

func (cb *CircuitBreaker) Reset()

Reset resets the circuit breaker to its initial closed state. Clears failure count and state, effectively recovering from any open state.

type CircuitBreakerConfig

type CircuitBreakerConfig struct {
	// MaxFailures is the number of failures before opening the circuit
	MaxFailures int `json:"max_failures"`
	// Timeout is how long to wait before trying to recover (open -> half-open)
	Timeout time.Duration `json:"timeout"`
	// ResetTimeout is how long to wait before fully closing the circuit
	ResetTimeout time.Duration `json:"reset_timeout"`
}

CircuitBreakerConfig holds configuration parameters for circuit breakers. These settings control when the circuit opens and how it recovers.

func DefaultCircuitBreakerConfig

func DefaultCircuitBreakerConfig() CircuitBreakerConfig

DefaultCircuitBreakerConfig returns sensible default configuration for circuit breakers. Configured for typical web service scenarios with moderate tolerance for failures.

type CircuitBreakerState

type CircuitBreakerState int

CircuitBreakerState represents the current state of a circuit breaker. The circuit breaker pattern prevents cascading failures by monitoring error rates and temporarily blocking requests to failing services.

const (
	// CircuitBreakerClosed allows all requests through (normal operation)
	CircuitBreakerClosed CircuitBreakerState = iota
	// CircuitBreakerOpen blocks all requests (service is failing)
	CircuitBreakerOpen
	// CircuitBreakerHalfOpen allows limited requests to test service recovery
	CircuitBreakerHalfOpen
)

Circuit breaker states following the standard pattern: Closed: Normal operation, requests flow through Open: Circuit is tripped, requests are blocked HalfOpen: Testing state, limited requests allowed to test recovery

type ClientAssertionSigner

type ClientAssertionSigner struct {
	// contains filtered or unexported fields
}

ClientAssertionSigner builds and signs client_assertion JWTs (RFC 7523 §2.2).

func NewClientAssertionSigner

func NewClientAssertionSigner(pemBytes []byte, alg, kid string) (*ClientAssertionSigner, error)

NewClientAssertionSigner parses pemBytes as a private key, validates that alg is consistent with the key type, and returns a ready-to-use signer. kid is placed verbatim in the JWS header.

PEM block types understood:

  • "PRIVATE KEY" → PKCS#8 (tried first for all types)
  • "RSA PRIVATE KEY" → PKCS#1
  • "EC PRIVATE KEY" → SEC1

func (*ClientAssertionSigner) Sign

func (s *ClientAssertionSigner) Sign(audience, clientID string) (string, error)

Sign constructs and returns a signed client_assertion JWT. audience is typically the token endpoint URL (RFC 7523 §3). clientID is used as both iss and sub per RFC 7523 §2.2.

type ClientRegistrationError

type ClientRegistrationError struct {
	Error            string `json:"error"`
	ErrorDescription string `json:"error_description,omitempty"`
}

ClientRegistrationError represents an error response from client registration (RFC 7591)

type ClientRegistrationMetadata

type ClientRegistrationMetadata struct {
	TokenEndpointAuthMethod string   `json:"token_endpoint_auth_method,omitempty"`
	TOSURI                  string   `json:"tos_uri,omitempty"`
	Scope                   string   `json:"scope,omitempty"`
	ApplicationType         string   `json:"application_type,omitempty"`
	SubjectType             string   `json:"subject_type,omitempty"`
	ClientName              string   `json:"client_name,omitempty"`
	LogoURI                 string   `json:"logo_uri,omitempty"`
	ClientURI               string   `json:"client_uri,omitempty"`
	PolicyURI               string   `json:"policy_uri,omitempty"`
	JWKSURI                 string   `json:"jwks_uri,omitempty"`
	ResponseTypes           []string `json:"response_types,omitempty"`
	Contacts                []string `json:"contacts,omitempty"`
	RedirectURIs            []string `json:"redirect_uris"`
	DefaultACRValues        []string `json:"default_acr_values,omitempty"`
	GrantTypes              []string `json:"grant_types,omitempty"`
	DefaultMaxAge           int      `json:"default_max_age,omitempty"`
	RequireAuthTime         bool     `json:"require_auth_time,omitempty"`
}

ClientRegistrationMetadata contains client metadata for dynamic registration (RFC 7591)

type ClientRegistrationResponse

type ClientRegistrationResponse struct {
	SubjectType             string   `json:"subject_type,omitempty"`
	LogoURI                 string   `json:"logo_uri,omitempty"`
	RegistrationAccessToken string   `json:"registration_access_token,omitempty"`
	RegistrationClientURI   string   `json:"registration_client_uri,omitempty"`
	Scope                   string   `json:"scope,omitempty"`
	TokenEndpointAuthMethod string   `json:"token_endpoint_auth_method,omitempty"`
	TOSURI                  string   `json:"tos_uri,omitempty"`
	PolicyURI               string   `json:"policy_uri,omitempty"`
	ClientSecret            string   `json:"client_secret,omitempty"`
	ApplicationType         string   `json:"application_type,omitempty"`
	ClientID                string   `json:"client_id"`
	ClientName              string   `json:"client_name,omitempty"`
	JWKSURI                 string   `json:"jwks_uri,omitempty"`
	ClientURI               string   `json:"client_uri,omitempty"`
	Contacts                []string `json:"contacts,omitempty"`
	GrantTypes              []string `json:"grant_types,omitempty"`
	ResponseTypes           []string `json:"response_types,omitempty"`
	RedirectURIs            []string `json:"redirect_uris,omitempty"`
	ClientSecretExpiresAt   int64    `json:"client_secret_expires_at,omitempty"`
	ClientIDIssuedAt        int64    `json:"client_id_issued_at,omitempty"`
}

ClientRegistrationResponse represents the response from a successful client registration (RFC 7591)

type Config

type Config struct {
	DynamicClientRegistration *DynamicClientRegistrationConfig `json:"dynamicClientRegistration,omitempty"`
	Redis                     *RedisConfig                     `json:"redis,omitempty"`
	HTTPClient                *http.Client                     `json:"-"`
	SecurityHeaders           *SecurityHeadersConfig           `json:"securityHeaders,omitempty"`
	PostLogoutRedirectURI     string                           `json:"postLogoutRedirectURI"`
	LogLevel                  string                           `json:"logLevel"`
	LogoutURL                 string                           `json:"logoutURL"`
	ClientID                  string                           `json:"clientID"`
	ClientSecret              string                           `json:"clientSecret"`
	Audience                  string                           `json:"audience,omitempty"`
	CookiePrefix              string                           `json:"cookiePrefix"`
	CallbackURL               string                           `json:"callbackURL"`
	SessionEncryptionKey      string                           `json:"sessionEncryptionKey"`
	ProviderURL               string                           `json:"providerURL"`
	RevocationURL             string                           `json:"revocationURL"`
	UserIdentifierClaim       string                           `json:"userIdentifierClaim,omitempty"`
	GroupClaimName            string                           `json:"groupClaimName,omitempty"`
	RoleClaimName             string                           `json:"roleClaimName,omitempty"`
	CookieDomain              string                           `json:"cookieDomain"`
	OIDCEndSessionURL         string                           `json:"oidcEndSessionURL"`
	// IntrospectionURL overrides the RFC 7662 token introspection endpoint.
	// Set it when the IdP omits introspection_endpoint from discovery. It
	// takes precedence over the discovered value.
	IntrospectionURL      string            `json:"introspectionURL"`
	Scopes                []string          `json:"scopes"`
	AllowedRolesAndGroups []string          `json:"allowedRolesAndGroups"`
	ExcludedURLs          []string          `json:"excludedURLs"`
	BypassSourceRanges    []string          `json:"bypassSourceRanges,omitempty"`
	AllowedUserDomains    []string          `json:"allowedUserDomains"`
	AllowedUsers          []string          `json:"allowedUsers"`
	Headers               []TemplatedHeader `json:"headers"`
	// AllowedClaims extends the built-in claims whitelist that header value
	// templates may emit. Add the exact claim name (e.g. "employee_id") to allow
	// {{.Claims.employee_id}} / {{get .Claims "employee_id"}}. Applies to both
	// template validation and the runtime get helper. Built-in claims (email,
	// groups, roles, realm_access, ...) need not be listed.
	AllowedClaims             []string          `json:"allowedClaims,omitempty"`
	ExtraAuthParams           map[string]string `json:"extraAuthParams,omitempty"`
	RefreshGracePeriodSeconds int               `json:"refreshGracePeriodSeconds"`
	// MaxRefreshTokenAgeSeconds is a heuristic upper bound on the lifetime of
	// a stored refresh token. Once the token has been in the session longer
	// than this, requests treat it as expired up-front - returning 401 to
	// AJAX callers and triggering full re-auth on navigations - instead of
	// hammering the IdP with grants that will only fail with invalid_grant.
	// IdPs do not expose RT TTL on the wire, so this is intentionally a
	// conservative heuristic; tune to match your provider configuration.
	// Default 21600 (6h). Set to 0 to disable the check.
	MaxRefreshTokenAgeSeconds int  `json:"maxRefreshTokenAgeSeconds"`
	SessionMaxAge             int  `json:"sessionMaxAge"`
	RateLimit                 int  `json:"rateLimit"`
	OverrideScopes            bool `json:"overrideScopes"`
	DisableReplayDetection    bool `json:"disableReplayDetection,omitempty"`
	RequireTokenIntrospection bool `json:"requireTokenIntrospection,omitempty"`
	AllowOpaqueTokens         bool `json:"allowOpaqueTokens,omitempty"`
	StrictAudienceValidation  bool `json:"strictAudienceValidation,omitempty"`
	EnablePKCE                bool `json:"enablePKCE"`
	ForceHTTPS                bool `json:"forceHTTPS"`
	AllowPrivateIPAddresses   bool `json:"allowPrivateIPAddresses,omitempty"`
	MinimalHeaders            bool `json:"minimalHeaders,omitempty"`
	StripAuthCookies          bool `json:"stripAuthCookies,omitempty"`
	// CookiePath restricts session cookies to a specific path prefix instead of "/".
	// When traefikoidc protects some but not all paths on a domain, set this to the
	// middleware's path prefix (e.g. "/app-protegido") so the browser does not send
	// the OIDC session cookies to unprotected paths — preventing "Request Header
	// Or Cookie Too Large" (431) errors on those paths.
	// Default "/" (all paths, current behaviour).
	CookiePath               string `json:"cookiePath,omitempty"`
	EnableBackchannelLogout  bool   `json:"enableBackchannelLogout,omitempty"`
	EnableFrontchannelLogout bool   `json:"enableFrontchannelLogout,omitempty"`
	BackchannelLogoutURL     string `json:"backchannelLogoutURL,omitempty"`
	FrontchannelLogoutURL    string `json:"frontchannelLogoutURL,omitempty"`
	// CACertPath is an optional filesystem path to a PEM-encoded CA bundle used
	// to verify the OIDC provider's TLS certificate. Use this when the provider
	// is signed by an internal/private CA that is not in the system trust store.
	CACertPath string `json:"caCertPath,omitempty"`
	// CACertPEM is an optional inline PEM-encoded CA bundle, equivalent to
	// CACertPath but supplied directly in the middleware configuration. Both
	// may be set; certificates from both sources are combined.
	CACertPEM string `json:"caCertPEM,omitempty"`
	// InsecureSkipVerify disables TLS certificate verification for the OIDC
	// provider. Intended ONLY for local development against self-signed
	// providers. Enabling this in production is a security hole — prefer
	// CACertPath/CACertPEM. Emits a loud warning at startup.
	InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`

	// ClientAuthMethod selects the OAuth 2.0 client authentication method used
	// at the token / revocation / introspection endpoints. Supported values:
	//
	//   - "client_secret_post" (default, current behavior): clientSecret is
	//     sent in the request body alongside client_id.
	//   - "private_key_jwt" (RFC 7523 §2.2): the plugin signs a short-lived JWT
	//     assertion with a configured private key and sends it as
	//     client_assertion. Use this when your IdP enforces short-lived secrets
	//     or mandates secretless client auth (Entra ID, Okta, Auth0, Keycloak).
	//
	// When set to "private_key_jwt", clientSecret may be left empty and one of
	// clientAssertionPrivateKey / clientAssertionKeyPath must be configured.
	ClientAuthMethod string `json:"clientAuthMethod,omitempty"`

	// ClientAssertionPrivateKey is an inline PEM-encoded private key used to
	// sign client_assertion JWTs. Mutually exclusive with
	// ClientAssertionKeyPath. Supports PKCS#8, PKCS#1 (RSA), and SEC1 (EC).
	ClientAssertionPrivateKey string `json:"clientAssertionPrivateKey,omitempty"`

	// ClientAssertionKeyPath is a filesystem path to a PEM-encoded private key,
	// equivalent to ClientAssertionPrivateKey but loaded from disk.
	ClientAssertionKeyPath string `json:"clientAssertionKeyPath,omitempty"`

	// ClientAssertionKeyID is the JWK key id (kid) advertised in the JWS
	// header. Required when using private_key_jwt so the IdP can locate the
	// matching public key registered for the client.
	ClientAssertionKeyID string `json:"clientAssertionKeyID,omitempty"`

	// ClientAssertionAlg is the JWS signing algorithm. Defaults to RS256.
	// Supported: RS256/384/512, PS256/384/512, ES256/384/512.
	ClientAssertionAlg string `json:"clientAssertionAlg,omitempty"`

	// EnableBearerAuth turns on the Authorization: Bearer <jwt> auth path.
	// Default false. When true, Audience MUST be set or startup fails. The
	// bearer path is M2M-only: it accepts validated access-token JWTs, rejects
	// ID tokens, and forwards principal headers downstream without creating a
	// cookie session. See docs/BEARER_AUTH.md for the threat model.
	EnableBearerAuth bool `json:"enableBearerAuth,omitempty"`
	// BearerIdentifierClaim names the JWT claim used as the principal identifier
	// on the bearer-token auth path. Default "sub". Decoupled from
	// UserIdentifierClaim (which defaults to "email" and drives the cookie path)
	// so M2M bearer flow never accidentally relies on an unverified email.
	BearerIdentifierClaim string `json:"bearerIdentifierClaim,omitempty"`
	// StripAuthorizationHeader removes the Authorization header from the
	// forwarded request after successful bearer auth, so downstream services
	// never see the raw token. Default true. Disable only when a downstream
	// explicitly needs to re-validate the bearer.
	StripAuthorizationHeader bool `json:"stripAuthorizationHeader,omitempty"`
	// BearerEmitWWWAuthenticate controls whether 401 responses on the bearer
	// path include a WWW-Authenticate: Bearer error="invalid_token" hint per
	// RFC 6750 §3. Default true. Disable to reduce reconnaissance signal.
	BearerEmitWWWAuthenticate bool `json:"bearerEmitWWWAuthenticate,omitempty"`
	// BearerOverridesCookie controls precedence when both Authorization:
	// Bearer and a session cookie are present. Default false: cookie wins
	// (safer against browser/extension/proxy bearer injection). Set true for
	// the bearer-wins convention used by AWS/GCP/Kubernetes API gateways.
	BearerOverridesCookie bool `json:"bearerOverridesCookie,omitempty"`
	// MaxTokenAgeSeconds caps how old (iat-based) a bearer token may be.
	// Default 86400 (24h). Bounds clock-manipulation tokens with implausibly
	// distant iat values.
	MaxTokenAgeSeconds int64 `json:"maxTokenAgeSeconds,omitempty"`
	// MaxIdentifierLength bounds the post-sanitisation length of the bearer
	// principal identifier (the value injected as X-Forwarded-User). Default
	// 256.
	MaxIdentifierLength int `json:"maxIdentifierLength,omitempty"`
	// BearerFailureThreshold is the number of consecutive 401s from one
	// source IP within BearerFailureWindowSeconds that trips the throttle.
	// Default 20.
	BearerFailureThreshold int `json:"bearerFailureThreshold,omitempty"`
	// BearerFailureWindowSeconds is the rolling window (seconds) over which
	// 401s are counted for throttling. Default 60.
	BearerFailureWindowSeconds int `json:"bearerFailureWindowSeconds,omitempty"`
	// BearerFailurePenaltySeconds is how long an IP is parked in the 429
	// penalty box after BearerFailureThreshold is exceeded. Default 60.
	BearerFailurePenaltySeconds int `json:"bearerFailurePenaltySeconds,omitempty"`
}

Config holds the configuration for the OIDC middleware. It provides all necessary settings to configure OpenID Connect authentication with various providers like Auth0, Logto, or any standard OIDC provider.

func CreateConfig

func CreateConfig() *Config

CreateConfig creates a new Config with secure default values. Default values are set for optional fields:

  • Scopes: ["openid", "profile", "email"]
  • LogLevel: "info"
  • LogoutURL: CallbackURL + "/logout"
  • RateLimit: 100 requests per second
  • PostLogoutRedirectURI: "/"
  • ForceHTTPS: true (for security)
  • EnablePKCE: false (PKCE is opt-in)
  • Redis: nil (disabled by default, can be configured via Traefik config or env vars)

CreateConfig initializes a new Config struct with default values for optional fields. It sets default scopes, log level, rate limit, enables ForceHTTPS, and sets the default refresh grace period. Required fields like ProviderURL, ClientID, ClientSecret, CallbackURL, and SessionEncryptionKey must be set explicitly after creation. Redis configuration can be provided through Traefik's dynamic configuration or as a fallback through environment variables.

Returns:

  • A pointer to a new Config struct with default settings applied.

func (*Config) GetSecurityHeadersApplier

func (c *Config) GetSecurityHeadersApplier() func(http.ResponseWriter, *http.Request)

handleError logs an error message using the provided logger and sends an HTTP error response to the client with the specified message and status code.

Parameters:

  • w: The http.ResponseWriter to send the error response to.
  • message: The error message string.
  • code: The HTTP status code for the response.
  • logger: The Logger instance to use for logging the error.

GetSecurityHeadersApplier returns a function that applies security headers

func (Config) MarshalJSON

func (c Config) MarshalJSON() ([]byte, error)

MarshalJSON implements custom JSON marshaling to redact sensitive fields Rewritten without type aliases for yaegi compatibility

func (Config) MarshalYAML

func (c Config) MarshalYAML() (interface{}, error)

MarshalYAML implements custom YAML marshaling to redact sensitive fields Rewritten without type aliases for yaegi compatibility

func (*Config) Validate

func (c *Config) Validate() error

Validate checks the configuration settings for validity. It ensures that required fields (ProviderURL, CallbackURL, ClientID, ClientSecret, SessionEncryptionKey) are present and that URLs are well-formed (HTTPS where required). It also validates the session key length, log level, rate limit, and refresh grace period.

Returns:

  • nil if the configuration is valid.
  • An error describing the first validation failure encountered.

type DCRCredentialsStore

type DCRCredentialsStore interface {
	// Save stores the client registration response for a provider
	// The providerURL is used as a key to support multi-tenant scenarios
	Save(ctx context.Context, providerURL string, creds *ClientRegistrationResponse) error

	// Load retrieves stored credentials for a provider
	// Returns nil, nil if no credentials exist (not an error)
	Load(ctx context.Context, providerURL string) (*ClientRegistrationResponse, error)

	// Delete removes stored credentials for a provider
	Delete(ctx context.Context, providerURL string) error

	// Exists checks if credentials exist for a provider
	Exists(ctx context.Context, providerURL string) (bool, error)
}

DCRCredentialsStore defines the interface for storing DCR credentials. This abstraction allows different storage backends (file, Redis) to be used for persisting OIDC Dynamic Client Registration credentials across nodes.

func NewDCRCredentialsStore

func NewDCRCredentialsStore(
	config *DynamicClientRegistrationConfig,
	cacheManager *CacheManager,
	logger *Logger,
) (DCRCredentialsStore, error)

NewDCRCredentialsStore creates a DCRCredentialsStore based on configuration. This factory function handles backend selection logic:

  • "file": Use file-based storage (default for backward compatibility)
  • "redis": Use Redis exclusively (fails if Redis unavailable)
  • "auto": Use Redis if available, fallback to file

type DCRStorageBackend

type DCRStorageBackend = dcrstorage.StorageBackend

DCRStorageBackend represents the type of storage backend for DCR credentials. Alias for internal package type for backward compatibility.

const (
	// DCRStorageBackendFile uses file-based storage (default for backward compatibility)
	DCRStorageBackendFile DCRStorageBackend = dcrstorage.StorageBackendFile

	// DCRStorageBackendRedis uses Redis for distributed storage
	DCRStorageBackendRedis DCRStorageBackend = dcrstorage.StorageBackendRedis

	// DCRStorageBackendAuto automatically selects Redis if available, otherwise file
	DCRStorageBackendAuto DCRStorageBackend = dcrstorage.StorageBackendAuto
)

type DoublyLinkedList

type DoublyLinkedList struct {
	*list.List
}

DoublyLinkedList for backward compatibility

func NewDoublyLinkedList

func NewDoublyLinkedList() *DoublyLinkedList

NewDoublyLinkedList creates a new doubly linked list

func (*DoublyLinkedList) PopFront

func (l *DoublyLinkedList) PopFront() interface{}

PopFront removes and returns the front element

type DynamicClientRegistrar

type DynamicClientRegistrar struct {
	// contains filtered or unexported fields
}

DynamicClientRegistrar handles OIDC Dynamic Client Registration (RFC 7591)

func NewDynamicClientRegistrar

func NewDynamicClientRegistrar(
	httpClient *http.Client,
	logger *Logger,
	dcrConfig *DynamicClientRegistrationConfig,
	providerURL string,
) *DynamicClientRegistrar

NewDynamicClientRegistrar creates a new dynamic client registrar

func NewDynamicClientRegistrarWithStore

func NewDynamicClientRegistrarWithStore(
	httpClient *http.Client,
	logger *Logger,
	dcrConfig *DynamicClientRegistrationConfig,
	providerURL string,
	store DCRCredentialsStore,
) *DynamicClientRegistrar

NewDynamicClientRegistrarWithStore creates a new dynamic client registrar with a specific storage backend

func (*DynamicClientRegistrar) GetCachedResponse

func (r *DynamicClientRegistrar) GetCachedResponse() *ClientRegistrationResponse

GetCachedResponse returns the cached registration response

func (*DynamicClientRegistrar) RegisterClient

func (r *DynamicClientRegistrar) RegisterClient(ctx context.Context, registrationEndpoint string) (*ClientRegistrationResponse, error)

RegisterClient performs dynamic client registration with the OIDC provider It first attempts to load existing credentials from storage if persistence is enabled, then registers a new client if no valid credentials exist.

func (*DynamicClientRegistrar) SetStore

func (r *DynamicClientRegistrar) SetStore(store DCRCredentialsStore)

SetStore sets the credentials store for the registrar This allows setting the store after creation when the cache manager is available

type DynamicClientRegistrationConfig

type DynamicClientRegistrationConfig struct {
	ClientMetadata       *ClientRegistrationMetadata `json:"clientMetadata,omitempty"`
	InitialAccessToken   string                      `json:"initialAccessToken,omitempty"`
	RegistrationEndpoint string                      `json:"registrationEndpoint,omitempty"`
	CredentialsFile      string                      `json:"credentialsFile,omitempty"`
	// StorageBackend specifies where to store DCR credentials: "file", "redis", or "auto"
	// - "file": Use file-based storage (default for backward compatibility)
	// - "redis": Use Redis exclusively (fails if Redis unavailable)
	// - "auto": Use Redis if available, fallback to file (default)
	StorageBackend string `json:"storageBackend,omitempty"`
	// RedisKeyPrefix is the prefix for Redis keys when using Redis storage (default: "dcr:creds:")
	RedisKeyPrefix     string `json:"redisKeyPrefix,omitempty"`
	Enabled            bool   `json:"enabled"`
	PersistCredentials bool   `json:"persistCredentials"`
}

DynamicClientRegistrationConfig configures OIDC Dynamic Client Registration (RFC 7591)

type EdgeCaseGenerator

type EdgeCaseGenerator struct {
	// contains filtered or unexported fields
}

EdgeCaseGenerator provides utilities for generating comprehensive edge cases

func NewEdgeCaseGenerator

func NewEdgeCaseGenerator() *EdgeCaseGenerator

NewEdgeCaseGenerator creates a new edge case generator

func (*EdgeCaseGenerator) GenerateHTTPRequestEdgeCases

func (g *EdgeCaseGenerator) GenerateHTTPRequestEdgeCases() []*http.Request

GenerateHTTPRequestEdgeCases generates edge cases for HTTP requests

func (*EdgeCaseGenerator) GenerateIntegerEdgeCases

func (g *EdgeCaseGenerator) GenerateIntegerEdgeCases() []int

GenerateIntegerEdgeCases generates edge cases for integer inputs

func (*EdgeCaseGenerator) GenerateStringEdgeCases

func (g *EdgeCaseGenerator) GenerateStringEdgeCases() []string

GenerateStringEdgeCases generates edge cases for string inputs

func (*EdgeCaseGenerator) GenerateTimeEdgeCases

func (g *EdgeCaseGenerator) GenerateTimeEdgeCases() []time.Time

GenerateTimeEdgeCases generates edge cases for time inputs

type ErrorRecoveryManager

type ErrorRecoveryManager struct {
	// contains filtered or unexported fields
}

ErrorRecoveryManager coordinates all error recovery mechanisms

func NewErrorRecoveryManager

func NewErrorRecoveryManager(logger *Logger) *ErrorRecoveryManager

NewErrorRecoveryManager creates a new error recovery manager NewErrorRecoveryManager creates a comprehensive error recovery manager. Combines circuit breakers, retry logic, and graceful degradation into a unified system.

func (*ErrorRecoveryManager) ExecuteWithRecovery

func (erm *ErrorRecoveryManager) ExecuteWithRecovery(ctx context.Context, serviceName string, fn func() error) error

ExecuteWithRecovery executes a function with full error recovery support ExecuteWithRecovery executes a function with comprehensive error recovery. Applies circuit breaker protection and retry logic for the specified service.

func (*ErrorRecoveryManager) GetCircuitBreaker

func (erm *ErrorRecoveryManager) GetCircuitBreaker(serviceName string) *CircuitBreaker

GetCircuitBreaker gets or creates a circuit breaker for a service GetCircuitBreaker returns the circuit breaker for a specific service. Creates a new circuit breaker if one doesn't exist for the service.

func (*ErrorRecoveryManager) GetRecoveryMetrics

func (erm *ErrorRecoveryManager) GetRecoveryMetrics() map[string]interface{}

GetRecoveryMetrics returns metrics for all recovery mechanisms GetRecoveryMetrics returns comprehensive metrics for all recovery mechanisms. Includes circuit breaker states, retry statistics, and graceful degradation status.

type ErrorRecoveryMechanism

type ErrorRecoveryMechanism interface {
	// ExecuteWithContext executes a function with error recovery mechanisms
	ExecuteWithContext(ctx context.Context, fn func() error) error
	// GetMetrics returns metrics about the recovery mechanism's performance
	GetMetrics() map[string]interface{}
	// Reset resets the mechanism to its initial state
	Reset()
	// IsAvailable returns whether the mechanism is available for requests
	IsAvailable() bool
}

ErrorRecoveryMechanism defines the interface for error recovery strategies. It provides a common contract for implementing various resilience patterns (circuit breaker, retry, graceful degradation) to handle transient failures and protect downstream services from cascading failures.

type FileCredentialsStore

type FileCredentialsStore = fileStoreWrapper

FileCredentialsStore implements DCRCredentialsStore using file-based storage. This is the default storage backend for backward compatibility with existing deployments.

func NewFileCredentialsStore

func NewFileCredentialsStore(basePath string, logger *Logger) *FileCredentialsStore

NewFileCredentialsStore creates a new file-based credentials store. If basePath is empty, defaults to /tmp/oidc-client-credentials.json

type GenericCache

type GenericCache struct {
	// contains filtered or unexported fields
}

GenericCache provides a simple cache implementation for testing

func NewGenericCache

func NewGenericCache(ttl time.Duration, logger *Logger) *GenericCache

NewGenericCache creates a new generic cache

func (*GenericCache) Delete

func (gc *GenericCache) Delete(key string)

Delete removes a value from the cache

func (*GenericCache) Get

func (gc *GenericCache) Get(key string) (interface{}, bool)

Get retrieves a value from the cache

func (*GenericCache) Set

func (gc *GenericCache) Set(key string, value interface{})

Set stores a value in the cache

func (*GenericCache) Stop

func (gc *GenericCache) Stop()

Stop stops the cleanup routine

type GlobalTestCleanup

type GlobalTestCleanup struct {
	// contains filtered or unexported fields
}

GlobalTestCleanup tracks and cleans up test resources

func (*GlobalTestCleanup) CleanupAll

func (g *GlobalTestCleanup) CleanupAll()

CleanupAll cleans up all registered resources with timeout protection

func (*GlobalTestCleanup) RegisterCache

func (g *GlobalTestCleanup) RegisterCache(cache interface{ Close() })

RegisterCache registers a cache for cleanup

func (*GlobalTestCleanup) RegisterServer

func (g *GlobalTestCleanup) RegisterServer(server *httptest.Server)

RegisterServer registers an HTTP test server for cleanup

func (*GlobalTestCleanup) RegisterTask

func (g *GlobalTestCleanup) RegisterTask(task *BackgroundTask)

RegisterTask registers a background task for cleanup

type GoroutineManager

type GoroutineManager struct {
	// contains filtered or unexported fields
}

GoroutineManager manages background goroutines with proper lifecycle

func NewGoroutineManager

func NewGoroutineManager(logger *Logger) *GoroutineManager

NewGoroutineManager creates a new goroutine manager

func (*GoroutineManager) GetStatus

func (m *GoroutineManager) GetStatus() map[string]GoroutineStatus

GetStatus returns the status of all managed goroutines

func (*GoroutineManager) Shutdown

func (m *GoroutineManager) Shutdown(timeout time.Duration) error

Shutdown gracefully shuts down all managed goroutines

func (*GoroutineManager) StartGoroutine

func (m *GoroutineManager) StartGoroutine(name string, fn func(context.Context))

StartGoroutine starts a managed goroutine with context-based cancellation

func (*GoroutineManager) StartPeriodicTask

func (m *GoroutineManager) StartPeriodicTask(name string, interval time.Duration, task func())

StartPeriodicTask starts a periodic task with context-based cancellation

func (*GoroutineManager) StopGoroutine

func (m *GoroutineManager) StopGoroutine(name string)

StopGoroutine stops a specific goroutine by name

type GoroutinePool

type GoroutinePool struct {
	// contains filtered or unexported fields
}

GoroutinePool provides a pool of workers for controlled concurrency

func NewGoroutinePool

func NewGoroutinePool(maxWorkers int, logger *Logger) *GoroutinePool

NewGoroutinePool creates a new goroutine pool with the specified max workers

func (*GoroutinePool) PendingTasks

func (p *GoroutinePool) PendingTasks() int64

PendingTasks returns the number of tasks currently pending (queued or in-progress)

func (*GoroutinePool) Shutdown

func (p *GoroutinePool) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the pool

func (*GoroutinePool) Submit

func (p *GoroutinePool) Submit(task func()) error

Submit submits a task to the pool

func (*GoroutinePool) Wait

func (p *GoroutinePool) Wait()

Wait waits for all submitted tasks to complete using condition variable This is efficient and does not busy-poll, avoiding CPU spikes

func (*GoroutinePool) WaitWithTimeout

func (p *GoroutinePool) WaitWithTimeout(timeout time.Duration) bool

WaitWithTimeout waits for all submitted tasks to complete with a timeout Returns true if all tasks completed, false if timeout occurred

type GoroutineStatus

type GoroutineStatus struct {
	StartTime time.Time
	Name      string
	Runtime   time.Duration
	Running   bool
}

GoroutineStatus represents the status of a managed goroutine

type GracefulDegradation

type GracefulDegradation struct {
	*BaseRecoveryMechanism
	// contains filtered or unexported fields
}

GracefulDegradation implements graceful degradation patterns for service resilience. It provides fallback mechanisms when primary services are unavailable and monitors service health to automatically recover when services become available again.

func NewGracefulDegradation

func NewGracefulDegradation(config GracefulDegradationConfig, logger *Logger) *GracefulDegradation

NewGracefulDegradation creates a new graceful degradation manager NewGracefulDegradation creates a new graceful degradation mechanism. Initializes fallback and health check maps and starts background health monitoring.

func (*GracefulDegradation) Close

func (gd *GracefulDegradation) Close()

Close shuts down the graceful degradation system and cleans up resources

func (*GracefulDegradation) ExecuteWithContext

func (gd *GracefulDegradation) ExecuteWithContext(ctx context.Context, fn func() error) error

ExecuteWithContext implements the ErrorRecoveryMechanism interface

func (*GracefulDegradation) ExecuteWithFallback

func (gd *GracefulDegradation) ExecuteWithFallback(serviceName string, primary func() (interface{}, error)) (interface{}, error)

ExecuteWithFallback executes a function with fallback support

func (*GracefulDegradation) GetDegradedServices

func (gd *GracefulDegradation) GetDegradedServices() []string

GetDegradedServices returns a list of currently degraded services

func (*GracefulDegradation) GetMetrics

func (gd *GracefulDegradation) GetMetrics() map[string]interface{}

GetMetrics returns metrics about the graceful degradation mechanism

func (*GracefulDegradation) IsAvailable

func (gd *GracefulDegradation) IsAvailable() bool

IsAvailable returns whether the mechanism is available for use

func (*GracefulDegradation) RegisterFallback

func (gd *GracefulDegradation) RegisterFallback(serviceName string, fallback func() (interface{}, error))

RegisterFallback registers a fallback function for a service

func (*GracefulDegradation) RegisterHealthCheck

func (gd *GracefulDegradation) RegisterHealthCheck(serviceName string, healthCheck func() bool)

RegisterHealthCheck registers a health check function for a service

func (*GracefulDegradation) Reset

func (gd *GracefulDegradation) Reset()

Reset resets the state of all degraded services

type GracefulDegradationConfig

type GracefulDegradationConfig struct {
	// HealthCheckInterval defines how often to check service health
	HealthCheckInterval time.Duration `json:"health_check_interval"`
	// RecoveryTimeout is how long to wait before attempting service recovery
	RecoveryTimeout time.Duration `json:"recovery_timeout"`
	// EnableFallbacks controls whether fallback mechanisms are active
	EnableFallbacks bool `json:"enable_fallbacks"`
}

GracefulDegradationConfig holds configuration for graceful degradation behavior. Controls health checking frequency, recovery timing, and fallback enablement.

func DefaultGracefulDegradationConfig

func DefaultGracefulDegradationConfig() GracefulDegradationConfig

DefaultGracefulDegradationConfig returns sensible defaults for graceful degradation. Configured with moderate health check frequency and recovery timeouts.

type GzipReaderPool

type GzipReaderPool struct {
	// contains filtered or unexported fields
}

GzipReaderPool manages a pool of gzip readers

func NewGzipReaderPool

func NewGzipReaderPool() *GzipReaderPool

NewGzipReaderPool creates a new gzip reader pool

func (*GzipReaderPool) Get

func (p *GzipReaderPool) Get() *gzip.Reader

Get retrieves a gzip reader from the pool

func (*GzipReaderPool) Put

func (p *GzipReaderPool) Put(r *gzip.Reader)

Put returns a gzip reader to the pool

type GzipWriterPool

type GzipWriterPool struct {
	// contains filtered or unexported fields
}

GzipWriterPool manages a pool of gzip writers

func NewGzipWriterPool

func NewGzipWriterPool() *GzipWriterPool

NewGzipWriterPool creates a new gzip writer pool

func (*GzipWriterPool) Get

func (p *GzipWriterPool) Get() *gzip.Writer

Get retrieves a gzip writer from the pool

func (*GzipWriterPool) Put

func (p *GzipWriterPool) Put(w *gzip.Writer)

Put returns a gzip writer to the pool

type HTTPClientConfig

type HTTPClientConfig struct {
	IdleConnTimeout       time.Duration
	MaxIdleConns          int
	ReadBufferSize        int
	DialTimeout           time.Duration
	KeepAlive             time.Duration
	TLSHandshakeTimeout   time.Duration
	ResponseHeaderTimeout time.Duration
	ExpectContinueTimeout time.Duration
	MaxRedirects          int
	MaxIdleConnsPerHost   int
	Timeout               time.Duration
	MaxConnsPerHost       int
	WriteBufferSize       int
	// RootCAs is an optional certificate pool used for TLS verification.
	// A nil pool means "use the system trust store" (default behavior).
	RootCAs *x509.CertPool
	// InsecureSkipVerify disables TLS certificate verification.
	// ONLY set this for local development against self-signed certificates.
	InsecureSkipVerify bool
	UseCookieJar       bool
	ForceHTTP2         bool
	DisableKeepAlives  bool
	DisableCompression bool
}

HTTPClientConfig provides configuration for creating HTTP clients

func DefaultHTTPClientConfig

func DefaultHTTPClientConfig() HTTPClientConfig

DefaultHTTPClientConfig returns the default configuration for general use

func OIDCProviderHTTPClientConfig

func OIDCProviderHTTPClientConfig() HTTPClientConfig

OIDCProviderHTTPClientConfig returns configuration optimized for OIDC provider calls

func TokenHTTPClientConfig

func TokenHTTPClientConfig() HTTPClientConfig

TokenHTTPClientConfig returns configuration optimized for token operations

type HTTPClientFactory

type HTTPClientFactory struct{}

HTTPClientFactory provides methods for creating configured HTTP clients

func NewHTTPClientFactory

func NewHTTPClientFactory() *HTTPClientFactory

NewHTTPClientFactory creates a new HTTP client factory

func (*HTTPClientFactory) CreateDefaultClient

func (f *HTTPClientFactory) CreateDefaultClient() *http.Client

CreateDefaultClient creates a client with default configuration

func (*HTTPClientFactory) CreateHTTPClient

func (f *HTTPClientFactory) CreateHTTPClient(config HTTPClientConfig) *http.Client

CreateHTTPClient creates an HTTP client with the given configuration Validates configuration parameters before creating the client

func (*HTTPClientFactory) CreateTokenClient

func (f *HTTPClientFactory) CreateTokenClient() *http.Client

CreateTokenClient creates a client optimized for token operations

func (*HTTPClientFactory) ValidateHTTPClientConfig

func (f *HTTPClientFactory) ValidateHTTPClientConfig(config *HTTPClientConfig) error

ValidateHTTPClientConfig validates HTTP client configuration parameters

type HTTPClientProfiler

type HTTPClientProfiler struct {
	// contains filtered or unexported fields
}

HTTPClientProfiler monitors HTTP client connection pools

func NewHTTPClientProfiler

func NewHTTPClientProfiler(client *http.Client, logger *Logger) *HTTPClientProfiler

NewHTTPClientProfiler creates a new HTTP client profiler

func (*HTTPClientProfiler) AnalyzeLeaks

func (hcp *HTTPClientProfiler) AnalyzeLeaks(baseline, current *MemorySnapshot) *LeakAnalysis

AnalyzeLeaks analyzes HTTP client for connection leaks

func (*HTTPClientProfiler) GetCurrentStats

func (hcp *HTTPClientProfiler) GetCurrentStats() *runtime.MemStats

GetCurrentStats returns current memory statistics

func (*HTTPClientProfiler) StartProfiling

func (hcp *HTTPClientProfiler) StartProfiling(config ProfilingConfig) error

StartProfiling begins profiling (no-op for HTTP client)

func (*HTTPClientProfiler) StopProfiling

func (hcp *HTTPClientProfiler) StopProfiling() (*MemorySnapshot, error)

StopProfiling ends profiling

func (*HTTPClientProfiler) TakeSnapshot

func (hcp *HTTPClientProfiler) TakeSnapshot() (*MemorySnapshot, error)

TakeSnapshot captures HTTP client memory statistics

type HTTPError

type HTTPError struct {
	// Message is the error description
	Message string
	// StatusCode is the HTTP status code
	StatusCode int
}

HTTPError represents an HTTP error with status code and message. Used for categorizing HTTP-related errors in error recovery mechanisms.

func (*HTTPError) Error

func (e *HTTPError) Error() string

Error returns the string representation of the HTTP error. Implements the error interface.

type InputValidationConfig

type InputValidationConfig struct {
	MaxTokenLength          int  `json:"max_token_length"`
	MaxURLLength            int  `json:"max_url_length"`
	MaxHeaderLength         int  `json:"max_header_length"`
	MaxClaimLength          int  `json:"max_claim_length"`
	MaxEmailLength          int  `json:"max_email_length"`
	MaxUsernameLength       int  `json:"max_username_length"`
	StrictMode              bool `json:"strict_mode"`
	AllowPrivateIPAddresses bool `json:"allow_private_ip_addresses"` // Allow private IP addresses in URL validation
}

InputValidationConfig defines the configuration parameters for input validation. It specifies maximum lengths for various input types and controls whether strict validation mode is enabled.

func DefaultInputValidationConfig

func DefaultInputValidationConfig() InputValidationConfig

DefaultInputValidationConfig returns a secure default configuration for input validation with reasonable limits based on industry standards and security best practices.

type InputValidator

type InputValidator struct {
	// contains filtered or unexported fields
}

InputValidator provides comprehensive input validation and sanitization to protect against common security vulnerabilities including SQL injection, XSS, path traversal, and other injection attacks. It validates and sanitizes various input types used in OIDC authentication flows.

func NewInputValidator

func NewInputValidator(config InputValidationConfig, logger *Logger) (*InputValidator, error)

NewInputValidator creates a new input validator with the specified configuration. It uses pre-compiled regex patterns and initializes security pattern lists.

Parameters:

  • config: Validation configuration with size limits and mode settings.
  • logger: Logger instance for recording validation events.

Returns:

  • A configured InputValidator instance.
  • An error (always nil, kept for API compatibility).

func (*InputValidator) SanitizeInput

func (iv *InputValidator) SanitizeInput(input string, maxLength int) string

SanitizeInput provides general input sanitization

func (*InputValidator) ValidateBoundaryValues

func (iv *InputValidator) ValidateBoundaryValues(value interface{}, min, max int64) ValidationResult

ValidateBoundaryValues validates numeric boundary values

func (*InputValidator) ValidateClaim

func (iv *InputValidator) ValidateClaim(claimName, claimValue string) ValidationResult

ValidateClaim validates individual JWT claims

func (*InputValidator) ValidateEmail

func (iv *InputValidator) ValidateEmail(email string) ValidationResult

ValidateEmail validates email addresses

func (*InputValidator) ValidateHeader

func (iv *InputValidator) ValidateHeader(headerName, headerValue string) ValidationResult

ValidateHeader validates HTTP header values

func (*InputValidator) ValidateToken

func (iv *InputValidator) ValidateToken(token string) ValidationResult

ValidateToken validates JWT tokens and similar token strings

func (*InputValidator) ValidateURL

func (iv *InputValidator) ValidateURL(urlStr string) ValidationResult

ValidateURL validates URLs

func (*InputValidator) ValidateUsername

func (iv *InputValidator) ValidateUsername(username string) ValidationResult

ValidateUsername validates usernames

type IntrospectionResponse

type IntrospectionResponse struct {
	Scope     string `json:"scope,omitempty"`
	ClientID  string `json:"client_id,omitempty"`
	Username  string `json:"username,omitempty"`
	TokenType string `json:"token_type,omitempty"`
	Sub       string `json:"sub,omitempty"`
	// Aud holds the introspection audience. Per RFC 7662 it may be a single
	// string or an array of strings, so it is decoded as interface{} and
	// matched with verifyAudience (which handles both shapes).
	Aud    interface{} `json:"aud,omitempty"`
	Iss    string      `json:"iss,omitempty"`
	Jti    string      `json:"jti,omitempty"`
	Exp    int64       `json:"exp,omitempty"`
	Iat    int64       `json:"iat,omitempty"`
	Nbf    int64       `json:"nbf,omitempty"`
	Active bool        `json:"active"`
}

IntrospectionResponse represents the response from an OAuth 2.0 token introspection endpoint. Per RFC 7662, this contains information about the token's validity and properties.

type JWK

type JWK struct {
	Kty    string   `json:"kty"`
	Use    string   `json:"use,omitempty"`
	Alg    string   `json:"alg,omitempty"`
	Kid    string   `json:"kid,omitempty"`
	N      string   `json:"n,omitempty"`
	E      string   `json:"e,omitempty"`
	Crv    string   `json:"crv,omitempty"`
	X      string   `json:"x,omitempty"`
	Y      string   `json:"y,omitempty"`
	KeyOps []string `json:"key_ops,omitempty"`
}

JWK represents a JSON Web Key as defined in RFC 7517. It can represent different key types including RSA, EC, and symmetric keys.

func (*JWK) ToECDSAPublicKey

func (jwk *JWK) ToECDSAPublicKey() (*ecdsa.PublicKey, error)

ToECDSAPublicKey converts a JWK to an ECDSA public key. Returns an error if the JWK is not an EC key or if the key data is invalid.

func (*JWK) ToRSAPublicKey

func (jwk *JWK) ToRSAPublicKey() (*rsa.PublicKey, error)

ToRSAPublicKey converts a JWK to an RSA public key. Returns an error if the JWK is not an RSA key or if the key data is invalid.

type JWKCache

type JWKCache struct {
	// contains filtered or unexported fields
}

JWKCache provides thread-safe caching of JWKS using UniversalCache.

inflightFetches deduplicates concurrent fetches for the same JWKS URL. It replaces a global sync.RWMutex that was previously held for the entire HTTP round-trip in GetJWKS: on a cold cache (cold pod, JWK rotation, brief network blip) every concurrent request piled up on that single Lock(), and under Yaegi each Lock acquisition costs 10-50ms of interpreter-dispatch overhead. The singleflight pattern keeps the cold-cache cost O(1) HTTP fetch regardless of how many requests are waiting.

func NewJWKCache

func NewJWKCache() *JWKCache

NewJWKCache creates a new JWK cache using the global cache manager

func (*JWKCache) Cleanup

func (c *JWKCache) Cleanup()

Cleanup is a no-op as cleanup is handled by UniversalCache

func (*JWKCache) Close

func (c *JWKCache) Close()

Close is a no-op as the cache is managed globally

func (*JWKCache) GetJWKS

func (c *JWKCache) GetJWKS(ctx context.Context, jwksURL string, httpClient *http.Client) (*JWKSet, error)

GetJWKS retrieves JWKS from cache or fetches from the remote URL if not cached.

The entry is stored locally only via SetLocal/GetLocal. Going through a distributed backend defeats the cache: JSON round-tripping turns *JWKSet into map[string]interface{}, the type assertion below fails, and every request refetches from the upstream. JWK rotation is rare and a per-replica HTTP fetch on cold cache is cheap, so cross-replica coherence buys nothing.

func (*JWKCache) GetPublicKey

func (c *JWKCache) GetPublicKey(ctx context.Context, jwksURL, kid string, httpClient *http.Client) (crypto.PublicKey, error)

GetPublicKey returns the parsed public key for a given kid, fetching and caching the JWKS plus its derived parsedJWKS on miss. The parsed entry is stored alongside the raw JWKSet under a sibling cache key with the same 1-hour TTL, so both invalidate together when the upstream JWKS rotates.

parsedJWKS is stored locally only (SetLocal/GetLocal). Its values are crypto.PublicKey interfaces wrapping *rsa.PublicKey/*ecdsa.PublicKey, which contain *big.Int that marshals to a hundreds-digit JSON number. On a distributed backend round-trip, json.Unmarshal into interface{} would try to fit that into float64 and fail with UnmarshalTypeError. Under yaegi the unexported parsedJWKS.keys field is exposed via an X-prefixed name on Marshal, leaking the modulus into the cached payload (issue #134).

type JWKCacheConfig

type JWKCacheConfig struct {
	RefreshInterval time.Duration
	MinRefreshTime  time.Duration
	MaxKeyAge       time.Duration
}

JWKCacheConfig provides JWK-specific cache configuration

type JWKCacheInterface

type JWKCacheInterface interface {
	GetJWKS(ctx context.Context, jwksURL string, httpClient *http.Client) (*JWKSet, error)
	GetPublicKey(ctx context.Context, jwksURL, kid string, httpClient *http.Client) (crypto.PublicKey, error)
	Cleanup()
	Close()
}

JWKCacheInterface defines the contract for JWK caching implementations.

type JWKSet

type JWKSet struct {
	// Keys contains the array of JWK objects
	Keys []JWK `json:"keys"`
}

JWKSet represents a set of JSON Web Keys. Typically fetched from an OIDC provider's JWKS endpoint.

func (*JWKSet) GetKey

func (jwks *JWKSet) GetKey(kid string) *JWK

GetKey finds a key by its ID (kid) in the JWKSet. Returns nil if no key with the given ID is found.

type JWT

type JWT struct {
	// Header contains the JWT header claims (alg, typ, kid, etc.)
	Header map[string]interface{}
	// Claims contains the JWT payload claims (iss, sub, aud, exp, etc.)
	Claims map[string]interface{}
	// Token is the original JWT token string
	Token string
	// Signature contains the decoded JWT signature bytes
	Signature []byte
}

JWT represents a parsed JSON Web Token with its constituent parts. It provides a structured representation of JWT components for validation and processing within the OIDC middleware.

func (*JWT) Verify

func (j *JWT) Verify(issuerURL, expectedAudience string, skipReplayCheck ...bool) error

Verify performs comprehensive JWT token validation according to OIDC specifications. It validates the token signature algorithm, issuer, audience, expiration, issued-at time, not-before time (if present), and prevents replay attacks using JTI claims. Parameters:

  • issuerURL: Expected issuer URL to validate against
  • expectedAudience: Expected audience to validate against (can be clientID or custom audience)
  • skipReplayCheck: Optional parameter to skip replay attack protection

Returns:

  • An error describing the first validation failure encountered

type JWTVerifier

type JWTVerifier interface {
	VerifyJWTSignatureAndClaims(jwt *JWT, token string) error
}

JWTVerifier interface defines JWT-specific verification capabilities. Implementations should validate JWT structure, signature using JWKs, and standard claims.

type LRUStrategy

type LRUStrategy struct {
	// contains filtered or unexported fields
}

LRUStrategy for backward compatibility

func (*LRUStrategy) EstimateSize

func (s *LRUStrategy) EstimateSize(item interface{}) int64

func (*LRUStrategy) GetEvictionCandidate

func (s *LRUStrategy) GetEvictionCandidate() (key string, found bool)

func (*LRUStrategy) Name

func (s *LRUStrategy) Name() string

func (*LRUStrategy) OnAccess

func (s *LRUStrategy) OnAccess(key string, item interface{})

func (*LRUStrategy) OnRemove

func (s *LRUStrategy) OnRemove(key string)

func (*LRUStrategy) ShouldEvict

func (s *LRUStrategy) ShouldEvict(item interface{}, now time.Time) bool

type LazyBackgroundTask

type LazyBackgroundTask struct {
	// BackgroundTask is the underlying task implementation
	*BackgroundTask
	// contains filtered or unexported fields
}

LazyBackgroundTask wraps BackgroundTask to provide delayed initialization. This prevents memory leaks from unnecessary background tasks by starting them only when actually needed, reducing resource usage in idle scenarios.

Lifecycle is one-shot: once Stop has been called the task cannot be restarted. The underlying BackgroundTask uses sync.Once for Start and refuses to re-run after Stop, so restart is not supported by design.

func NewLazyBackgroundTask

func NewLazyBackgroundTask(name string, interval time.Duration, taskFunc func(), logger *Logger, wg ...*sync.WaitGroup) *LazyBackgroundTask

NewLazyBackgroundTask creates a background task that doesn't start immediately. The task will only start when explicitly activated, preventing unnecessary resource usage for tasks that may never be needed.

func (*LazyBackgroundTask) StartIfNeeded

func (lt *LazyBackgroundTask) StartIfNeeded()

StartIfNeeded starts the background task only if it hasn't been started yet. Safe to call concurrently. After Stop has been called this is a no-op; the task is not restartable.

func (*LazyBackgroundTask) Stop

func (lt *LazyBackgroundTask) Stop()

Stop stops the background task if it was started. Once stopped, the task cannot be restarted (see type doc).

type LeakAnalysis

type LeakAnalysis struct {
	LeakDescription   string
	SuspectedLeaks    []string
	Recommendations   []string
	MemoryIncrease    uint64
	GoroutineIncrease int
	HasLeak           bool
}

LeakAnalysis contains the results of memory leak detection and analysis. Provides actionable insights about potential memory leaks and recommendations for addressing identified issues.

type LeakDetectionConfig

type LeakDetectionConfig struct {
	// EnableLeakDetection enables automatic leak detection
	EnableLeakDetection bool
	// LeakThresholdMB sets general memory leak threshold in megabytes
	LeakThresholdMB uint64
	// GoroutineLeakThreshold sets limit for goroutine count increases
	GoroutineLeakThreshold int
	// SessionPoolThreshold sets limit for session pool size
	SessionPoolThreshold int
	// CacheMemoryThreshold sets limit for cache memory usage
	CacheMemoryThreshold uint64
	// HTTPClientThreshold sets limit for HTTP client connections
	HTTPClientThreshold int
	// Deprecated: TokenCompressionThreshold is no longer used
	TokenCompressionThreshold uint64
}

LeakDetectionConfig contains configuration parameters for memory leak detection. Defines thresholds and limits for various types of memory leak detection.

type ListNode

type ListNode struct {
	Value interface{}
	Next  *ListNode
	Prev  *ListNode
	Key   string
}

ListNode for backward compatibility

type Logger

type Logger struct {
	// contains filtered or unexported fields
}

Logger provides structured logging capabilities with different severity levels. It supports error, info, and debug levels with appropriate output streams and formatting for each level.

func GetSingletonNoOpLogger

func GetSingletonNoOpLogger() *Logger

GetSingletonNoOpLogger returns the singleton no-op logger instance. This reduces memory allocation by reusing the same no-op logger instance across the entire application.

func NewLogger

func NewLogger(logLevel string) *Logger

NewLogger creates and configures a new Logger instance based on the provided log level. It initializes loggers for ERROR (stderr), INFO (stdout), and DEBUG (stdout) levels, enabling output based on the specified level:

  • "error": Only ERROR messages are output.
  • "info": INFO and ERROR messages are output.
  • "debug": DEBUG, INFO, and ERROR messages are output.

If an invalid level is provided, it defaults to behavior similar to "error".

Parameters:

  • logLevel: The desired logging level ("debug", "info", or "error").

Returns:

  • A pointer to the configured Logger instance.

NewLogger creates a new logger instance with the specified log level. If logLevel is empty, defaults to "info". Invalid log levels default to "info".

func (*Logger) Debug

func (l *Logger) Debug(format string, args ...interface{})

Debug logs a message at the DEBUG level. Output is directed to stdout only if the configured log level is "debug".

Parameters:

  • format: The format string (as in fmt.Printf).
  • args: The arguments for the format string.

Debug logs a debug message if the logger's level allows it.

func (*Logger) Debugf

func (l *Logger) Debugf(format string, args ...interface{})

Debugf logs a formatted message at the DEBUG level. Equivalent to calling l.Debug(format, args...). Output is directed to stdout only if the configured log level is "debug".

Parameters:

  • format: The format string (as in fmt.Printf).
  • args: The arguments for the format string.

Debugf logs a formatted debug message if the logger's level allows it.

func (*Logger) Error

func (l *Logger) Error(format string, args ...interface{})

Error logs a message at the ERROR level using Printf style formatting. Output is always directed to stderr, regardless of the configured log level.

Parameters:

  • format: The format string (as in fmt.Printf).
  • args: The arguments for the format string.

Error logs an error message. Errors are always logged regardless of level.

func (*Logger) Errorf

func (l *Logger) Errorf(format string, args ...interface{})

Errorf logs a message at the ERROR level using Printf style formatting. Equivalent to calling l.Error(format, args...). Output is always directed to stderr, regardless of the configured log level.

Parameters:

  • format: The format string (as in fmt.Printf).
  • args: The arguments for the format string.

Errorf logs a formatted error message. Errors are always logged regardless of level.

func (*Logger) Info

func (l *Logger) Info(format string, args ...interface{})

Info logs a message at the INFO level using Printf style formatting. Output is directed to stdout if the configured log level is "info" or "debug".

Parameters:

  • format: The format string (as in fmt.Printf).
  • args: The arguments for the format string.

Info logs an informational message if the logger's level allows it.

func (*Logger) Infof

func (l *Logger) Infof(format string, args ...interface{})

Infof logs a message at the INFO level using Printf style formatting. Equivalent to calling l.Info(format, args...). Output is directed to stdout if the configured log level is "info" or "debug".

Parameters:

  • format: The format string (as in fmt.Printf).
  • args: The arguments for the format string.

Infof logs a formatted informational message if the logger's level allows it.

func (*Logger) IsDebug

func (l *Logger) IsDebug() bool

IsDebug reports whether debug-level logging is enabled. Callers should use this to avoid expensive format-string expansion (e.g. on hot paths under yaegi) when debug output would be discarded.

type LogoutTokenClaims

type LogoutTokenClaims struct {
	Issuer    string                 `json:"iss"`
	Subject   string                 `json:"sub,omitempty"`
	Audience  interface{}            `json:"aud"` // Can be string or []string
	IssuedAt  int64                  `json:"iat"`
	JTI       string                 `json:"jti"`
	Events    map[string]interface{} `json:"events"`
	SessionID string                 `json:"sid,omitempty"`
	Nonce     string                 `json:"nonce,omitempty"` // Must NOT be present
}

LogoutTokenClaims represents the claims in an OIDC logout token as defined in OpenID Connect Back-Channel Logout 1.0

type MemoryAlertThresholds

type MemoryAlertThresholds struct {
	HeapSizeMB          uint64  // Alert when heap exceeds this size in MB
	HeapGrowthRateMB    float64 // Alert when heap grows faster than this MB/sec
	GoroutineCount      int     // Alert when goroutine count exceeds this
	GoroutineGrowthRate float64 // Alert when goroutines grow faster than this per minute
	GCFrequency         float64 // Alert when GC frequency exceeds this per minute
}

MemoryAlertThresholds defines when to trigger memory alerts

func DefaultMemoryAlertThresholds

func DefaultMemoryAlertThresholds() MemoryAlertThresholds

DefaultMemoryAlertThresholds returns sensible default alert thresholds

type MemoryLeakTestCase

type MemoryLeakTestCase struct {
	Operation          func() error
	Setup              func() error
	Teardown           func() error
	Name               string
	Description        string
	Iterations         int
	MaxGoroutineGrowth int
	MaxMemoryGrowthMB  float64
	Timeout            time.Duration
	GCBetweenRuns      bool
}

MemoryLeakTestCase represents a test case specifically for memory leak detection

type MemoryMonitor

type MemoryMonitor struct {
	// contains filtered or unexported fields
}

MemoryMonitor provides comprehensive memory monitoring and alerting.

Memory sampling is expensive: runtime.ReadMemStats is a stop-the-world operation. To keep latency predictable the monitor caches the most recent sample and only refreshes it when the background ticker fires, when TriggerGC is invoked, or when a caller explicitly calls Refresh(). GetCurrentStats is a cheap read of that cached sample.

func GetGlobalMemoryMonitor

func GetGlobalMemoryMonitor() *MemoryMonitor

GetGlobalMemoryMonitor returns the singleton memory monitor

func NewMemoryMonitor

func NewMemoryMonitor(logger *Logger, thresholds MemoryAlertThresholds) *MemoryMonitor

NewMemoryMonitor creates a new memory monitor using default scheduling configuration. See NewMemoryMonitorWithConfig for full control.

func NewMemoryMonitorWithConfig

func NewMemoryMonitorWithConfig(logger *Logger, thresholds MemoryAlertThresholds, config MemoryMonitorConfig) *MemoryMonitor

NewMemoryMonitorWithConfig creates a new memory monitor with an explicit scheduling config.

NOTE: the constructor performs a single runtime.ReadMemStats call to capture baseline heap / goroutine / GC counters used for leak and growth detection. This is a one-time stop-the-world cost at startup; all subsequent samples only happen on the monitoring ticker or on explicit Refresh() calls.

func (*MemoryMonitor) GetCurrentStats

func (mm *MemoryMonitor) GetCurrentStats() *MemoryStats

GetCurrentStats returns the most recently sampled memory statistics.

This is a cheap cached read: it does NOT call runtime.ReadMemStats. Samples are refreshed only by the monitoring ticker or by an explicit call to Refresh(). If no sample has been produced yet, stats derived from the constructor-time raw sample are returned (with no additional STW cost).

func (*MemoryMonitor) GetMemoryPressure

func (mm *MemoryMonitor) GetMemoryPressure() MemoryPressureLevel

GetMemoryPressure returns the current memory pressure level

func (*MemoryMonitor) IsMonitoringActive

func (mm *MemoryMonitor) IsMonitoringActive() bool

IsMonitoringActive returns true if global memory monitoring is currently active

func (*MemoryMonitor) LogMemoryStats

func (mm *MemoryMonitor) LogMemoryStats(stats *MemoryStats)

LogMemoryStats logs comprehensive memory statistics

func (*MemoryMonitor) Refresh

func (mm *MemoryMonitor) Refresh() *MemoryStats

Refresh synchronously samples current memory statistics via runtime.ReadMemStats and updates the cached value. This is the only path (other than the monitoring ticker and TriggerGC) that pays the stop-the-world cost. Use it in tests or in callers that explicitly need a fresh sample.

func (*MemoryMonitor) StartMonitoring

func (mm *MemoryMonitor) StartMonitoring(ctx context.Context, interval time.Duration)

StartMonitoring starts continuous memory monitoring as a global singleton.

The effective interval is resolved as follows:

  1. If the caller passes a positive interval, that is used.
  2. Otherwise the configured MemoryMonitorConfig.Interval is used.
  3. Otherwise the built-in default (60s) is used.

The result is then clamped to a minimum of MinMemoryMonitorInterval (30s) to avoid stop-the-world ReadMemStats storms. Callers that need rapid updates in tests should call Refresh() directly instead of spinning the ticker fast.

func (*MemoryMonitor) StopMonitoring

func (mm *MemoryMonitor) StopMonitoring()

StopMonitoring stops the global memory monitoring if it's running

func (*MemoryMonitor) TriggerGC

func (mm *MemoryMonitor) TriggerGC()

TriggerGC forces garbage collection and logs the impact. Both the before and after measurements are fresh samples (explicit Refresh() calls) because the comparison is meaningless against a stale cached snapshot.

type MemoryMonitorConfig

type MemoryMonitorConfig struct {
	// Interval between background samples. Must be >= MinMemoryMonitorInterval
	// (30s). Values below the minimum are clamped when monitoring starts.
	Interval time.Duration
}

MemoryMonitorConfig configures the memory monitor's scheduling behavior. Thresholds are kept separate in MemoryAlertThresholds.

func DefaultMemoryMonitorConfig

func DefaultMemoryMonitorConfig() MemoryMonitorConfig

DefaultMemoryMonitorConfig returns a config with sensible production defaults.

type MemoryOptimizations

type MemoryOptimizations struct {
	// contains filtered or unexported fields
}

MemoryOptimizations contains all memory optimization utilities

func GetMemoryOptimizations

func GetMemoryOptimizations() *MemoryOptimizations

GetMemoryOptimizations returns the global memory optimizations instance

func (*MemoryOptimizations) GetSingletonLogger

func (m *MemoryOptimizations) GetSingletonLogger(level string) *Logger

GetSingletonLogger returns a singleton logger instance

type MemoryPressureLevel

type MemoryPressureLevel int

MemoryPressureLevel indicates the current memory pressure

const (
	MemoryPressureNone MemoryPressureLevel = iota
	MemoryPressureLow
	MemoryPressureModerate
	MemoryPressureHigh
	MemoryPressureCritical
)

func (MemoryPressureLevel) String

func (mpl MemoryPressureLevel) String() string

type MemoryProfiler

type MemoryProfiler interface {
	// TakeSnapshot captures current memory state for analysis
	TakeSnapshot() (*MemorySnapshot, error)
	// StartProfiling begins continuous memory monitoring
	StartProfiling(config ProfilingConfig) error
	// StopProfiling ends monitoring and returns final snapshot
	StopProfiling() (*MemorySnapshot, error)
	// GetCurrentStats returns current runtime memory statistics
	GetCurrentStats() *runtime.MemStats
	// AnalyzeLeaks compares snapshots to detect memory leaks
	AnalyzeLeaks(baseline, current *MemorySnapshot) *LeakAnalysis
}

MemoryProfiler defines the interface for memory profiling operations. Implementations provide memory monitoring, leak detection, and performance analysis capabilities for debugging and optimizing memory usage in production environments.

type MemorySnapshot

type MemorySnapshot struct {
	Timestamp        time.Time
	CustomMetrics    map[string]interface{}
	HeapProfile      []byte
	GoroutineProfile []byte
	RuntimeStats     runtime.MemStats
}

MemorySnapshot represents a point-in-time capture of memory statistics. It provides comprehensive memory profiling data including heap, goroutines, and custom metrics for detailed memory usage analysis.

type MemoryStats

type MemoryStats struct {
	LastGCTime        time.Time
	Timestamp         time.Time
	GCSysBytes        uint64
	NumGoroutines     int
	HeapReleasedBytes uint64
	HeapObjects       uint64
	StackInuseBytes   uint64
	StackSysBytes     uint64
	HeapAllocBytes    uint64
	HeapInuseBytes    uint64
	HeapIdleBytes     uint64
	SessionCount      int
	TaskCount         int
	CacheSize         int64
	ConnectionPools   int
	MemoryPressure    MemoryPressureLevel
	GCFrequency       float64
	HeapSysBytes      uint64
}

MemoryStats holds comprehensive memory statistics

type MemoryTestOrchestrator

type MemoryTestOrchestrator struct {
	// contains filtered or unexported fields
}

MemoryTestOrchestrator coordinates memory leak testing across components

func GetGlobalTestOrchestrator

func GetGlobalTestOrchestrator() *MemoryTestOrchestrator

GetGlobalTestOrchestrator returns the singleton test orchestrator

func NewMemoryTestOrchestrator

func NewMemoryTestOrchestrator(config LeakDetectionConfig, logger *Logger) *MemoryTestOrchestrator

NewMemoryTestOrchestrator creates a new test orchestrator

func (*MemoryTestOrchestrator) GetAllLeakAnalyses

func (mto *MemoryTestOrchestrator) GetAllLeakAnalyses() map[string]*LeakAnalysis

GetAllLeakAnalyses returns leak analyses for all components

func (*MemoryTestOrchestrator) GetLeakAnalysis

func (mto *MemoryTestOrchestrator) GetLeakAnalysis(componentName string) (*LeakAnalysis, bool)

GetLeakAnalysis returns leak analysis for a specific component

func (*MemoryTestOrchestrator) RegisterComponent

func (mto *MemoryTestOrchestrator) RegisterComponent(name string, profiler MemoryProfiler)

RegisterComponent registers a component for memory leak testing

func (*MemoryTestOrchestrator) StartLeakDetection

func (mto *MemoryTestOrchestrator) StartLeakDetection() error

StartLeakDetection begins continuous leak detection monitoring

func (*MemoryTestOrchestrator) StopLeakDetection

func (mto *MemoryTestOrchestrator) StopLeakDetection() error

StopLeakDetection stops continuous leak detection monitoring

func (*MemoryTestOrchestrator) UnregisterComponent

func (mto *MemoryTestOrchestrator) UnregisterComponent(name string)

UnregisterComponent removes a component from leak testing

type MetadataCache

type MetadataCache struct {
	// contains filtered or unexported fields
}

MetadataCache wraps UniversalCache for metadata operations

func NewFixedMetadataCache

func NewFixedMetadataCache(args ...interface{}) *MetadataCache

NewFixedMetadataCache creates a metadata cache with fixed configuration

func NewMetadataCache

func NewMetadataCache(wg *sync.WaitGroup) *MetadataCache

NewMetadataCache creates a new metadata cache

func NewMetadataCacheWithLogger

func NewMetadataCacheWithLogger(wg *sync.WaitGroup, logger *Logger) *MetadataCache

NewMetadataCacheWithLogger creates a metadata cache with specific logger

func (*MetadataCache) CleanupExpired

func (mc *MetadataCache) CleanupExpired()

CleanupExpired triggers cleanup of expired entries

func (*MetadataCache) Clear

func (mc *MetadataCache) Clear()

Clear removes all cached metadata

func (*MetadataCache) Close

func (mc *MetadataCache) Close()

Close shuts down the cache

func (*MetadataCache) Delete

func (mc *MetadataCache) Delete(key string)

Delete removes an entry from the cache

func (*MetadataCache) Get

func (mc *MetadataCache) Get(providerURL string) (*ProviderMetadata, bool)

Get retrieves provider metadata from cache

func (*MetadataCache) GetMetadata

func (mc *MetadataCache) GetMetadata(providerURL string, httpClient *http.Client, logger *Logger) (*ProviderMetadata, error)

GetMetadata fetches metadata with HTTP client and logger

func (*MetadataCache) GetMetadataWithRecovery

func (mc *MetadataCache) GetMetadataWithRecovery(providerURL string, httpClient *http.Client, logger *Logger, errorRecoveryManager *ErrorRecoveryManager) (*ProviderMetadata, error)

GetMetadataWithRecovery fetches metadata with retry support for startup scenarios. This handles the race condition where Traefik initializes the plugin before the OIDC provider routes are fully established, or before TLS certificates are loaded. Uses aggressive retry settings (10 attempts, 1s intervals) to give the infrastructure time to stabilize during cold starts. See: https://github.com/orangeboyChen/traefikoidc/issues/90

func (*MetadataCache) GetMetrics

func (mc *MetadataCache) GetMetrics() map[string]interface{}

GetMetrics returns cache metrics

func (*MetadataCache) GetProviderMetadata

func (mc *MetadataCache) GetProviderMetadata(ctx context.Context, providerURL string, httpClient *http.Client) (*ProviderMetadata, error)

GetProviderMetadata fetches metadata with automatic caching

func (*MetadataCache) GetStats

func (mc *MetadataCache) GetStats() map[string]interface{}

GetStats returns cache statistics for testing

func (*MetadataCache) Mutex

func (mc *MetadataCache) Mutex() *sync.RWMutex

Mutex returns the cache mutex for testing

func (*MetadataCache) Set

func (mc *MetadataCache) Set(providerURL string, metadata *ProviderMetadata, ttl time.Duration) error

Set stores provider metadata with a TTL

func (*MetadataCache) Size

func (mc *MetadataCache) Size() int

Size returns the number of cached entries

type MetadataCacheConfig

type MetadataCacheConfig struct {
	SecurityCriticalFields         []string
	GracePeriod                    time.Duration
	ExtendedGracePeriod            time.Duration
	MaxGracePeriod                 time.Duration
	SecurityCriticalMaxGracePeriod time.Duration
}

MetadataCacheConfig provides metadata-specific cache configuration

type MetadataCacheEntry

type MetadataCacheEntry struct {
}

MetadataCacheEntry for compatibility

type MetadataCacheResilienceConfig

type MetadataCacheResilienceConfig struct {
	SecurityCriticalFields         []string
	InitialGracePeriod             time.Duration
	ExtendedGracePeriod            time.Duration
	MaxGracePeriod                 time.Duration
	SecurityCriticalMaxGracePeriod time.Duration
	EnableProgressiveGracePeriod   bool
}

MetadataCacheResilienceConfig defines resilience settings for metadata cache

func DefaultMetadataCacheResilienceConfig

func DefaultMetadataCacheResilienceConfig() MetadataCacheResilienceConfig

DefaultMetadataCacheResilienceConfig returns the default metadata cache resilience configuration

func (MetadataCacheResilienceConfig) GetEffectiveMaxGracePeriod

func (config MetadataCacheResilienceConfig) GetEffectiveMaxGracePeriod(fieldName string) time.Duration

GetEffectiveMaxGracePeriod returns the effective maximum grace period for a field considering Allan's security limits

func (MetadataCacheResilienceConfig) IsSecurityCriticalField

func (config MetadataCacheResilienceConfig) IsSecurityCriticalField(fieldName string) bool

IsSecurityCriticalField checks if a metadata field is security-critical

type MetadataSnapshot

type MetadataSnapshot struct {
	IssuerURL        string
	JWKSURL          string
	TokenURL         string
	AuthURL          string
	RevocationURL    string
	EndSessionURL    string
	IntrospectionURL string
	RegistrationURL  string
}

TraefikOidc is the main middleware struct that implements OIDC authentication for Traefik. It integrates with various OIDC providers, manages sessions, caches tokens, and handles the complete authentication flow. It's designed to work seamlessly with Traefik's plugin system and provides flexible configuration options. MetadataSnapshot is an immutable bundle of provider-metadata URLs that the plugin needs on the hot request path. Published atomically via TraefikOidc.metadataSnapshot; readers do exactly one atomic.Value.Load to access all fields. Replaces 3 per-request metadataMu.RLock acquisitions in middleware.ServeHTTP + token_manager paths, each of which paid 1-5ms of Yaegi-dispatch overhead.

The fields are a strict subset of the metadataMu-guarded TraefikOidc fields; the legacy fields are still written under metadataMu for less-frequent code paths that have not been migrated.

type OIDCError

type OIDCError struct {
	Cause   error
	Context map[string]interface{}
	Code    string
	Message string
}

OIDCError represents OIDC-specific errors with context information. It provides structured error reporting for authentication and authorization failures.

func NewOIDCError

func NewOIDCError(code, message string, cause error) *OIDCError

NewOIDCError creates a new OIDC error with context.

func (*OIDCError) Error

func (e *OIDCError) Error() string

Error returns the string representation of the OIDC error. Implements the error interface.

func (*OIDCError) Unwrap

func (e *OIDCError) Unwrap() error

Unwrap returns the underlying error for error chain unwrapping.

func (*OIDCError) WithContext

func (e *OIDCError) WithContext(key string, value interface{}) *OIDCError

WithContext adds context information to the OIDC error.

type OptimizedCache

type OptimizedCache = CacheInterfaceWrapper

OptimizedCache is an alias for backward compatibility

type OptimizedCacheConfig

type OptimizedCacheConfig = UniversalCacheConfig

OptimizedCacheConfig for backward compatibility

type OptimizedMiddlewareConfig

type OptimizedMiddlewareConfig struct {
	// DelayBackgroundTasks defers starting background tasks until needed
	DelayBackgroundTasks bool
	// ReducedCleanupIntervals uses longer intervals to reduce CPU/memory overhead
	ReducedCleanupIntervals bool
	// AggressiveConnectionCleanup closes idle connections more frequently
	AggressiveConnectionCleanup bool
	// MinimalCacheSize uses smaller cache limits to reduce memory footprint
	MinimalCacheSize bool
}

OptimizedMiddlewareConfig provides configuration options for memory-optimized middleware. These settings help reduce memory usage and prevent leaks in resource-constrained environments.

func DefaultOptimizedConfig

func DefaultOptimizedConfig() *OptimizedMiddlewareConfig

DefaultOptimizedConfig returns a configuration optimized for low memory usage. All optimization features are enabled to minimize memory footprint and prevent leaks.

type PerformanceTestHelper

type PerformanceTestHelper struct {
	// contains filtered or unexported fields
}

PerformanceTestHelper provides utilities for performance testing

func NewPerformanceTestHelper

func NewPerformanceTestHelper() *PerformanceTestHelper

NewPerformanceTestHelper creates a new performance test helper

func (*PerformanceTestHelper) GetAverageTime

func (h *PerformanceTestHelper) GetAverageTime() time.Duration

GetAverageTime returns the average execution time

func (*PerformanceTestHelper) GetPercentile

func (h *PerformanceTestHelper) GetPercentile(percentile float64) time.Duration

GetPercentile returns the nth percentile of execution times

func (*PerformanceTestHelper) Measure

func (h *PerformanceTestHelper) Measure(fn func()) time.Duration

Measure measures the execution time of a function

func (*PerformanceTestHelper) Reset

func (h *PerformanceTestHelper) Reset()

Reset clears all performance samples

type ProfilingConfig

type ProfilingConfig struct {
	SnapshotInterval           time.Duration
	LeakThresholdMB            uint64
	MaxSnapshots               int
	MonitoringInterval         time.Duration
	EnableHeapProfiling        bool
	EnableGoroutineProfiling   bool
	EnableContinuousMonitoring bool
}

ProfilingConfig contains configuration parameters for profiling operations. Controls what types of profiling are enabled and how frequently they run.

type ProfilingManager

type ProfilingManager struct {
	// contains filtered or unexported fields
}

ProfilingManager coordinates memory profiling operations across the application. It manages multiple profiler instances, handles configuration, and provides centralized access to memory monitoring and leak detection capabilities.

func GetGlobalProfilingManager

func GetGlobalProfilingManager() *ProfilingManager

GetGlobalProfilingManager returns the singleton profiling manager

func NewProfilingManager

func NewProfilingManager(logger *Logger) *ProfilingManager

NewProfilingManager creates a new profiling manager with default configuration. Initializes profiling with sensible defaults for production monitoring.

func (*ProfilingManager) AnalyzeLeaks

func (pm *ProfilingManager) AnalyzeLeaks(baseline, current *MemorySnapshot) *LeakAnalysis

AnalyzeLeaks performs leak detection analysis

func (*ProfilingManager) GetCurrentStats

func (pm *ProfilingManager) GetCurrentStats() *runtime.MemStats

GetCurrentStats returns current runtime memory statistics

func (*ProfilingManager) GetRegisteredProfilers

func (pm *ProfilingManager) GetRegisteredProfilers() []string

GetRegisteredProfilers returns list of registered profiler names

func (*ProfilingManager) RegisterProfiler

func (pm *ProfilingManager) RegisterProfiler(name string, profiler MemoryProfiler)

RegisterProfiler registers a component-specific profiler

func (*ProfilingManager) StartProfiling

func (pm *ProfilingManager) StartProfiling(config ProfilingConfig) error

StartProfiling begins memory profiling with specified configuration

func (*ProfilingManager) StopProfiling

func (pm *ProfilingManager) StopProfiling() (*MemorySnapshot, error)

StopProfiling ends memory profiling and returns final snapshot

func (*ProfilingManager) TakeSnapshot

func (pm *ProfilingManager) TakeSnapshot() (*MemorySnapshot, error)

TakeSnapshot captures a comprehensive snapshot of current memory statistics. Includes runtime stats, heap profile, goroutine profile, and custom metrics.

func (*ProfilingManager) UnregisterProfiler

func (pm *ProfilingManager) UnregisterProfiler(name string)

UnregisterProfiler removes a component-specific profiler

type ProviderMetadata

type ProviderMetadata struct {
	Issuer           string   `json:"issuer"`
	AuthURL          string   `json:"authorization_endpoint"`
	TokenURL         string   `json:"token_endpoint"`
	JWKSURL          string   `json:"jwks_uri"`
	RevokeURL        string   `json:"revocation_endpoint"`
	EndSessionURL    string   `json:"end_session_endpoint"`
	IntrospectionURL string   `json:"introspection_endpoint,omitempty"`
	RegistrationURL  string   `json:"registration_endpoint,omitempty"`
	ScopesSupported  []string `json:"scopes_supported,omitempty"`
}

ProviderMetadata represents OIDC provider configuration data. This data is typically retrieved from the provider's .well-known/openid-configuration endpoint and contains essential URLs for authentication, token exchange, and key retrieval.

type RedisConfig

type RedisConfig struct {
	KeyPrefix               string `json:"keyPrefix" yaml:"keyPrefix"`
	Address                 string `json:"address" yaml:"address"`
	Password                string `json:"password,omitempty" yaml:"password,omitempty"`
	CacheMode               string `json:"cacheMode" yaml:"cacheMode"`
	WriteTimeout            int    `json:"writeTimeout" yaml:"writeTimeout"`
	CircuitBreakerThreshold int    `json:"circuitBreakerThreshold" yaml:"circuitBreakerThreshold"`
	ConnectTimeout          int    `json:"connectTimeout" yaml:"connectTimeout"`
	ReadTimeout             int    `json:"readTimeout" yaml:"readTimeout"`
	PoolSize                int    `json:"poolSize" yaml:"poolSize"`
	HealthCheckInterval     int    `json:"healthCheckInterval" yaml:"healthCheckInterval"`
	CircuitBreakerTimeout   int    `json:"circuitBreakerTimeout" yaml:"circuitBreakerTimeout"`
	DB                      int    `json:"db" yaml:"db"`
	HybridL1Size            int    `json:"hybridL1Size" yaml:"hybridL1Size"`
	HybridL1MemoryMB        int64  `json:"hybridL1MemoryMB" yaml:"hybridL1MemoryMB"`
	Enabled                 bool   `json:"enabled" yaml:"enabled"`
	EnableCircuitBreaker    bool   `json:"enableCircuitBreaker" yaml:"enableCircuitBreaker"`
	TLSSkipVerify           bool   `json:"tlsSkipVerify" yaml:"tlsSkipVerify"`
	EnableHealthCheck       bool   `json:"enableHealthCheck" yaml:"enableHealthCheck"`
	EnableTLS               bool   `json:"enableTLS" yaml:"enableTLS"`
}

RedisConfig configures Redis cache backend settings for distributed caching. All fields support both JSON and YAML configuration for compatibility with Traefik's dynamic configuration (labels, YAML files, etc.)

func (*RedisConfig) ApplyDefaults

func (rc *RedisConfig) ApplyDefaults()

ApplyDefaults sets default values for Redis configuration when fields are not explicitly set. This ensures reasonable defaults while allowing full customization through configuration.

func (*RedisConfig) ApplyEnvFallbacks

func (rc *RedisConfig) ApplyEnvFallbacks()

ApplyEnvFallbacks applies environment variable values as fallbacks for empty config fields. This allows environment variables to be used as optional overrides only when the corresponding config field is not set through Traefik's dynamic configuration. The plugin configuration takes precedence over environment variables.

func (RedisConfig) MarshalJSON

func (r RedisConfig) MarshalJSON() ([]byte, error)

MarshalJSON for RedisConfig to redact sensitive fields Rewritten without type aliases for yaegi compatibility

func (RedisConfig) MarshalYAML

func (r RedisConfig) MarshalYAML() (interface{}, error)

MarshalYAML for RedisConfig to redact sensitive fields Rewritten without type aliases for yaegi compatibility

func (*RedisConfig) Validate

func (rc *RedisConfig) Validate() error

isOriginAllowed checks if an origin is in the allowed list Validate checks if the Redis configuration is valid

type RedisCredentialsStore

type RedisCredentialsStore = redisStoreWrapper

RedisCredentialsStore implements DCRCredentialsStore using Redis-backed cache. This storage backend enables sharing DCR credentials across multiple Traefik instances.

func NewRedisCredentialsStore

func NewRedisCredentialsStore(cache *UniversalCache, keyPrefix string, logger *Logger) *RedisCredentialsStore

NewRedisCredentialsStore creates a new Redis-backed credentials store. The cache should be configured with a Redis backend for distributed storage. If keyPrefix is empty, defaults to "dcr:creds:"

type RefreshCircuitBreaker

type RefreshCircuitBreaker struct {
	// contains filtered or unexported fields
}

RefreshCircuitBreaker implements a circuit breaker specifically for refresh operations. All mutable fields are atomic so AllowRequest/RecordSuccess/ RecordFailure run without any mutex. The previous sync.RWMutex.RLock() was taken on every CoordinateRefresh — under Yaegi this added 10-50ms of interpreter dispatch per call, which compounded with attemptsMutex to keep the pod's single CPU core saturated.

func (*RefreshCircuitBreaker) AllowRequest

func (cb *RefreshCircuitBreaker) AllowRequest() bool

AllowRequest reports whether the circuit breaker allows a request. Lock-free.

func (*RefreshCircuitBreaker) GetState

func (cb *RefreshCircuitBreaker) GetState() string

GetState returns the current state of the circuit breaker

func (*RefreshCircuitBreaker) RecordFailure

func (cb *RefreshCircuitBreaker) RecordFailure()

RecordFailure records a failed operation. Lock-free.

func (*RefreshCircuitBreaker) RecordSuccess

func (cb *RefreshCircuitBreaker) RecordSuccess()

RecordSuccess records a successful operation. Lock-free.

type RefreshCircuitBreakerConfig

type RefreshCircuitBreakerConfig struct {
	MaxFailures      int
	OpenDuration     time.Duration
	HalfOpenRequests int
}

RefreshCircuitBreakerConfig configures the refresh circuit breaker

type RefreshCoordinator

type RefreshCoordinator struct {
	// contains filtered or unexported fields
}

RefreshCoordinator prevents duplicate refresh token operations and manages refresh attempt tracking to prevent infinite loops and OOM conditions. It implements request coalescing, rate limiting, and circuit breaking specifically for token refresh operations.

func NewRefreshCoordinator

func NewRefreshCoordinator(config RefreshCoordinatorConfig, logger *Logger) *RefreshCoordinator

NewRefreshCoordinator creates a new refresh coordinator

func (*RefreshCoordinator) CoordinateRefresh

func (rc *RefreshCoordinator) CoordinateRefresh(
	ctx context.Context,
	sessionID string,
	refreshToken string,
	refreshFunc func() (*TokenResponse, error),
) (*TokenResponse, error)

CoordinateRefresh ensures only one refresh operation happens per refresh token and implements request coalescing for concurrent refresh attempts

func (*RefreshCoordinator) GetMetrics

func (rc *RefreshCoordinator) GetMetrics() map[string]interface{}

GetMetrics returns current coordinator metrics

func (*RefreshCoordinator) Shutdown

func (rc *RefreshCoordinator) Shutdown()

Shutdown gracefully shuts down the coordinator. Pending delayed-cleanup timers are NOT canceled explicitly: time.AfterFunc callbacks are tiny (one map LoadAndDelete) and harmless after Shutdown — sync.Map operations remain safe on an unused coordinator until GC.

type RefreshCoordinatorConfig

type RefreshCoordinatorConfig struct {
	// Maximum refresh attempts per session before giving up
	MaxRefreshAttempts int
	// Time window for refresh attempt tracking
	RefreshAttemptWindow time.Duration
	// Cooldown period after max attempts reached
	RefreshCooldownPeriod time.Duration
	// Maximum concurrent refresh operations
	MaxConcurrentRefreshes int
	// Timeout for individual refresh operations
	RefreshTimeout time.Duration
	// Enable memory pressure detection
	EnableMemoryPressureDetection bool
	// Memory pressure threshold (in MB)
	MemoryPressureThresholdMB uint64
	// Cleanup interval for stale entries
	CleanupInterval time.Duration
	// Delay before cleaning up completed refresh operations from deduplication map
	// Set to 0 for immediate cleanup (useful for tests)
	DeduplicationCleanupDelay time.Duration
}

RefreshCoordinatorConfig configures the refresh coordinator behavior

func DefaultRefreshCoordinatorConfig

func DefaultRefreshCoordinatorConfig() RefreshCoordinatorConfig

DefaultRefreshCoordinatorConfig returns production-ready configuration

type RefreshMetrics

type RefreshMetrics struct {
	// contains filtered or unexported fields
}

RefreshMetrics tracks coordinator performance metrics

type ResourceManager

type ResourceManager struct {
	// contains filtered or unexported fields
}

ResourceManager manages shared resources across all middleware instances to prevent duplication and goroutine leaks when Traefik recreates middleware

func GetResourceManager

func GetResourceManager() *ResourceManager

GetResourceManager returns the global singleton ResourceManager instance

func (*ResourceManager) AddReference

func (rm *ResourceManager) AddReference(instanceID string)

AddReference increments the reference count for a given instance

func (*ResourceManager) GetCache

func (rm *ResourceManager) GetCache(key string) interface{}

GetCache returns a shared cache for the given key

func (*ResourceManager) GetGoroutinePool

func (rm *ResourceManager) GetGoroutinePool(key string, maxWorkers int) *GoroutinePool

GetGoroutinePool returns a shared goroutine pool for controlled concurrency

func (*ResourceManager) GetHTTPClient

func (rm *ResourceManager) GetHTTPClient(key string) *http.Client

GetHTTPClient returns a shared HTTP client for the given key

func (*ResourceManager) GetReferenceCount

func (rm *ResourceManager) GetReferenceCount(instanceID string) int32

GetReferenceCount returns the current reference count for an instance

func (*ResourceManager) IsTaskRunning

func (rm *ResourceManager) IsTaskRunning(name string) bool

IsTaskRunning checks if a background task is running

func (*ResourceManager) RegisterBackgroundTask

func (rm *ResourceManager) RegisterBackgroundTask(name string, interval time.Duration, taskFunc func()) error

RegisterBackgroundTask registers a singleton background task

func (*ResourceManager) RemoveReference

func (rm *ResourceManager) RemoveReference(instanceID string)

RemoveReference decrements the reference count and triggers cleanup if needed

func (*ResourceManager) Shutdown

func (rm *ResourceManager) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down all managed resources

func (*ResourceManager) StartBackgroundTask

func (rm *ResourceManager) StartBackgroundTask(name string) error

StartBackgroundTask starts a registered background task

func (*ResourceManager) StopBackgroundTask

func (rm *ResourceManager) StopBackgroundTask(name string) error

StopBackgroundTask stops a running background task

type RetryConfig

type RetryConfig struct {
	// RetryableErrors defines error patterns that should trigger retries
	RetryableErrors []string `json:"retryable_errors"`
	// MaxAttempts is the maximum number of retry attempts
	MaxAttempts int `json:"max_attempts"`
	// InitialDelay is the delay before the first retry
	InitialDelay time.Duration `json:"initial_delay"`
	// MaxDelay caps the maximum delay between retries
	MaxDelay time.Duration `json:"max_delay"`
	// BackoffFactor multiplies delay between attempts (exponential backoff)
	BackoffFactor float64 `json:"backoff_factor"`
	// EnableJitter adds randomness to delays to prevent thundering herd
	EnableJitter bool `json:"enable_jitter"`
}

RetryConfig holds configuration parameters for retry mechanisms. Controls retry behavior including which errors to retry, timing, and backoff strategy.

func DefaultRetryConfig

func DefaultRetryConfig() RetryConfig

DefaultRetryConfig returns sensible default configuration for retry mechanisms. Configured with exponential backoff, jitter, and common retryable error patterns.

func MetadataFetchRetryConfig

func MetadataFetchRetryConfig() RetryConfig

MetadataFetchRetryConfig returns retry configuration optimized for OIDC metadata fetching during startup. Uses more aggressive retry settings to handle the race condition where Traefik initializes the plugin before routes are fully established, or before TLS certificates are properly loaded. See: https://github.com/orangeboyChen/traefikoidc/issues/90

type RetryExecutor

type RetryExecutor struct {
	// BaseRecoveryMechanism provides common functionality
	*BaseRecoveryMechanism
	// contains filtered or unexported fields
}

RetryExecutor implements retry logic with exponential backoff and jitter. It automatically retries failed operations based on configurable error patterns and uses exponential backoff to avoid overwhelming failing services.

func NewRetryExecutor

func NewRetryExecutor(config RetryConfig, logger *Logger) *RetryExecutor

NewRetryExecutor creates a new retry executor with the specified configuration. The executor will retry operations according to the provided configuration.

func (*RetryExecutor) Execute

func (re *RetryExecutor) Execute(ctx context.Context, fn func() error) error

Execute runs the given function with retry logic (for backward compatibility) Execute executes a function with retry logic (backward compatibility). This method provides the same functionality as ExecuteWithContext.

func (*RetryExecutor) ExecuteWithContext

func (re *RetryExecutor) ExecuteWithContext(ctx context.Context, fn func() error) error

ExecuteWithContext executes a function with retry logic and exponential backoff. Retries failed operations based on error patterns and respects context cancellation. Implements the ErrorRecoveryMechanism interface.

func (*RetryExecutor) GetMetrics

func (re *RetryExecutor) GetMetrics() map[string]interface{}

GetMetrics returns metrics about the retry executor GetMetrics returns comprehensive metrics about the retry executor. Includes base metrics plus retry-specific configuration information.

func (*RetryExecutor) IsAvailable

func (re *RetryExecutor) IsAvailable() bool

IsAvailable always returns true for RetryExecutor IsAvailable returns whether the retry executor is available. Always returns true as retry executors don't have availability state.

func (*RetryExecutor) Reset

func (re *RetryExecutor) Reset()

Reset resets the retry executor state Reset clears any internal state of the retry executor. For RetryExecutor, this is primarily a logging operation.

type ScopeFilter

type ScopeFilter struct {
	// contains filtered or unexported fields
}

ScopeFilter handles OAuth scope validation and filtering based on provider capabilities.

func NewScopeFilter

func NewScopeFilter(logger ScopeFilterLogger) *ScopeFilter

NewScopeFilter creates a new ScopeFilter instance.

func (*ScopeFilter) EnsureOpenIDScope

func (sf *ScopeFilter) EnsureOpenIDScope(scopes []string) []string

EnsureOpenIDScope ensures "openid" scope is present in the scope list. This is required for OIDC compliance.

func (*ScopeFilter) FilterSupportedScopes

func (sf *ScopeFilter) FilterSupportedScopes(requestedScopes, supportedScopes []string, providerURL string) []string

FilterSupportedScopes returns the intersection of requested and supported scopes. It preserves the order of requested scopes and returns all requested scopes if supportedScopes is empty (fallback for providers without scopes_supported).

Parameters:

  • requestedScopes: Scopes the application wants to request
  • supportedScopes: Scopes advertised by the provider (from discovery doc)
  • providerURL: Provider URL for logging purposes

Returns:

  • Filtered list of scopes safe to request from the provider

type ScopeFilterLogger

type ScopeFilterLogger interface {
	Debugf(format string, args ...interface{})
	Infof(format string, args ...interface{})
	Errorf(format string, args ...interface{})
}

ScopeFilterLogger interface for dependency injection

type SecurityHeadersConfig

type SecurityHeadersConfig struct {
	CustomHeaders                     map[string]string `json:"customHeaders,omitempty"`
	PermissionsPolicy                 string            `json:"permissionsPolicy,omitempty"`
	Profile                           string            `json:"profile"`
	ContentSecurityPolicy             string            `json:"contentSecurityPolicy,omitempty"`
	CrossOriginResourcePolicy         string            `json:"crossOriginResourcePolicy,omitempty"`
	CrossOriginOpenerPolicy           string            `json:"crossOriginOpenerPolicy,omitempty"`
	CrossOriginEmbedderPolicy         string            `json:"crossOriginEmbedderPolicy,omitempty"`
	FrameOptions                      string            `json:"frameOptions,omitempty"`
	ContentTypeOptions                string            `json:"contentTypeOptions,omitempty"`
	XSSProtection                     string            `json:"xssProtection,omitempty"`
	ReferrerPolicy                    string            `json:"referrerPolicy,omitempty"`
	CORSAllowedHeaders                []string          `json:"corsAllowedHeaders,omitempty"`
	CORSAllowedOrigins                []string          `json:"corsAllowedOrigins,omitempty"`
	CORSAllowedMethods                []string          `json:"corsAllowedMethods,omitempty"`
	StrictTransportSecurityMaxAge     int               `json:"strictTransportSecurityMaxAge"`
	CORSMaxAge                        int               `json:"corsMaxAge"`
	StrictTransportSecurityPreload    bool              `json:"strictTransportSecurityPreload"`
	StrictTransportSecuritySubdomains bool              `json:"strictTransportSecuritySubdomains"`
	CORSEnabled                       bool              `json:"corsEnabled"`
	Enabled                           bool              `json:"enabled"`
	CORSAllowCredentials              bool              `json:"corsAllowCredentials"`
	StrictTransportSecurity           bool              `json:"strictTransportSecurity"`
	DisableServerHeader               bool              `json:"disableServerHeader"`
	DisablePoweredByHeader            bool              `json:"disablePoweredByHeader"`
}

SecurityHeadersConfig configures security headers for the plugin

type SessionChunkManager

type SessionChunkManager struct {
	// contains filtered or unexported fields
}

SessionChunkManager manages session chunks with proper cleanup

func NewSessionChunkManager

func NewSessionChunkManager(maxChunks int) *SessionChunkManager

NewSessionChunkManager creates a new session chunk manager

func (*SessionChunkManager) CleanupChunks

func (m *SessionChunkManager) CleanupChunks(chunks map[int]*sessions.Session, w http.ResponseWriter)

CleanupChunks removes all chunks from a map and expires them if writer is provided

func (*SessionChunkManager) CompactChunks

func (m *SessionChunkManager) CompactChunks(chunks map[int]*sessions.Session) map[int]*sessions.Session

CompactChunks removes nil entries and reindexes chunks

func (*SessionChunkManager) GetChunkCount

func (m *SessionChunkManager) GetChunkCount(chunks map[int]*sessions.Session) int

GetChunkCount returns the number of chunks in a map

func (*SessionChunkManager) SafeSetChunk

func (m *SessionChunkManager) SafeSetChunk(chunks map[int]*sessions.Session, index int, session *sessions.Session) bool

SafeSetChunk safely sets a chunk with bounds checking

func (*SessionChunkManager) ValidateAndCleanChunks

func (m *SessionChunkManager) ValidateAndCleanChunks(chunks map[int]*sessions.Session) bool

ValidateAndCleanChunks validates chunk count and cleans if exceeded

type SessionData

type SessionData struct {
	// contains filtered or unexported fields
}

SessionData represents a user's authentication session with comprehensive token management. It handles main session data and supports large tokens that need to be split across multiple cookies due to browser size limitations. Supports both legacy (separate cookies) and combined (single compressed cookie) storage.

func (*SessionData) Clear

func (sd *SessionData) Clear(r *http.Request, w http.ResponseWriter) error

Clear completely clears all session data and safely returns the session to the pool. It removes all authentication data, expires cookies, and handles panic recovery. This method ensures the SessionData object is always returned to the pool. Parameters:

  • r: The HTTP request context.
  • w: The HTTP response writer for cookie expiration (can be nil).

Returns:

  • An error if session saving fails during cleanup.

func (*SessionData) GetAccessToken

func (sd *SessionData) GetAccessToken() string

GetAccessToken retrieves the user's access token from session storage. It handles both single-cookie storage and chunked storage for large tokens, with automatic decompression if the token was compressed. Returns:

  • The complete, decompressed access token string, or an empty string if not found.

func (*SessionData) GetAuthenticated

func (sd *SessionData) GetAuthenticated() bool

GetAuthenticated returns whether the user is currently authenticated. It checks both the authentication flag and session timeout. Returns:

  • true if the user is authenticated and the session is not expired.
  • false otherwise.

func (*SessionData) GetCSRF

func (sd *SessionData) GetCSRF() string

GetCSRF retrieves the CSRF token for state validation. This token is used to prevent cross-site request forgery attacks during the OIDC authentication flow. Returns:

  • The CSRF token string, or an empty string if not set.

func (*SessionData) GetCodeVerifier

func (sd *SessionData) GetCodeVerifier() string

GetCodeVerifier retrieves the PKCE code verifier. This is used in the PKCE (Proof Key for Code Exchange) flow to enhance security for public clients. Returns:

  • The code verifier string, or an empty string if not set or PKCE is disabled.

func (*SessionData) GetIDToken

func (sd *SessionData) GetIDToken() string

GetIDToken retrieves the user's ID token from session storage. The ID token contains user claims and is used for user identification and authorization decisions. Handles compression and chunking automatically. Returns:

  • The complete, decompressed ID token string, or an empty string if not found.

func (*SessionData) GetIDTokenClaims

func (sd *SessionData) GetIDTokenClaims(parser func(string) (map[string]interface{}, error)) (map[string]interface{}, error)

GetIDTokenClaims returns claims parsed from the current ID token, caching the result on the SessionData so repeated callers within the same request do not re-parse the JWT. The cache is keyed on the ID token string and is cleared when the SessionData is reset (see Reset) or when the ID token changes (e.g. after a refresh).

The parser parameter is typically the TraefikOidc.extractClaimsFunc, which lets tests inject mocks just like the direct call it replaces.

Returns an empty claims map and a nil error when the session has no ID token, matching the existing "no-op" behavior of the caller sites.

func (*SessionData) GetIncomingPath

func (sd *SessionData) GetIncomingPath() string

GetIncomingPath retrieves the original request URI that triggered authentication. This path is used to redirect the user back to their intended destination after successful authentication. Returns:

  • The original request URI string, or an empty string if not set.

func (*SessionData) GetNonce

func (sd *SessionData) GetNonce() string

GetNonce retrieves the nonce for ID token validation. The nonce prevents replay attacks by ensuring ID tokens were issued in response to the specific authentication request. Returns:

  • The nonce string, or an empty string if not set.

func (*SessionData) GetRedirectCount

func (sd *SessionData) GetRedirectCount() int

GetRedirectCount returns the number of redirects in the current authentication flow. STABILITY FIX: Prevents infinite redirect loops by tracking redirect attempts. Returns:

  • The current redirect count, 0 if not set.

func (*SessionData) GetRefreshToken

func (sd *SessionData) GetRefreshToken() string

GetRefreshToken retrieves the user's refresh token from session storage. It handles both single-cookie storage and chunked storage for large tokens, with automatic decompression if the token was compressed. Returns:

  • The complete, decompressed refresh token string, or an empty string if not found.

func (*SessionData) GetRefreshTokenIssuedAt

func (sd *SessionData) GetRefreshTokenIssuedAt() time.Time

GetRefreshTokenIssuedAt retrieves the timestamp when the refresh token was issued/stored. Returns the time when the current refresh token was obtained, or zero time if not available.

func (*SessionData) GetUserIdentifier

func (sd *SessionData) GetUserIdentifier() string

GetUserIdentifier retrieves the authenticated user's identifier as extracted from the configured userIdentifierClaim of the ID token (email, sub, oid, upn, preferred_username, etc.). The value is used for authorization decisions and header injection. Returns:

  • The user identifier string, or an empty string if not set.

func (*SessionData) IncrementRedirectCount

func (sd *SessionData) IncrementRedirectCount()

IncrementRedirectCount increases the redirect counter by one. STABILITY FIX: Prevents infinite redirect loops by tracking successive redirects. Used to detect potential redirect loops and abort authentication if too many occur.

func (*SessionData) IsDirty

func (sd *SessionData) IsDirty() bool

IsDirty returns true if the session data has been modified since it was last loaded or saved. This is used to optimize session saves by only writing when necessary. Returns:

  • true if the session has pending changes, false otherwise.

func (*SessionData) MarkDirty

func (sd *SessionData) MarkDirty()

MarkDirty marks the session as having pending changes that need to be saved. This is used when session data hasn't changed in content but should still trigger a session save (e.g., to ensure the cookie is re-issued).

func (*SessionData) Reset

func (sd *SessionData) Reset()

Reset clears all session data and prepares the SessionData for reuse. It ensures no authentication data persists when the object is reused between different users/sessions.

func (*SessionData) ResetRedirectCount

func (sd *SessionData) ResetRedirectCount()

ResetRedirectCount resets the redirect counter to zero. STABILITY FIX: Prevents infinite redirect loops by clearing the counter when authentication completes successfully or when starting a new flow.

func (*SessionData) ReturnToPool

func (sd *SessionData) ReturnToPool()

ReturnToPool manually returns the session to the object pool. This is used in cleanup paths where Clear() is not called, to prevent memory leaks. It only returns the session if it's not currently in use.

func (*SessionData) Save

func (sd *SessionData) Save(r *http.Request, w http.ResponseWriter) error

Save persists all session data including main session and token chunks. It applies security options, saves all session components, and handles errors gracefully by continuing to save other components even if one fails. Uses combined cookie storage for efficiency when useCombinedStorage is true. Parameters:

  • r: The HTTP request context for security option configuration.
  • w: The HTTP response writer for setting session cookies.

Returns:

  • An error if saving any of the session components fails.

func (*SessionData) SetAccessToken

func (sd *SessionData) SetAccessToken(token string)

SetAccessToken stores an access token with automatic compression and chunking. It validates token format, compresses if beneficial, and splits into chunks if the token exceeds cookie size limits. Includes integrity verification. Parameters:

  • token: The access token string to store.

func (*SessionData) SetAuthenticated

func (sd *SessionData) SetAuthenticated(value bool) error

SetAuthenticated sets the authentication status and manages session security. When setting to true, it generates a new secure session ID and updates timestamps. This prevents session fixation attacks by regenerating the session identifier. Parameters:

  • value: The authentication status to set.

Returns:

  • An error if generating a new session ID fails when setting value to true.

func (*SessionData) SetCSRF

func (sd *SessionData) SetCSRF(token string)

SetCSRF stores the CSRF token for state validation. The token is used to validate the state parameter in OAuth callbacks. Parameters:

  • token: The CSRF token to store.

func (*SessionData) SetCodeVerifier

func (sd *SessionData) SetCodeVerifier(codeVerifier string)

SetCodeVerifier stores the PKCE code verifier. The code verifier is used to generate the code challenge sent to the authorization server and validated during token exchange. Parameters:

  • codeVerifier: The PKCE code verifier string to store.

func (*SessionData) SetIDToken

func (sd *SessionData) SetIDToken(token string)

SetIDToken stores an ID token with automatic compression and chunking. It validates the JWT format, compresses if beneficial, and splits into chunks if the token exceeds cookie size limits. Includes comprehensive validation. Parameters:

  • token: The ID token string to store.

func (*SessionData) SetIncomingPath

func (sd *SessionData) SetIncomingPath(path string)

SetIncomingPath stores the original request URI for post-authentication redirect. This allows the user to be redirected to their originally requested resource after completing the authentication flow. Parameters:

  • path: The original request URI string (e.g., "/protected/resource?id=123").

func (*SessionData) SetNonce

func (sd *SessionData) SetNonce(nonce string)

SetNonce stores the nonce for ID token validation. The nonce will be validated against the nonce claim in received ID tokens. Parameters:

  • nonce: The nonce string to store.

func (*SessionData) SetRefreshToken

func (sd *SessionData) SetRefreshToken(token string)

SetRefreshToken stores a refresh token with automatic compression and chunking. It validates token size, compresses if beneficial, and splits into chunks if needed. Includes comprehensive error checking and integrity verification. Parameters:

  • token: The refresh token string to store.

func (*SessionData) SetUserIdentifier

func (sd *SessionData) SetUserIdentifier(userIdentifier string)

SetUserIdentifier stores the authenticated user's identifier value. Parameters:

  • userIdentifier: The user identifier to store (email, sub, or other claim value).

type SessionEntry

type SessionEntry struct {
	Session      *sessions.Session
	ExpiresAt    time.Time
	LastUsed     time.Time
	SizeEstimate int64 // Estimated memory usage
}

SessionEntry represents a session with expiration tracking

type SessionError

type SessionError struct {
	Cause     error
	Operation string
	Message   string
	SessionID string
}

SessionError represents session-related errors with context. Used for session management, validation, and storage errors.

func NewSessionError

func NewSessionError(operation, message string, cause error) *SessionError

NewSessionError creates a new session error with operation context.

func (*SessionError) Error

func (e *SessionError) Error() string

Error returns the string representation of the session error. Implements the error interface.

func (*SessionError) Unwrap

func (e *SessionError) Unwrap() error

Unwrap returns the underlying error for error chain unwrapping.

func (*SessionError) WithSessionID

func (e *SessionError) WithSessionID(sessionID string) *SessionError

WithSessionID adds session ID to the session error.

type SessionManager

type SessionManager struct {
	// contains filtered or unexported fields
}

SessionManager manages OIDC session state and cookie-based storage. It provides secure session management with support for token compression, chunked storage for large tokens, session pooling for performance, session object reuse and supports both HTTP and HTTPS schemes.

func NewSessionManager

func NewSessionManager(encryptionKey string, forceHTTPS bool, cookieDomain string, cookiePrefix string, sessionMaxAge time.Duration, logger *Logger) (*SessionManager, error)

NewSessionManager creates a new SessionManager instance with secure defaults. It initializes the cookie store with encryption, sets up session pooling, and configures chunk management for large tokens. Parameters:

  • encryptionKey: The key for encrypting session cookies (minimum 32 bytes).
  • forceHTTPS: Whether to force HTTPS-only cookies regardless of request scheme.
  • cookieDomain: The domain for session cookies (empty for auto-detection).
  • cookiePrefix: Prefix for session cookie names (empty for default "_oidc_raczylo_").
  • sessionMaxAge: Maximum session age duration (0 for default 24 hours).
  • logger: Logger instance for debug and error logging.

Returns:

  • The configured SessionManager instance.
  • An error if the encryption key does not meet minimum length requirements.

func (*SessionManager) CleanupOldCookies

func (sm *SessionManager) CleanupOldCookies(w http.ResponseWriter, r *http.Request)

CleanupOldCookies removes stale session cookies from the client browser. This method handles cleanup of cookies that may exist with different domain configurations, ensuring clean state when domain settings change. It removes cookies with various domain variations to ensure cleanup after configuration changes. Parameters:

  • w: The HTTP response writer for setting cookie deletion headers.
  • r: The HTTP request containing cookies to examine and clean up.

func (*SessionManager) EnhanceSessionSecurity

func (sm *SessionManager) EnhanceSessionSecurity(options *sessions.Options, r *http.Request) *sessions.Options

EnhanceSessionSecurity applies additional security measures to session options. It configures secure cookies, domain detection, SameSite policies, and adapts security settings based on request context and client characteristics. Parameters:

  • options: The base session options to enhance (can be nil).
  • r: The HTTP request context for security decisions.

Returns:

  • Enhanced sessions.Options with additional security measures.

func (*SessionManager) GetCookiePrefix

func (sm *SessionManager) GetCookiePrefix() string

GetCookiePrefix returns the cookie prefix used for all OIDC session cookies.

func (*SessionManager) GetSession

func (sm *SessionManager) GetSession(r *http.Request) (*SessionData, error)

GetSession retrieves or creates session data from the HTTP request. It first tries to load from combined cookies (new format), falling back to legacy cookies if combined cookies don't exist. Performs validation and timeout checks. The returned session must be explicitly returned to the pool by calling returnToPoolSafely() to prevent memory leaks. MEMORY LEAK FIX: Session is NOT returned to pool here - caller must call ReturnToPool() when done. Parameters:

  • r: The HTTP request containing session cookies.

Returns:

  • The loaded SessionData instance.
  • An error if session loading or validation fails.

func (*SessionManager) GetSessionMetrics

func (sm *SessionManager) GetSessionMetrics() map[string]interface{}

GetSessionMetrics returns metrics about session management for monitoring purposes. It provides information about session configuration, security settings, and internal state for debugging and monitoring. Returns:

  • A map containing session metrics and configuration information.

func (*SessionManager) GetSessionStats

func (sm *SessionManager) GetSessionStats() map[string]interface{}

GetSessionStats returns statistics about session management

func (*SessionManager) PeriodicChunkCleanup

func (sm *SessionManager) PeriodicChunkCleanup()

PeriodicChunkCleanup performs comprehensive session maintenance and cleanup. It cleans up orphaned token chunks, expired sessions, and unused pool objects. This helps maintain performance and prevent cookie accumulation in client browsers.

func (*SessionManager) Shutdown

func (sm *SessionManager) Shutdown() error

Shutdown gracefully shuts down the SessionManager and all its background tasks

func (*SessionManager) ValidateSessionHealth

func (sm *SessionManager) ValidateSessionHealth(sessionData *SessionData) error

ValidateSessionHealth performs comprehensive validation of session integrity. It checks authentication state, validates token formats, and detects potential tampering or corruption in session data. Parameters:

  • sessionData: The session data to validate.

Returns:

  • An error describing any validation failures, nil if session is healthy.

type SessionPoolProfiler

type SessionPoolProfiler struct {
	// contains filtered or unexported fields
}

SessionPoolProfiler monitors session pool memory usage

func NewSessionPoolProfiler

func NewSessionPoolProfiler(sm *SessionManager, logger *Logger) *SessionPoolProfiler

NewSessionPoolProfiler creates a new session pool profiler

func (*SessionPoolProfiler) AnalyzeLeaks

func (spp *SessionPoolProfiler) AnalyzeLeaks(baseline, current *MemorySnapshot) *LeakAnalysis

AnalyzeLeaks analyzes session pool for leaks

func (*SessionPoolProfiler) GetCurrentStats

func (spp *SessionPoolProfiler) GetCurrentStats() *runtime.MemStats

GetCurrentStats returns current memory statistics

func (*SessionPoolProfiler) StartProfiling

func (spp *SessionPoolProfiler) StartProfiling(config ProfilingConfig) error

StartProfiling begins profiling (no-op for session pools)

func (*SessionPoolProfiler) StopProfiling

func (spp *SessionPoolProfiler) StopProfiling() (*MemorySnapshot, error)

StopProfiling ends profiling (no-op for session pools)

func (*SessionPoolProfiler) TakeSnapshot

func (spp *SessionPoolProfiler) TakeSnapshot() (*MemorySnapshot, error)

TakeSnapshot captures session pool memory statistics

type ShardedCache

type ShardedCache struct {
	// contains filtered or unexported fields
}

ShardedCache provides a thread-safe cache with sharded locks to reduce contention. Instead of a single global mutex, it distributes entries across multiple shards, each with its own mutex. This dramatically reduces lock contention under high load.

func NewShardedCache

func NewShardedCache(numShards int, maxSize int) *ShardedCache

NewShardedCache creates a new sharded cache with the specified number of shards. More shards = less contention but more memory overhead. Recommended: 32-256 shards depending on expected concurrency.

func (*ShardedCache) Cleanup

func (c *ShardedCache) Cleanup()

Cleanup removes all expired items from all shards. Call this periodically to prevent memory growth.

func (*ShardedCache) Clear

func (c *ShardedCache) Clear()

Clear removes all items from all shards.

func (*ShardedCache) Delete

func (c *ShardedCache) Delete(key string)

Delete removes an item from the cache.

func (*ShardedCache) Exists

func (c *ShardedCache) Exists(key string) bool

Exists checks if a key exists in the cache and is not expired.

func (*ShardedCache) Get

func (c *ShardedCache) Get(key string) (interface{}, bool)

Get retrieves an item from the cache. Returns the value and true if found and not expired, nil and false otherwise.

func (*ShardedCache) Set

func (c *ShardedCache) Set(key string, value interface{}, ttl time.Duration)

Set adds or updates an item in the cache with a TTL. If ttl is 0 or negative, the item never expires.

func (*ShardedCache) ShardStats

func (c *ShardedCache) ShardStats() []int

ShardStats returns statistics about each shard for debugging/monitoring.

func (*ShardedCache) Size

func (c *ShardedCache) Size() int

Size returns the total number of items across all shards.

type SharedTransportPool

type SharedTransportPool struct {
	// contains filtered or unexported fields
}

SharedTransportPool manages a pool of shared HTTP transports to prevent connection exhaustion

func GetGlobalTransportPool

func GetGlobalTransportPool() *SharedTransportPool

GetGlobalTransportPool returns the singleton transport pool instance

func (*SharedTransportPool) Cleanup

func (p *SharedTransportPool) Cleanup()

Cleanup closes all transports and stops the cleanup goroutine

func (*SharedTransportPool) GetOrCreateTransport

func (p *SharedTransportPool) GetOrCreateTransport(config HTTPClientConfig) *http.Transport

GetOrCreateTransport gets or creates a shared transport with the given config

func (*SharedTransportPool) ReleaseTransport

func (p *SharedTransportPool) ReleaseTransport(transport *http.Transport)

ReleaseTransport decrements the reference count for a transport

type SimplifiedSessionData

type SimplifiedSessionData struct {
	// contains filtered or unexported fields
}

SimplifiedSessionData represents a simplified session structure with fewer references

func NewSimplifiedSessionData

func NewSimplifiedSessionData() *SimplifiedSessionData

NewSimplifiedSessionData creates a new simplified session data structure

func (*SimplifiedSessionData) Clear

func (s *SimplifiedSessionData) Clear()

Clear clears all session data

func (*SimplifiedSessionData) GetToken

func (s *SimplifiedSessionData) GetToken(name string) (string, bool)

GetToken gets a token value

func (*SimplifiedSessionData) SetToken

func (s *SimplifiedSessionData) SetToken(name, value string)

SetToken sets a token value

type TableTestCase

type TableTestCase struct {
	Input         interface{}
	Expected      interface{}
	ExpectedError error
	Setup         func(*testing.T) error
	Teardown      func(*testing.T) error
	Name          string
	Description   string
	SkipReason    string
	Tags          []string
	Timeout       time.Duration
	Parallel      bool
}

TableTestCase represents a standardized test case structure

type TaskCircuitBreaker

type TaskCircuitBreaker struct {
	// contains filtered or unexported fields
}

TaskCircuitBreaker implements circuit breaker pattern for background task creation It limits concurrent task execution and tracks failures to prevent system overload

func NewTaskCircuitBreaker

func NewTaskCircuitBreaker(failureThreshold int32, timeout time.Duration, logger *Logger) *TaskCircuitBreaker

NewTaskCircuitBreaker creates a new circuit breaker for background tasks with concurrency limiting capability

func (*TaskCircuitBreaker) CanCreateTask

func (cb *TaskCircuitBreaker) CanCreateTask(taskName string) error

CanCreateTask checks if a new task can be created based on circuit breaker state and concurrency limits

func (*TaskCircuitBreaker) OnTaskComplete

func (cb *TaskCircuitBreaker) OnTaskComplete(taskName string)

OnTaskComplete records a task completing execution

func (*TaskCircuitBreaker) OnTaskFailure

func (cb *TaskCircuitBreaker) OnTaskFailure(taskName string, err error)

OnTaskFailure records a task creation failure

func (*TaskCircuitBreaker) OnTaskStart

func (cb *TaskCircuitBreaker) OnTaskStart(taskName string)

OnTaskStart records a task starting execution

func (*TaskCircuitBreaker) OnTaskSuccess

func (cb *TaskCircuitBreaker) OnTaskSuccess(taskName string)

OnTaskSuccess records a successful task creation (legacy compatibility)

type TaskMemoryMonitor

type TaskMemoryMonitor struct {
	// contains filtered or unexported fields
}

TaskMemoryMonitor provides system memory monitoring and leak detection capabilities for task registry

func GetGlobalTaskMemoryMonitor

func GetGlobalTaskMemoryMonitor(logger *Logger) *TaskMemoryMonitor

GetGlobalTaskMemoryMonitor returns the global singleton TaskMemoryMonitor instance

func NewTaskMemoryMonitor deprecated

func NewTaskMemoryMonitor(logger *Logger, registry *TaskRegistry) *TaskMemoryMonitor

NewTaskMemoryMonitor creates a new memory monitor for task registry.

Deprecated: Use GetGlobalTaskMemoryMonitor instead for singleton behavior.

func (*TaskMemoryMonitor) ForceGC

func (mm *TaskMemoryMonitor) ForceGC() (before, after TaskMemoryStats, err error)

ForceGC triggers garbage collection and returns stats before/after

func (*TaskMemoryMonitor) GetCurrentStats

func (mm *TaskMemoryMonitor) GetCurrentStats() (TaskMemoryStats, error)

GetCurrentStats returns the latest memory statistics

func (*TaskMemoryMonitor) GetStatsHistory

func (mm *TaskMemoryMonitor) GetStatsHistory() []TaskMemoryStats

GetStatsHistory returns a copy of the memory statistics history

func (*TaskMemoryMonitor) Start

func (mm *TaskMemoryMonitor) Start(interval time.Duration) error

Start begins memory monitoring

func (*TaskMemoryMonitor) Stop

func (mm *TaskMemoryMonitor) Stop()

Stop stops memory monitoring

type TaskMemoryStats

type TaskMemoryStats struct {
	Timestamp    time.Time
	Goroutines   int
	HeapAlloc    uint64
	HeapSys      uint64
	NumGC        uint32
	AllocObjects uint64
	FreeObjects  uint64
	ActiveTasks  int
}

TaskMemoryStats represents a snapshot of memory usage statistics for task registry

type TaskRegistry

type TaskRegistry struct {
	// contains filtered or unexported fields
}

TaskRegistry maintains a registry of all active background tasks to prevent duplicates

func GetGlobalTaskRegistry

func GetGlobalTaskRegistry() *TaskRegistry

GetGlobalTaskRegistry returns the singleton task registry

func (*TaskRegistry) CreateSingletonTask

func (tr *TaskRegistry) CreateSingletonTask(name string, interval time.Duration,
	taskFunc func(), logger *Logger, wg *sync.WaitGroup) (*BackgroundTask, error)

CreateSingletonTask creates or returns existing singleton task with strict enforcement

func (*TaskRegistry) GetTask

func (tr *TaskRegistry) GetTask(name string) (*BackgroundTask, bool)

GetTask returns a task from the registry

func (*TaskRegistry) GetTaskCount

func (tr *TaskRegistry) GetTaskCount() int

GetTaskCount returns the number of active tasks

func (*TaskRegistry) RegisterTask

func (tr *TaskRegistry) RegisterTask(name string, task *BackgroundTask) error

RegisterTask registers a new background task with the registry and wraps the task function to track execution

func (*TaskRegistry) StopAllTasks

func (tr *TaskRegistry) StopAllTasks()

StopAllTasks stops all registered background tasks

func (*TaskRegistry) UnregisterTask

func (tr *TaskRegistry) UnregisterTask(name string)

UnregisterTask removes a task from the registry

type TemplatedHeader

type TemplatedHeader struct {
	// Name is the HTTP header name to set (e.g., "X-Forwarded-Email")
	Name string `json:"name"`

	// Value is the template string for the header value
	// Example: "{{.claims.email}}", "Bearer {{.accessToken}}"
	Value string `json:"value"`
}

TemplatedHeader represents a custom HTTP header with a templated value. The value can contain template expressions that will be evaluated for each authenticated request, such as {{.claims.email}} or {{.accessToken}}.

type TestCacheEntry

type TestCacheEntry struct {
	ExpiresAt time.Time
	Metadata  map[string]interface{}
	Token     string
}

TestCacheEntry represents a cached token entry for testing

type TestConfig

type TestConfig struct {
	MemoryThreshold  float64
	MaxConcurrency   int
	MaxIterations    int
	DefaultTimeout   time.Duration
	GoroutineGrowth  int
	CacheSize        int
	CleanupInterval  time.Duration
	LongTests        bool
	QuickMode        bool
	ExtendedTests    bool
	MemoryStressTest bool
	ConcurrencyTest  bool
	LeakDetection    bool
}

TestConfig manages test execution configuration and performance settings

func GetTestConfig

func GetTestConfig() *TestConfig

GetTestConfig returns the global test configuration

func NewTestConfig

func NewTestConfig() *TestConfig

NewTestConfig creates a test configuration based on flags and environment

func (*TestConfig) AdjustConcurrencyParams

func (c *TestConfig) AdjustConcurrencyParams(requested int) int

AdjustConcurrencyParams adjusts concurrency parameters for tests

func (*TestConfig) AdjustMemoryLeakTestCase

func (c *TestConfig) AdjustMemoryLeakTestCase(testCase *MemoryLeakTestCase)

AdjustMemoryLeakTestCase adjusts a memory leak test case based on configuration

func (*TestConfig) EnableExtendedTests

func (c *TestConfig) EnableExtendedTests()

EnableExtendedTests switches to extended test mode

func (*TestConfig) EnableLongTests

func (c *TestConfig) EnableLongTests()

EnableLongTests switches to long-running test mode

func (*TestConfig) EnableStressTests

func (c *TestConfig) EnableStressTests()

EnableStressTests switches to stress test mode

func (*TestConfig) GetCacheSize

func (c *TestConfig) GetCacheSize() int

GetCacheSize returns appropriate cache size for tests

func (*TestConfig) GetCleanupInterval

func (c *TestConfig) GetCleanupInterval() time.Duration

GetCleanupInterval returns appropriate cleanup interval for tests

func (*TestConfig) ShouldSkipTest

func (c *TestConfig) ShouldSkipTest(t *testing.T, testType TestType) bool

ShouldSkipTest determines if a test should be skipped based on config

type TestDataFactory

type TestDataFactory struct{}

TestDataFactory provides utilities for generating test data

func NewTestDataFactory

func NewTestDataFactory() *TestDataFactory

NewTestDataFactory creates a new test data factory

func (*TestDataFactory) GenerateRandomString

func (f *TestDataFactory) GenerateRandomString(length int) string

GenerateRandomString generates a random string of specified length

func (*TestDataFactory) GenerateTestHTTPRequest

func (f *TestDataFactory) GenerateTestHTTPRequest() *http.Request

GenerateTestHTTPRequest generates a test HTTP request

func (*TestDataFactory) GenerateTestSession

func (f *TestDataFactory) GenerateTestSession() *UnifiedMockSession

GenerateTestSession generates a test session with random data

func (*TestDataFactory) GenerateTestToken

func (f *TestDataFactory) GenerateTestToken() string

GenerateTestToken generates a test JWT-like token

type TestSuiteRunner

type TestSuiteRunner struct {
	// contains filtered or unexported fields
}

TestSuiteRunner provides utilities for running table-driven tests

func NewTestSuiteRunner

func NewTestSuiteRunner() *TestSuiteRunner

NewTestSuiteRunner creates a new test suite runner

func (*TestSuiteRunner) RunMemoryLeakTests

func (r *TestSuiteRunner) RunMemoryLeakTests(t *testing.T, tests []MemoryLeakTestCase)

RunMemoryLeakTests executes memory leak test cases

func (*TestSuiteRunner) RunTests

func (r *TestSuiteRunner) RunTests(t *testing.T, tests []TableTestCase)

RunTests executes a table of test cases

func (*TestSuiteRunner) SetAfterEach

func (r *TestSuiteRunner) SetAfterEach(fn func(*testing.T))

SetAfterEach sets a function to run after each test

func (*TestSuiteRunner) SetBeforeEach

func (r *TestSuiteRunner) SetBeforeEach(fn func(*testing.T))

SetBeforeEach sets a function to run before each test

func (*TestSuiteRunner) SetParallel

func (r *TestSuiteRunner) SetParallel(parallel bool)

SetParallel enables or disables parallel test execution

func (*TestSuiteRunner) SetTimeout

func (r *TestSuiteRunner) SetTimeout(timeout time.Duration)

SetTimeout sets the default timeout for tests

type TestType

type TestType int

TestType represents different categories of tests

const (
	TestTypeQuick TestType = iota
	TestTypeExtended
	TestTypeLong
	TestTypeMemoryStress
	TestTypeConcurrencyStress
	TestTypeLeakDetection
)

func (TestType) String

func (tt TestType) String() string

String returns string representation of test type

type TokenCache

type TokenCache struct {
	// contains filtered or unexported fields
}

TokenCache provides a specialized cache for JWT tokens and their parsed claims. It wraps the UniversalCache with token-specific operations.

func NewTokenCache

func NewTokenCache() *TokenCache

NewTokenCache creates and initializes a new TokenCache. It uses the global cache manager to ensure singleton behavior.

func (*TokenCache) Cleanup

func (tc *TokenCache) Cleanup()

Cleanup removes expired entries from the token cache. This is a no-op as cleanup is handled internally by UniversalCache.

func (*TokenCache) Clear

func (tc *TokenCache) Clear()

Clear removes all items from the cache

func (*TokenCache) Close

func (tc *TokenCache) Close()

Close stops the cleanup goroutine and releases resources. This is a no-op as the cache is managed globally.

func (*TokenCache) Delete

func (tc *TokenCache) Delete(token string)

Delete removes a token from the cache. Parameters:

  • token: The raw token string to remove from the cache

func (*TokenCache) Get

func (tc *TokenCache) Get(token string) (map[string]interface{}, bool)

Get retrieves cached claims for a token. Parameters:

  • token: The JWT token string to look up

Returns:

  • map[string]interface{}: The cached claims if found
  • A boolean indicating whether the token was found in the cache (true if found, false otherwise)

func (*TokenCache) Set

func (tc *TokenCache) Set(token string, claims map[string]interface{}, expiration time.Duration)

Set stores parsed token claims in the cache with expiration. The token is prefixed to prevent collisions with other cache entries. Parameters:

  • token: The JWT token string (used as cache key)
  • claims: Parsed claims from the token
  • expiration: The duration for which the cache entry should be valid

type TokenCacheConfig

type TokenCacheConfig struct {
	BlacklistTTL        time.Duration
	RefreshTokenTTL     time.Duration
	EnableTokenRotation bool
}

TokenCacheConfig provides token-specific cache configuration

type TokenConfig

type TokenConfig struct {
	Type              string
	MinLength         int
	MaxLength         int
	MaxChunks         int
	MaxChunkSize      int
	AllowOpaqueTokens bool
	RequireJWTFormat  bool
}

TokenConfig defines validation and storage parameters for different token types. It specifies size limits, format requirements, and security constraints to ensure tokens can be safely stored in browser cookies while maintaining security.

type TokenError

type TokenError struct {
	Cause     error
	TokenType string
	Reason    string
	Message   string
}

TokenError represents token-related errors with validation context. Used for JWT validation, token refresh, and token format errors.

func NewTokenError

func NewTokenError(tokenType, reason, message string, cause error) *TokenError

NewTokenError creates a new token error with type and reason.

func (*TokenError) Error

func (e *TokenError) Error() string

Error returns the string representation of the token error. Implements the error interface.

func (*TokenError) Unwrap

func (e *TokenError) Unwrap() error

Unwrap returns the underlying error for error chain unwrapping.

type TokenExchanger

type TokenExchanger interface {
	ExchangeCodeForToken(ctx context.Context, grantType string, codeOrToken string, redirectURL string, codeVerifier string) (*TokenResponse, error)
	GetNewTokenWithRefreshToken(refreshToken string) (*TokenResponse, error)
	RevokeTokenWithProvider(token, tokenType string) error
}

TokenExchanger interface defines OAuth 2.0 and OpenID Connect token exchange capabilities. Implementations should handle authorization code exchange, refresh tokens, and revocation according to the OAuth 2.0 and OpenID Connect specifications.

type TokenResilienceConfig

type TokenResilienceConfig struct {
	MetadataCacheConfig   MetadataCacheResilienceConfig
	RetryConfig           RetryConfig
	CircuitBreakerConfig  CircuitBreakerConfig
	CircuitBreakerEnabled bool
	RetryEnabled          bool
}

TokenResilienceConfig centralizes resilience configuration for token operations

func DefaultTokenResilienceConfig

func DefaultTokenResilienceConfig() TokenResilienceConfig

DefaultTokenResilienceConfig returns the default resilience configuration for token operations

type TokenResilienceManager

type TokenResilienceManager struct {
	// contains filtered or unexported fields
}

TokenResilienceManager coordinates resilience mechanisms for token operations

func NewTokenResilienceManager

func NewTokenResilienceManager(config TokenResilienceConfig, logger *Logger) *TokenResilienceManager

NewTokenResilienceManager creates a new token resilience manager

func (*TokenResilienceManager) ExecuteTokenExchange

func (trm *TokenResilienceManager) ExecuteTokenExchange(ctx context.Context, t *TraefikOidc, grantType, codeOrToken, redirectURL, codeVerifier string) (*TokenResponse, error)

ExecuteTokenExchange executes token exchange with resilience

func (*TokenResilienceManager) ExecuteTokenOperation

func (trm *TokenResilienceManager) ExecuteTokenOperation(ctx context.Context, operation string, fn func() error) error

ExecuteTokenOperation executes a token operation with full resilience support

func (*TokenResilienceManager) ExecuteTokenRefresh

func (trm *TokenResilienceManager) ExecuteTokenRefresh(ctx context.Context, t *TraefikOidc, refreshToken string) (*TokenResponse, error)

ExecuteTokenRefresh executes token refresh with resilience

func (*TokenResilienceManager) GetMetrics

func (trm *TokenResilienceManager) GetMetrics() map[string]interface{}

GetMetrics returns metrics for all resilience mechanisms

func (*TokenResilienceManager) Reset

func (trm *TokenResilienceManager) Reset()

Reset resets all resilience mechanisms

type TokenResponse

type TokenResponse struct {
	// IDToken contains the OpenID Connect identity token (JWT)
	IDToken string `json:"id_token"`
	// AccessToken is the OAuth 2.0 access token for API access
	AccessToken string `json:"access_token"`
	// RefreshToken allows obtaining new tokens when the access token expires
	RefreshToken string `json:"refresh_token"`
	// TokenType specifies the token type (typically "Bearer")
	TokenType string `json:"token_type"`
	// ExpiresIn indicates token lifetime in seconds
	ExpiresIn int `json:"expires_in"`
}

TokenResponse represents the standard OAuth 2.0/OIDC token response. It contains the tokens and metadata returned by the authorization server during code exchange or token refresh operations.

type TokenRetrievalResult

type TokenRetrievalResult struct {
	Error error
	Token string
}

TokenRetrievalResult represents the outcome of a token retrieval operation. It contains either the successfully retrieved token or an error describing what went wrong during retrieval.

type TokenVerifier

type TokenVerifier interface {
	VerifyToken(token string) error
}

TokenVerifier interface defines token verification capabilities. Implementations should validate token format, signature, and claims.

type TraefikOidc

type TraefikOidc struct {
	// contains filtered or unexported fields
}

func NewWithContext

func NewWithContext(ctx context.Context, config *Config, next http.Handler, name string) (*TraefikOidc, error)

NewWithContext creates a new TraefikOidc middleware instance with proper context handling. This is the preferred constructor that ensures proper goroutine lifecycle management.

func (*TraefikOidc) Close

func (t *TraefikOidc) Close() error

Close gracefully shuts down the TraefikOidc middleware instance. It cancels contexts, stops background goroutines, closes HTTP connections, cleans up caches, and releases all resources. Safe to call multiple times. Returns:

  • An error if shutdown times out or resource cleanup fails.

func (*TraefikOidc) ExchangeCodeForToken

func (t *TraefikOidc) ExchangeCodeForToken(ctx context.Context, grantType string, codeOrToken string, redirectURL string, codeVerifier string) (*TokenResponse, error)

ExchangeCodeForToken exchanges an authorization code for tokens. This is a wrapper method that delegates to the internal token exchange logic while still allowing mocking for tests. Parameters:

  • ctx: The request context.
  • grantType: The OAuth 2.0 grant type ("authorization_code").
  • codeOrToken: The authorization code received from the provider.
  • redirectURL: The redirect URI used in the authorization request.
  • codeVerifier: The PKCE code verifier (if PKCE is enabled).

Returns:

  • The token response containing access token, ID token, and refresh token.
  • An error if the token exchange fails.

func (*TraefikOidc) GetNewTokenWithRefreshToken

func (t *TraefikOidc) GetNewTokenWithRefreshToken(refreshToken string) (*TokenResponse, error)

GetNewTokenWithRefreshToken refreshes tokens using a refresh token. This is a wrapper method that delegates to the internal refresh token logic while still allowing mocking for tests. Parameters:

  • refreshToken: The refresh token to use for obtaining new tokens.

Returns:

  • The token response containing new access token, ID token, and potentially new refresh token.
  • An error if the refresh fails.

func (*TraefikOidc) RevokeToken

func (t *TraefikOidc) RevokeToken(token string)

RevokeToken revokes a token locally by adding it to the blacklist cache. It removes the token from the verification cache and adds both the token and its JTI (if present) to the blacklist to prevent future use. Parameters:

  • token: The raw token string to revoke locally.

func (*TraefikOidc) RevokeTokenWithProvider

func (t *TraefikOidc) RevokeTokenWithProvider(token, tokenType string) error

RevokeTokenWithProvider revokes a token with the OIDC provider. It sends a revocation request to the provider's revocation endpoint with proper authentication and error recovery if available. Parameters:

  • token: The token to revoke.
  • tokenType: The type of token ("access_token" or "refresh_token").

Returns:

  • An error if the request fails or the provider returns a non-OK status.

func (*TraefikOidc) ServeHTTP

func (t *TraefikOidc) ServeHTTP(rw http.ResponseWriter, req *http.Request)

ServeHTTP implements the main middleware logic for processing HTTP requests. It handles the complete OIDC authentication flow including:

  • Excluded URL bypass
  • Session validation and management
  • Authentication callback processing
  • Logout handling
  • Token verification and refresh
  • Header injection for authenticated requests

Parameters:

  • rw: The HTTP response writer.
  • req: The incoming HTTP request.

func (*TraefikOidc) VerifyJWTSignatureAndClaims

func (t *TraefikOidc) VerifyJWTSignatureAndClaims(jwt *JWT, token string) error

VerifyJWTSignatureAndClaims verifies JWT signature using provider's public keys and validates standard claims. It retrieves the appropriate public key from the JWKS cache, verifies the token signature, and validates standard OIDC claims like issuer, audience, and expiration. Parameters:

  • jwt: The parsed JWT structure containing header and claims.
  • token: The raw token string for signature verification.

Returns:

  • An error if verification fails (e.g., JWKS retrieval failed, no matching key, signature verification failed, standard claim validation failed), nil if successful.

func (*TraefikOidc) VerifyToken

func (t *TraefikOidc) VerifyToken(token string) error

VerifyToken verifies the validity of an ID token or access token. It performs comprehensive validation including format checks, blacklist verification, signature validation using JWKs, and standard claims validation. It also caches successfully verified tokens to avoid repeated verification. Parameters:

  • token: The JWT token string to verify.

Returns:

  • An error if verification fails (e.g., blacklisted token, invalid format, signature failure, or claims error), nil if verification succeeds.

type UnifiedCache

type UnifiedCache struct {
	*UniversalCache
	// contains filtered or unexported fields
}

UnifiedCache wraps UniversalCache for backward compatibility

func NewUnifiedCache

func NewUnifiedCache(config UniversalCacheConfig) *UnifiedCache

NewUnifiedCache creates a universal cache for backward compatibility

func (*UnifiedCache) SetMaxSize

func (c *UnifiedCache) SetMaxSize(size int)

SetMaxSize sets the maximum cache size

type UnifiedCacheConfig

type UnifiedCacheConfig = UniversalCacheConfig

UnifiedCacheConfig is an alias for backward compatibility

type UnifiedMockSession

type UnifiedMockSession struct {
	// contains filtered or unexported fields
}

UnifiedMockSession provides a comprehensive mock for the Session interface

func NewUnifiedMockSession

func NewUnifiedMockSession() *UnifiedMockSession

NewUnifiedMockSession creates a new mock session with default behavior

func (*UnifiedMockSession) Delete

func (m *UnifiedMockSession) Delete(key string)

func (*UnifiedMockSession) Destroy

func (m *UnifiedMockSession) Destroy() error

func (*UnifiedMockSession) Get

func (m *UnifiedMockSession) Get(key string) (interface{}, bool)

Session interface implementation

func (*UnifiedMockSession) GetCallCount

func (m *UnifiedMockSession) GetCallCount(method string) int64

GetCallCount returns the number of times a method was called

func (*UnifiedMockSession) GetDestroyCount

func (m *UnifiedMockSession) GetDestroyCount() int64

func (*UnifiedMockSession) IsDestroyed

func (m *UnifiedMockSession) IsDestroyed() bool

func (*UnifiedMockSession) Set

func (m *UnifiedMockSession) Set(key string, value interface{})

func (*UnifiedMockSession) SetDelay

func (m *UnifiedMockSession) SetDelay(method string, delay time.Duration)

SetDelay configures the mock to add delay for specific method calls

func (*UnifiedMockSession) SetError

func (m *UnifiedMockSession) SetError(method string, err error)

SetError configures the mock to return an error for specific method calls

type UnifiedMockTokenCache

type UnifiedMockTokenCache struct {
	// contains filtered or unexported fields
}

UnifiedMockTokenCache provides a comprehensive mock for token caching

func NewUnifiedMockTokenCache

func NewUnifiedMockTokenCache() *UnifiedMockTokenCache

NewUnifiedMockTokenCache creates a new mock token cache

func (*UnifiedMockTokenCache) Clear

func (m *UnifiedMockTokenCache) Clear()

func (*UnifiedMockTokenCache) Delete

func (m *UnifiedMockTokenCache) Delete(key string)

func (*UnifiedMockTokenCache) Get

func (m *UnifiedMockTokenCache) Get(key string) (string, bool)

func (*UnifiedMockTokenCache) GetCallCount

func (m *UnifiedMockTokenCache) GetCallCount(method string) int64

GetCallCount returns the number of times a method was called

func (*UnifiedMockTokenCache) Set

func (m *UnifiedMockTokenCache) Set(key, token string, expiry time.Time)

func (*UnifiedMockTokenCache) SetError

func (m *UnifiedMockTokenCache) SetError(method string, err error)

SetError configures the mock to return an error for specific method calls

func (*UnifiedMockTokenCache) SetHitRate

func (m *UnifiedMockTokenCache) SetHitRate(rate float64)

SetHitRate configures the cache hit rate (0.0 to 1.0)

type UnifiedMockTokenVerifier

type UnifiedMockTokenVerifier struct {
	// contains filtered or unexported fields
}

UnifiedMockTokenVerifier provides a comprehensive mock for token verification

func NewUnifiedMockTokenVerifier

func NewUnifiedMockTokenVerifier() *UnifiedMockTokenVerifier

NewUnifiedMockTokenVerifier creates a new mock token verifier

func (*UnifiedMockTokenVerifier) GetCallCount

func (m *UnifiedMockTokenVerifier) GetCallCount(method string) int64

GetCallCount returns the number of times a method was called

func (*UnifiedMockTokenVerifier) SetError

func (m *UnifiedMockTokenVerifier) SetError(method string, err error)

SetError configures the mock to return an error for specific method calls

func (*UnifiedMockTokenVerifier) SetTokenMetadata

func (m *UnifiedMockTokenVerifier) SetTokenMetadata(token string, metadata map[string]interface{})

SetTokenMetadata configures metadata for a token

func (*UnifiedMockTokenVerifier) SetTokenValid

func (m *UnifiedMockTokenVerifier) SetTokenValid(token string, valid bool)

SetTokenValid configures whether a token should be considered valid

func (*UnifiedMockTokenVerifier) SetVerificationFunc

func (m *UnifiedMockTokenVerifier) SetVerificationFunc(fn func(string) error)

SetVerificationFunc allows custom verification logic

func (*UnifiedMockTokenVerifier) VerifyToken

func (m *UnifiedMockTokenVerifier) VerifyToken(token string) error

type UniversalCache

type UniversalCache struct {
	// contains filtered or unexported fields
}

UniversalCache provides a single, unified cache implementation that replaces all other cache types

func NewUniversalCache

func NewUniversalCache(config UniversalCacheConfig) *UniversalCache

NewUniversalCache creates a new universal cache instance

func NewUniversalCacheWithBackend

func NewUniversalCacheWithBackend(config UniversalCacheConfig, cacheBackend backends.CacheBackend) *UniversalCache

NewUniversalCacheWithBackend creates a new universal cache with a specific backend

func (*UniversalCache) ActivateGracePeriod

func (c *UniversalCache) ActivateGracePeriod(key string)

ActivateGracePeriod activates grace period for a specific key (e.g., due to provider outage)

func (*UniversalCache) BlacklistToken

func (c *UniversalCache) BlacklistToken(token string, ttl time.Duration) error

TokenCacheOperations provides token-specific operations

func (*UniversalCache) Cleanup

func (c *UniversalCache) Cleanup()

Cleanup manually triggers cleanup of expired items

func (*UniversalCache) Clear

func (c *UniversalCache) Clear()

Clear removes all items from the cache

func (*UniversalCache) Close

func (c *UniversalCache) Close() error

Close shuts down the cache

func (*UniversalCache) Delete

func (c *UniversalCache) Delete(key string) bool

Delete removes a key from the cache

func (*UniversalCache) Get

func (c *UniversalCache) Get(key string) (interface{}, bool)

Get retrieves a value from the cache

func (*UniversalCache) GetLocal

func (c *UniversalCache) GetLocal(key string) (interface{}, bool)

GetLocal retrieves a value only from the in-memory LRU, never querying the distributed backend. Pair with SetLocal for values that aren't safe to serialize (see SetLocal docstring).

func (*UniversalCache) GetMetrics

func (c *UniversalCache) GetMetrics() map[string]interface{}

GetMetrics returns cache metrics

func (*UniversalCache) IsTokenBlacklisted

func (c *UniversalCache) IsTokenBlacklisted(token string) bool

IsTokenBlacklisted checks if a token is blacklisted

func (*UniversalCache) MemoryUsage

func (c *UniversalCache) MemoryUsage() int64

MemoryUsage returns the current memory usage in bytes

func (*UniversalCache) Mutex

func (c *UniversalCache) Mutex() *sync.RWMutex

Mutex returns the cache mutex for backward compatibility

func (*UniversalCache) Set

func (c *UniversalCache) Set(key string, value interface{}, ttl time.Duration) error

Set stores a value in the cache

func (*UniversalCache) SetLocal

func (c *UniversalCache) SetLocal(key string, value interface{}, ttl time.Duration) error

SetLocal stores a value only in the in-memory LRU, bypassing any distributed backend. Use for values that don't survive JSON round-tripping — interfaces holding concrete crypto keys, *big.Int, or types whose unexported fields yaegi exposes under an X prefix on Marshal. Each replica caches independently; correctness must not depend on cross-replica coherence for these keys.

func (*UniversalCache) SetMaxSize

func (c *UniversalCache) SetMaxSize(newSize int)

SetMaxSize sets the maximum size and evicts items if necessary

func (*UniversalCache) SetWithMetadata

func (c *UniversalCache) SetWithMetadata(key string, value interface{}, ttl time.Duration, metadata map[string]interface{}) error

SetWithMetadata sets a value with additional metadata

func (*UniversalCache) Size

func (c *UniversalCache) Size() int

Size returns the number of items in the cache

func (*UniversalCache) Strategy

func (c *UniversalCache) Strategy() CacheStrategy

Strategy returns the cache strategy for backward compatibility

type UniversalCacheConfig

type UniversalCacheConfig struct {
	Strategy          CacheStrategy
	Logger            *Logger
	JWKConfig         *JWKCacheConfig
	MetadataConfig    *MetadataCacheConfig
	TokenConfig       *TokenCacheConfig
	Type              CacheType
	DefaultTTL        time.Duration
	CleanupInterval   time.Duration
	MaxMemoryBytes    int64
	MaxSize           int
	EnableAutoCleanup bool
	EnableMemoryLimit bool
	EnableMetrics     bool
	EnableCompression bool
	SkipAutoCleanup   bool
}

UniversalCacheConfig provides configuration for the universal cache

func DefaultUnifiedCacheConfig

func DefaultUnifiedCacheConfig() UniversalCacheConfig

DefaultUnifiedCacheConfig returns default config for backward compatibility

type UniversalCacheManager

type UniversalCacheManager struct {
	// contains filtered or unexported fields
}

UniversalCacheManager manages all cache instances using the universal cache It runs a single consolidated cleanup goroutine for all caches, reducing goroutine count and CPU overhead compared to per-cache cleanup routines.

func GetUniversalCacheManager

func GetUniversalCacheManager(logger *Logger) *UniversalCacheManager

GetUniversalCacheManager returns the singleton universal cache manager

func GetUniversalCacheManagerWithConfig

func GetUniversalCacheManagerWithConfig(logger *Logger, redisConfig *RedisConfig) *UniversalCacheManager

GetUniversalCacheManagerWithConfig returns the singleton universal cache manager with Redis configuration

func (*UniversalCacheManager) Close

func (m *UniversalCacheManager) Close() error

Close shuts down all caches and the consolidated cleanup routine

func (*UniversalCacheManager) GetBlacklistCache

func (m *UniversalCacheManager) GetBlacklistCache() *UniversalCache

GetBlacklistCache returns the blacklist cache

func (*UniversalCacheManager) GetDCRCredentialsCache

func (m *UniversalCacheManager) GetDCRCredentialsCache() *UniversalCache

GetDCRCredentialsCache returns the DCR credentials cache for distributed storage

func (*UniversalCacheManager) GetIntrospectionCache

func (m *UniversalCacheManager) GetIntrospectionCache() *UniversalCache

GetIntrospectionCache returns the token introspection cache

func (*UniversalCacheManager) GetJWKCache

func (m *UniversalCacheManager) GetJWKCache() *UniversalCache

GetJWKCache returns the JWK cache

func (*UniversalCacheManager) GetMetadataCache

func (m *UniversalCacheManager) GetMetadataCache() *UniversalCache

GetMetadataCache returns the metadata cache

func (*UniversalCacheManager) GetRefreshResultCache

func (m *UniversalCacheManager) GetRefreshResultCache() *UniversalCache

GetRefreshResultCache returns the short-lived refresh-result cache used to coalesce refresh-token grants across Traefik replicas.

func (*UniversalCacheManager) GetSessionInvalidationCache

func (m *UniversalCacheManager) GetSessionInvalidationCache() *UniversalCache

GetSessionInvalidationCache returns the session invalidation cache for backchannel/front-channel logout

func (*UniversalCacheManager) GetTokenCache

func (m *UniversalCacheManager) GetTokenCache() *UniversalCache

GetTokenCache returns the token cache

func (*UniversalCacheManager) GetTokenTypeCache

func (m *UniversalCacheManager) GetTokenTypeCache() *UniversalCache

GetTokenTypeCache returns the token type detection cache

type ValidationResult

type ValidationResult struct {
	SanitizedValue string   `json:"sanitized_value,omitempty"`
	SecurityRisk   string   `json:"security_risk,omitempty"`
	Errors         []string `json:"errors,omitempty"`
	Warnings       []string `json:"warnings,omitempty"`
	IsValid        bool     `json:"is_valid"`
}

ValidationResult encapsulates the outcome of input validation. It includes the sanitized value, detected security risks, validation errors and warnings, and an overall validity status.

Directories

Path Synopsis
internal
cache
Package cache provides high-performance caching implementations for OIDC tokens, metadata, and JWKs.
Package cache provides high-performance caching implementations for OIDC tokens, metadata, and JWKs.
cache/backends
Package backend provides cache backend implementations for the Traefik OIDC plugin.
Package backend provides cache backend implementations for the Traefik OIDC plugin.
cache/resilience
Package resilience provides resilience patterns for cache backends.
Package resilience provides resilience patterns for cache backends.
cleanup
Package cleanup provides background task management and cleanup functionality.
Package cleanup provides background task management and cleanup functionality.
compat
Package compat provides backward compatibility layer during refactoring
Package compat provides backward compatibility layer during refactoring
dcrstorage
Package dcrstorage provides storage backends for OIDC Dynamic Client Registration credentials.
Package dcrstorage provides storage backends for OIDC Dynamic Client Registration credentials.
features
Package features provides feature flag management for safe rollback during refactoring
Package features provides feature flag management for safe rollback during refactoring
pool
Package pool provides a unified, centralized memory pool management system for the entire application.
Package pool provides a unified, centralized memory pool management system for the entire application.
providers
Package providers implements a universal OIDC provider abstraction system.
Package providers implements a universal OIDC provider abstraction system.
recovery
Package recovery provides error recovery and resilience mechanisms for OIDC authentication.
Package recovery provides error recovery and resilience mechanisms for OIDC authentication.
utils
Package utils provides common utility functions used across the OIDC middleware
Package utils provides common utility functions used across the OIDC middleware
session
chunking
Package chunking provides session chunking functionality for large tokens
Package chunking provides session chunking functionality for large tokens

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL