Skip to content

[Careers App] JWKS cache never refreshed and unsafe key fallback in JWT validation #298

Description

@pasindubalasooriya

Description:
The careers-app FastAPI backend has two defects in its JWKS (JSON Web Key Set) handling in apps/careers-app/backend/auth.py, affecting how incoming Asgardeo JWTs are validated:

  1. JWKS cache is never invalidated. _get_jwks fetches the key set once into a module-global _jwks_cache and only refetches when it is None. When Asgardeo rotates its signing keys, the cached set goes stale, jwt.decode fails for every newly-issued token, and the service silently degrades to the token-introspection endpoint on every request (introspection results are not cached either), a latent availability/latency cliff that only manifests at key-rotation time.

  2. Unsafe keys[0] fallback. When no JWK matches the token's kid, _get_key_for_token falls back to constructing the first key in the set. Verifying a token against an arbitrary key is a correctness/security smell; a kid miss should trigger a JWKS refresh and otherwise be rejected.

Sugged Labels:
bug, careers-app, security

Suggested Assignees:

Affected Product Version:
careers-app latest version

OS, DB, other environment details and versions:
Python 3.12, Asgardeo

Steps to reproduce:

  1. Start the careers backend and authenticate with a valid Asgardeo JWT (key is cached).
  2. Simulate Asgardeo key rotation by seeding _jwks_cache with a stale key set that lacks the token's kid.
  3. Send a request with a token whose kid is only in the current JWKS. kid is not found; the code tries to verify against the wrong keys[0] or fails jwt.decode, and every request silently falls back to introspection. The stale cache is never refreshed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions