Skip to main content

auth

Authentication for the patient-data API.

Verifies a hub-issued (Auth0) RS256 JWT presented in the Authorization: Bearer <token> header. Beyond signature, expiry, issuer and audience checks, the token's user must match the user the pod is logged in as: the pod's own username is itself the https://www.bitfount.com/username claim of its id token, so the check is an equality against that same claim.

Failures are surfaced as HTTP errors: a token that cannot be authenticated (missing, malformed, bad signature, expired, wrong issuer/audience) yields 401; a validly-signed token whose bearer is not permitted (email not verified, or a different user than the pod) yields 403.

Module

Functions

get_jwt_verifier

def get_jwt_verifier(request: Request)> JWTVerifier:

Return the JWT verifier bound to the app.

Arguments

  • request: The incoming request, used to reach app.state.

Returns The JWTVerifier stored on the app at creation time.

verify_jwt

def verify_jwt(    authorization: str | None = Header(None),    verifier: JWTVerifier = Depends(dependency=&lt;function get_jwt_verifier&gt;, use_cache=True, scope=None),)> AuthenticatedUser:

Authenticate a request from its Authorization header.

Arguments

  • authorization: The raw Authorization header, if present.
  • verifier: The app-scoped JWT verifier.

Returns The authenticated user.

Raises

  • HTTPException: 401 if the token is missing/invalid, 403 if the bearer is not the pod's user or has an unverified email.

Classes

JWTVerifier

class JWTVerifier(    jwk_client: PyJWKClient, issuer: str, audience: str, expected_username: str,):

Verifies hub-issued JWTs and matches them to the pod's user.

Arguments

  • jwk_client: Client that resolves a token's signing key from the JWKS endpoint (a PyJWKClient in production; the network boundary).
  • issuer: The exact expected iss claim (e.g. https://<domain>/).
  • audience: The exact expected aud claim.
  • expected_username: The username the pod is logged in as; a token's username claim must equal this.

Initialise the verifier with its JWKS client and expected claims.

Static methods


from_config

def from_config(expected_username: str)> JWTVerifier | None:

Build a verifier from settings, or None if it cannot be configured.

The verification parameters default from the SDK's canonical auth config: the issuer domain from the current BITFOUNT_ENVIRONMENT (the same domain the pod logs in against) and the audience from the hub API identifier. The patient_api_jwt_* settings override these.

note

Configuration is captured once, here, at build time — issuer, audience, username and the PyJWKClient are all fixed on the returned verifier. A later config.refresh_configuration() (or a change to BITFOUNT_ENVIRONMENT / the patient_api_jwt_* overrides) does not affect a running server; rebuild the verifier (restart the server) to pick up such a change.

Arguments

  • expected_username: The username the pod is logged in as.

Returns A configured JWTVerifier, or None when the pod has no username to match against (in which case the API must not be served).

Methods


verify

def verify(self, token: str)> AuthenticatedUser:

Verify a bearer token and return the authenticated user.

Arguments

  • token: The raw JWT extracted from the Authorization header.

Returns The authenticated user, whose id is the verified username.

Raises

  • HTTPException: 401 if the token cannot be authenticated (bad signature, expired, wrong issuer/audience, unresolvable key); 403 if the bearer is authenticated but not permitted (email not verified, or a different user than the pod).