Skip to content

API Reference

The auth sources, validators, token helpers, and core exceptions import directly from fastapi_multiauth:

from fastapi_multiauth import (
    APIKeyHeaderAuth,
    APIKeyQueryAuth,
    AuthSource,
    HTTPBasicAuth,
    HTTPBearerAuth,
    APIKeyCookieAuth,
    ForbiddenError,
    JWTValidator,
    MultiAuth,
    UnauthorizedError,
    hash_token,
    verify_token_hash,
)

The OAuth 2.0 / OIDC login-flow helpers are a separate concern: they obtain credentials via the browser redirect flow rather than validating credentials on an incoming request, and they require the oauth extra. They live in the fastapi_multiauth.oauth namespace:

from fastapi_multiauth.oauth import (
    OAuthDiscoveryError,
    OAuthError,
    OAuthExchangeError,
    OAuthUserinfoError,
    OIDCEndpoints,
    oauth_build_authorization_redirect,
    oauth_decode_state,
    oauth_encode_state,
    oauth_exchange_code,
    oauth_fetch_userinfo,
    oauth_generate_pkce_pair,
    oauth_generate_state_token,
    oauth_resolve_provider_urls,
)

Sources

fastapi_multiauth.AuthSource

Bases: ABC

Abstract base class for authentication sources.

Subclasses implement :meth:extract and :meth:authenticate; both Security(source) and MultiAuth route through that pair via :meth:dispatch.

__call__(**kwargs) async

FastAPI dependency dispatch.

__init__(scheme=None)

Set up the FastAPI dependency signature.

Parameters:

Name Type Description Default
scheme Any

Optional fastapi.security scheme; only its OpenAPI metadata is used, extraction always goes through :meth:extract.

None

authenticate(credential) abstractmethod async

Validate a credential and return the authenticated identity.

authenticate_scoped(credential, scopes) async

Validate a credential, enforcing the scopes declared on the route.

dispatch(request, scopes) async

Extract the credential, then authenticate it with the route scopes.

Raises:

Type Description
UnauthorizedError

When no credential is present. This source's WWW-Authenticate challenge is attached to any 401 raised.

extract(request) abstractmethod async

Extract the raw credential from the request without validating.

Must return None — never an empty string — when the credential is absent, empty, or does not belong to this source.

www_authenticate()

Challenge value for the WWW-Authenticate header on 401 responses.

Returns None when the source has no HTTP auth scheme (cookies, API keys).

fastapi_multiauth.HTTPBearerAuth

Bases: ValidatedAuthSource

Bearer token authentication source (wraps HTTPBearer for OpenAPI).

The validator is called as await validator(credential, **kwargs).

Parameters:

Name Type Description Default
validator Callable[..., Any]

Sync or async callable returning the identity; raises :class:~fastapi_multiauth.exceptions.UnauthorizedError on failure.

required
prefix str | None

Optional token prefix (e.g. "user_"); only tokens with this prefix are matched, and the prefix is kept in the validated value.

None
scheme_name str | None

OpenAPI security scheme name (default HTTPBearer); give each source a distinct name when several appear in the same app.

None
**kwargs Any

Extra keyword arguments forwarded to the validator on every call.

{}

__call__(**kwargs) async

FastAPI dependency dispatch.

authenticate(credential) async

Validate a credential and return the identity (no route scopes).

authenticate_scoped(credential, scopes) async

Validate the credential, re-checking the prefix and forwarding scopes.

dispatch(request, scopes) async

Extract the credential, then authenticate it with the route scopes.

Raises:

Type Description
UnauthorizedError

When no credential is present. This source's WWW-Authenticate challenge is attached to any 401 raised.

extract(request) async

Return the bearer token, or None when absent, empty, or mismatched.

The Bearer scheme is matched case-insensitively; the prefix, when configured, is kept in the returned value.

generate_token(nbytes=32)

Generate a secure URL-safe random token, prefixed when configured.

Parameters:

Name Type Description Default
nbytes int

Number of random bytes before base64 encoding (default 32).

32

Returns:

Type Description
str

A ready-to-use token string (e.g. "user_Xk3...").

require(**kwargs)

Return a copy of this source with additional (or overriding) validator kwargs.

www_authenticate()

Bearer challenge per RFC 6750 §3.

fastapi_multiauth.APIKeyCookieAuth

Bases: ValidatedAuthSource

