Summary
Both JWKS URLs the API verifies tokens against, FRAMES_BEARER_JWKS_URL and FRAMES_IDTOKEN_JWKS_URL (chart values frames.auth.bearer.jwksUrl and frames.auth.idToken.jwksUrl), are handed straight to PyJWT's PyJWKClient with no scheme check. A misconfigured http:// URL would fetch signing keys over cleartext, which lets an on-path attacker substitute a key set and mint accepted tokens. Today a malformed URL fails closed (first fetch fails, every token is rejected), but a well-formed cleartext URL is accepted silently.
Raised by @echarles on #47, which only changes how the IdToken path falls back to the bearer verifier and does not touch URL handling.
Proposed hardening
- Validate both JWKS URLs at startup: require
https; allow http only when unsafe_auth_enabled() is on (local development), and log loudly when that exception is used.
- Reject URLs with userinfo or fragments.
- Fail startup (not first request) on an invalid URL so the misconfiguration is visible in the pod's events rather than as 401s.
- Document the requirement next to both
jwksUrl values in helm/collab-hub/values.yaml and add a pattern (^https://) to the two jwksUrl properties in values.schema.json so the chart refuses it before the pod does.
Not in scope
Hostname allowlists or TLD checks. Internal Keycloak hostnames and cluster-local service URLs are legitimate here, so a public-suffix rule would not add security.
Refs #47.
Summary
Both JWKS URLs the API verifies tokens against,
FRAMES_BEARER_JWKS_URLandFRAMES_IDTOKEN_JWKS_URL(chart valuesframes.auth.bearer.jwksUrlandframes.auth.idToken.jwksUrl), are handed straight to PyJWT'sPyJWKClientwith no scheme check. A misconfiguredhttp://URL would fetch signing keys over cleartext, which lets an on-path attacker substitute a key set and mint accepted tokens. Today a malformed URL fails closed (first fetch fails, every token is rejected), but a well-formed cleartext URL is accepted silently.Raised by @echarles on #47, which only changes how the IdToken path falls back to the bearer verifier and does not touch URL handling.
Proposed hardening
https; allowhttponly whenunsafe_auth_enabled()is on (local development), and log loudly when that exception is used.jwksUrlvalues inhelm/collab-hub/values.yamland add apattern(^https://) to the twojwksUrlproperties invalues.schema.jsonso the chart refuses it before the pod does.Not in scope
Hostname allowlists or TLD checks. Internal Keycloak hostnames and cluster-local service URLs are legitimate here, so a public-suffix rule would not add security.
Refs #47.