Filed from SSO security review 2026-04-14. Severity: LOW (performance + availability).
Current state
`backend/app/services/auth/sso/oidc.py:103-113` does a synchronous `httpx.get()` to the IdP's JWKS endpoint on every SSO login. No caching.
Risks
- Latency: adds a round-trip to every SSO login
- Availability coupling: if the IdP's JWKS endpoint is slow or down, all SSO logins stall
- Rate-limiting: frequent JWKS fetches may be rate-limited by some IdPs
Industry practice
IdPs publish JWKS with Cache-Control / ETag headers; clients cache for minutes to hours. Google, Auth0, Okta all advise clients cache JWKS.
Recommendation
In-process TTL cache (5-15 min) via `cachetools.TTLCache`, with refresh-on-miss if the id_token's `kid` isn't in the cached set.
References
- Source: `docs/SSO_SECURITY_REVIEW_2026-04-14.md`
Filed from SSO security review 2026-04-14. Severity: LOW (performance + availability).
Current state
`backend/app/services/auth/sso/oidc.py:103-113` does a synchronous `httpx.get()` to the IdP's JWKS endpoint on every SSO login. No caching.
Risks
Industry practice
IdPs publish JWKS with Cache-Control / ETag headers; clients cache for minutes to hours. Google, Auth0, Okta all advise clients cache JWKS.
Recommendation
In-process TTL cache (5-15 min) via `cachetools.TTLCache`, with refresh-on-miss if the id_token's `kid` isn't in the cached set.
References