Cookie-based authentication source (wraps APIKeyCookie for OpenAPI).

When secret_key is set, the cookie is signed (HMAC-SHA256 with an embedded timestamp, salted by the cookie name) for stateless, tamper-proof sessions; otherwise the raw cookie value is passed through.

Parameters:

Name Type Description Default
name str

Cookie name.

required
validator Callable[..., Any]

Sync or async callable receiving the cookie value (plain, after signature verification when signed) and returning the identity.

required
secret_key str | Sequence[str] | None

One key or a sequence to rotate (first signs, all verify); each at least 32 bytes. When None, the cookie is not signed.

None
ttl int

Cookie lifetime in seconds (default 24 h); also enforced server-side when the cookie is signed.

86400
secure bool

Set the Secure flag (default True); disable only in local dev.

True
samesite SameSite

SameSite cookie attribute (default "lax").

'lax'
domain str | None

Optional Domain cookie attribute.

None
path str

Path cookie attribute (default "/").

'/'
scheme_name str | None

OpenAPI security scheme name (default APIKeyCookie_{name}).

None
**kwargs Any

Extra keyword arguments forwarded to the validator on every call.

{}

__call__(**kwargs) async

FastAPI dependency dispatch.

authenticate(credential) async

Validate a credential and return the identity (no route scopes).

authenticate_scoped(credential, scopes) async

Verify the cookie, forwarding route-declared scopes to the validator.

Clear the session cookie (logout) from this client only.

dispatch(request, scopes) async

Extract the credential, then authenticate it with the route scopes.

Raises:

Type Description
UnauthorizedError

When no credential is present. This source's WWW-Authenticate challenge is attached to any 401 raised.

extract(request) async

Return the raw cookie value, or None when absent or empty.

require(**kwargs)

Return a copy of this source with additional (or overriding) validator kwargs.

Attach the cookie to response, signing it when secret_key is set.

www_authenticate()

Challenge value for the WWW-Authenticate header on 401 responses.

Returns None when the source has no HTTP auth scheme (cookies, API keys).

fastapi_multiauth.APIKeyHeaderAuth

Bases: ValidatedAuthSource

API key header authentication source (wraps APIKeyHeader for OpenAPI).

The validator is called as await validator(api_key, **kwargs).

Parameters:

Name Type Description Default
name str

HTTP header name that carries the API key (e.g. "X-API-Key").

required
validator Callable[..., Any]

Sync or async callable returning the identity; raises :class:~fastapi_multiauth.exceptions.UnauthorizedError on failure.

required
scheme_name str | None

OpenAPI security scheme name (default APIKeyHeader_{name}).

None
**kwargs Any

Extra keyword arguments forwarded to the validator on every call.

{}

__call__(**kwargs) async

FastAPI dependency dispatch.

authenticate(credential) async

Validate a credential and return the identity (no route scopes).

authenticate_scoped(credential, scopes) async

Validate a credential, forwarding route-declared scopes to the validator.

dispatch(request, scopes) async

Extract the credential, then authenticate it with the route scopes.

Raises:

Type Description
UnauthorizedError

When no credential is present. This source's WWW-Authenticate challenge is attached to any 401 raised.

extract(request) async

Return the API key from the configured header, or None when absent or empty.

require(**kwargs)

Return a copy of this source with additional (or overriding) validator kwargs.

www_authenticate()

Challenge value for the WWW-Authenticate header on 401 responses.

Returns None when the source has no HTTP auth scheme (cookies, API keys).

fastapi_multiauth.APIKeyQueryAuth

Bases: ValidatedAuthSource

API key query-string authentication source (wraps APIKeyQuery for OpenAPI).

The validator is called as await validator(api_key, **kwargs).

.. warning:: Credentials in the query string leak into access logs, browser history, and Referer headers. Prefer a header or cookie when you can; use this only for clients that cannot set headers.

Parameters:

Name Type Description Default
name str

Query parameter name that carries the API key (e.g. "api_key").

required
validator Callable[..., Any]

Sync or async callable returning the identity; raises :class:~fastapi_multiauth.exceptions.UnauthorizedError on failure.

required
scheme_name str | None

OpenAPI security scheme name (default APIKeyQuery_{name}).

None
**kwargs Any

Extra keyword arguments forwarded to the validator on every call.

{}

__call__(**kwargs) async

FastAPI dependency dispatch.

authenticate(credential) async

