auth
auth copied to clipboard
feat(oidc): cache OIDC provider instances to prevent redundant calls
Problem
I noticed we were making redundant HTTP calls to OIDC discovery endpoints (.well-known/openid-configuration) on every single OAuth/OIDC request:
- Every
/authorizerequest -> HTTP call to provider's discovery endpoint - Every
/callbackrequest -> Another HTTP call to the same endpoint - Every ID token validation with
/token?grant_type=idtoken-> Yet another HTTP call
Impact: 10-500ms added latency per OAuth flow, 2+ unnecessary external HTTP requests per login. At scale this is huge amount of unnecessary traffic.
Solution
Implemented thread-safe caching of oidc.Provider instances with smart defaults:
// Before: Creates new provider on EVERY request
oidcProvider, err := oidc.NewProvider(ctx, issuer)
// After: Uses cached provider (1 hour TTL)
oidcProvider, err := defaultOIDCProviderCache.Get(ctx, issuer)
Also added a new optional environment variable:
GOTRUE_EXTERNAL_OIDC_PROVIDER_CACHE_TTL=1h # Default
GOTRUE_EXTERNAL_OIDC_PROVIDER_CACHE_TTL=30m # Custom TTL
Default: 1 hour (reasonable since OIDC discovery configs rarely change)
Notes
Safe for Cross-Account Use
IMPORTANT: The cache stores ONLY discovery metadata (endpoints, supported algorithms, etc), NOT user tokens or session data.
- Cache key: issuer URL (e.g., https://accounts.google.com)
- Cache value: oidc.Provider instance (stateless discovery metadata)
- User tokens, access tokens, refresh tokens: NEVER cached
JWKS Key Rotation Still Works
-
go-oidclibrary internally handles JWKS key fetching and rotation - Cached providers automatically fetch fresh keys when needed
- Key rotation happens independently of discovery document caching
- No risk of stale keys causing verification failures
Azure Multi-Tenant Support
- Each Azure tenant gets its own cache entry
- Cache key includes tenant ID in issuer URL
- Multi-tenant configurations work as before
Pull Request Test Coverage Report for Build 20601521323
Details
- 82 of 87 (94.25%) changed or added relevant lines in 8 files are covered.
- No unchanged relevant lines lost coverage.
- Overall coverage increased (+0.1%) to 68.887%
| Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
|---|---|---|---|
| internal/api/provider/linkedin_oidc.go | 0 | 1 | 0.0% |
| internal/api/provider/vercel_marketplace.go | 0 | 1 | 0.0% |
| internal/api/provider/cache.go | 75 | 78 | 96.15% |
| <!-- | Total: | 82 | 87 |
| Totals | |
|---|---|
| Change from base Build 20599680500: | 0.1% |
| Covered Lines: | 14821 |
| Relevant Lines: | 21515 |