Validate a credential and return the identity (no route scopes).

authenticate_scoped(credential, scopes) async

Validate a credential, forwarding route-declared scopes to the validator.

dispatch(request, scopes) async

Extract the credential, then authenticate it with the route scopes.

Raises:

Type Description
UnauthorizedError

When no credential is present. This source's WWW-Authenticate challenge is attached to any 401 raised.

extract(request) async

Return the API key from the configured query parameter, or None when absent or empty.

require(**kwargs)

Return a copy of this source with additional (or overriding) validator kwargs.

www_authenticate()

Challenge value for the WWW-Authenticate header on 401 responses.

Returns None when the source has no HTTP auth scheme (cookies, API keys).

fastapi_multiauth.HTTPBasicAuth

Bases: ValidatedAuthSource

HTTP Basic authentication source (wraps HTTPBasic for OpenAPI, RFC 7617).

The validator is called as await validator(username, password, **kwargs); compare the password in constant time (secrets.compare_digest).

Parameters:

Name Type Description Default
validator Callable[..., Any]

Sync or async callable receiving (username, password) and returning the identity; raises :class:~fastapi_multiauth.exceptions.UnauthorizedError on failure.

required
realm str | None

Optional protection-space name for the WWW-Authenticate challenge.

None
scheme_name str | None

OpenAPI security scheme name (default HTTPBasic).

None
**kwargs Any

Extra keyword arguments forwarded to the validator on every call.

{}

__call__(**kwargs) async

FastAPI dependency dispatch.

authenticate(credential) async

Validate a credential and return the identity (no route scopes).

authenticate_scoped(credential, scopes) async

Decode the blob, forwarding route-declared scopes to the validator.

dispatch(request, scopes) async

Extract the credential, then authenticate it with the route scopes.

Raises:

Type Description
UnauthorizedError

When no credential is present. This source's WWW-Authenticate challenge is attached to any 401 raised.

extract(request) async

Return the base64 credentials blob, or None when absent or empty.

The Basic scheme is matched case-insensitively; decoding and the split happen in :meth:authenticate, so a malformed blob is a 401.

require(**kwargs)

Return a copy of this source with additional (or overriding) validator kwargs.

www_authenticate()

Basic challenge, with the realm when configured (RFC 7617 §2).

fastapi_multiauth.MultiAuth

Combine multiple authentication sources into a single callable.

Sources are tried in declaration order through the same extract()/ authenticate() pair used by direct Security(source) access.

Parameters:

Name Type Description Default
*sources AuthSource

Auth source instances to try in order.

()

Raises:

Type Description
TypeError

If a source is not an :class:AuthSource instance.

dispatch(request, scopes) async

Authenticate with the first source whose credential is present.

require(**kwargs)

Return a new :class:MultiAuth with kwargs forwarded to each source.

www_authenticate()

Combined challenge of all sources (RFC 9110 §11.6.1), or None.

Validators

fastapi_multiauth.JWTValidator

Validate JWTs — plug directly into :class:~fastapi_multiauth.HTTPBearerAuth.

Requires the jwt extra. Configure exactly one of secret (symmetric HS*) or jwks_url (asymmetric, against the provider's JWKS).

Parameters:

Name Type Description Default
secret str | None

Symmetric key for HS* validation (at least 32 bytes).

None
jwks_url str | None

HTTPS URL of the provider's JWKS document.

None
algorithms Sequence[str] | None

Accepted signature algorithms. Defaults to ["HS256"] in secret mode and ["RS256", "ES256"] in JWKS mode. Symmetric algorithms are rejected in JWKS mode (key-confusion risk).

None
audience str | Sequence[str] | None

Expected aud claim value(s). Unset → aud not checked.

None
issuer str | None

Expected iss claim value. Unset → iss not checked.

None
leeway float

Clock-skew tolerance in seconds for time-based claims.

0.0
required_claims Sequence[str]

Claims that must be present (default ("exp",)).

('exp',)
scopes_claim str

Claim holding granted scopes — a space-separated string (scope) or a list (scp, roles). A valid token missing a route-declared scope raises a 403.

'scope'
claims_to_identity Callable[[dict[str, Any]], Any] | None

Optional sync or async hook mapping verified claims to a domain object. Defaults to returning the claims.

None
jwks_cache_ttl float

JWKS cache lifetime in seconds (default 1 h).

3600.0
jwks_refresh_cooldown float

Minimum interval in seconds between JWKS fetch attempts (default 30 s).

30.0
timeout float

Timeout in seconds for the JWKS request.

DEFAULT_TIMEOUT

__call__(token, scopes=None) async

Verify token and return the identity.

Raises:

Type Description
UnauthorizedError

Invalid/expired signature or claims (401).

ForbiddenError

Valid token missing route-required scopes (403).

HTTPException

503 when the JWKS cannot be fetched and no keys are cached — the token cannot be checked either way.

Token helpers

fastapi_multiauth.hash_token(token)

Return the SHA-256 hex digest of an opaque token.

Parameters:

Name Type Description Default
token str

The opaque token, including any prefix.

required

Returns:

Type Description
str

A 64-character lowercase hex digest.

fastapi_multiauth.verify_token_hash(token, stored_hash)

Compare a presented token against a stored hash in constant time.

Parameters:

Name Type Description Default
token str

The opaque token presented by the client.

required
stored_hash str

The hex digest previously stored via :func:hash_token.

required

Returns:

Type Description
bool

True if the token matches the stored hash.

Exceptions

fastapi_multiauth.UnauthorizedError

Bases: HTTPException

HTTP 401 — authentication credentials were missing or invalid.

Raise from a validator (or any HTTPException) to reject a credential.

__init__(detail='Unauthorized', headers=None)

Initialize the exception.

Parameters:

Name Type Description Default
detail str

Human-readable message returned in the response body.

'Unauthorized'
headers dict[str, str] | None

Extra response headers (e.g. WWW-Authenticate).

None

fastapi_multiauth.ForbiddenError

Bases: HTTPException

HTTP 403 — the identity is authenticated but lacks permission.

Keep 401 (:class:UnauthorizedError) for absent or invalid credentials.

__init__(detail='Forbidden', headers=None)

Initialize the exception.

Parameters:

Name Type Description Default
detail str

Human-readable message returned in the response body.

'Forbidden'
headers dict[str, str] | None

Extra response headers.

None

OAuth helpers

The OAuth login-flow helpers live in the fastapi_multiauth.oauth namespace and require the oauth extra (pip install fastapi-multiauth[oauth]). See OAuth 2.0 / OIDC login for the walkthrough.

fastapi_multiauth.oauth.OAuthError

Bases: Exception

Base class for OAuth flow errors.

Not an HTTPException: the route decides the HTTP outcome of a failed flow.

fastapi_multiauth.oauth.OAuthDiscoveryError

Bases: OAuthError

Raised when the OIDC discovery document cannot be fetched or is invalid.

fastapi_multiauth.oauth.OAuthExchangeError

Bases: OAuthError

Raised when the OAuth authorization code exchange fails.

fastapi_multiauth.oauth.OAuthUserinfoError

Bases: OAuthError

Raised when the userinfo endpoint cannot be reached or returns garbage.

fastapi_multiauth.oauth.OIDCEndpoints

Bases: NamedTuple

Validated endpoint URLs from an OIDC discovery document.

All URLs are HTTPS-checked (loopback hosts excepted). Optional fields are None when the provider does not advertise them.

fastapi_multiauth.oauth.oauth_resolve_provider_urls(discovery_url, timeout=DEFAULT_TIMEOUT) async

Fetch the OIDC discovery document and return its validated endpoints.

Cached for one hour. The discovery URL must come from configuration, never from request input (SSRF / cache-poisoning).

Parameters:

Name Type Description Default
discovery_url str

Provider's openid-configuration URL.

required
timeout float

Discovery request timeout in seconds.

DEFAULT_TIMEOUT

Returns:

Name Type Description
Validated OIDCEndpoints

class:OIDCEndpoints; optional fields are None when absent.

Raises:

Type Description
ValueError

If discovery_url is not HTTPS.

OAuthDiscoveryError

If the document is unreachable, malformed, or advertises non-HTTPS endpoints or a mismatched issuer.

fastapi_multiauth.oauth.oauth_exchange_code(*, token_url, code, client_id, client_secret, redirect_uri, required_scopes=None, code_verifier=None, token_endpoint_auth_method='client_secret_post', timeout=DEFAULT_TIMEOUT) async

Exchange an authorization code for tokens and return the token response.

Delegates the exchange (including PKCE) to httpx-oauth (the oauth extra).

Parameters:

Name Type Description Default
token_url str

Provider's token endpoint.

required
code str

Authorization code from the provider's callback.

required
client_id str

OAuth application client ID.

required
client_secret str

OAuth application client secret.

required
redirect_uri str

Redirect URI used in the authorization request.

required
required_scopes str | None

Space-separated scopes that must be present in the token response (RFC 6749 §3.3).

None
code_verifier str | None

PKCE code verifier matching the challenge sent earlier (from :func:~fastapi_multiauth.oauth.oauth_generate_pkce_pair).

None
token_endpoint_auth_method TokenEndpointAuthMethod

How credentials are sent — in the POST body (client_secret_post, default) or as a Basic header.

'client_secret_post'
timeout float

Timeout in seconds for the token request.

DEFAULT_TIMEOUT

Returns:

Type Description
dict[str, Any]

The full token response as a dict (access_token plus whatever

dict[str, Any]

else the provider returned).

Raises:

Type Description
ValueError

If token_url is not HTTPS.

OAuthExchangeError

If the exchange is rejected or fails, grants a non-bearer token, or omits a required scope.

fastapi_multiauth.oauth.oauth_fetch_userinfo(*, userinfo_url, access_token, timeout=DEFAULT_TIMEOUT) async

Fetch the userinfo payload with a bearer access token.

Parameters:

Name Type Description Default
userinfo_url str

Provider's userinfo endpoint.

required
access_token str

Access token from :func:oauth_exchange_code.

required
timeout float

Timeout in seconds for the userinfo request.

DEFAULT_TIMEOUT

Returns:

Type Description
dict[str, Any]

The JSON payload returned by the userinfo endpoint as a plain dict.

Raises:

Type Description
ValueError

If userinfo_url is not HTTPS.

OAuthUserinfoError

If the endpoint fails or does not return JSON.

fastapi_multiauth.oauth.oauth_generate_state_token()

Generate a cryptographically random CSRF token for the OAuth state parameter.

fastapi_multiauth.oauth.oauth_generate_pkce_pair()

Generate a PKCE (code_verifier, code_challenge) pair (RFC 7636, S256).

Store the verifier server-side and pass it back to :func:~fastapi_multiauth.oauth.oauth_exchange_code on the callback.

Returns:

Type Description
str

A (code_verifier, code_challenge) tuple; the challenge is the

str

base64url SHA-256 of the verifier.

fastapi_multiauth.oauth.oauth_build_authorization_redirect(authorization_url, *, client_id, scopes, redirect_uri, destination, state_token, code_challenge=None)

Return an OAuth 2.0 authorization RedirectResponse (303 See Other).

Parameters:

Name Type Description Default
authorization_url str

Provider's authorization endpoint.

required
client_id str

OAuth application client ID.

required
scopes str

Space-separated list of requested scopes.

required
redirect_uri str

URI the provider should redirect back to.

required
destination str

Post-login URL (embedded in state).

required
state_token str

CSRF token from :func:oauth_generate_state_token; verify it with :func:oauth_decode_state on the callback.

required
code_challenge str | None

PKCE challenge from :func:oauth_generate_pkce_pair; when set, code_challenge_method=S256 is sent along.

None

Returns:

Name Type Description
A RedirectResponse

class:~fastapi.responses.RedirectResponse to the provider's

RedirectResponse

authorization page, retaining any query string already present.

fastapi_multiauth.oauth.oauth_encode_state(url, state_token)

Encode a destination URL and CSRF token into an OAuth state parameter.

Parameters:

Name Type Description Default
url str

Post-login destination URL.

required
state_token str

CSRF token from :func:oauth_generate_state_token.

required

fastapi_multiauth.oauth.oauth_decode_state(state, *, expected_state_token, fallback, allowed_hosts=())

Decode and CSRF-verify an OAuth state parameter (constant-time).

The stored token is single-use: delete it from the session after this call, matched or not, so a captured callback cannot be replayed.

Parameters:

Name Type Description Default
state str | None

Raw state query parameter from the callback.

required
expected_state_token str

Token stored before the authorization redirect; a mismatch returns fallback.

required
fallback str

URL returned when state is absent, malformed, or fails verification.

required
allowed_hosts Sequence[str] | None

Open-redirect guard — the decoded destination must be a relative path or an absolute http(s) URL whose host is listed. The default (()) allows relative paths only; None disables the check.

()

Returns:

Type Description
str

The destination URL embedded in state, or fallback.