Skip to content

FastAPI MultiAuth

Composable authentication sources for FastAPI. You write the function that decides who a credential belongs to; the library extracts the credential, combines several schemes on one route, and declares all of it in OpenAPI.

No user model, no database coupling, no ready-made /login routes. Your store, your rules.

Installation

uv add fastapi-multiauth
pip install fastapi-multiauth

Optional extras: jwt for JWTValidator, oauth for the OAuth login helpers.

A first route

One route that accepts either an API token or a browser session cookie:

import os

from fastapi import FastAPI, Security

from fastapi_multiauth import (
    APIKeyCookieAuth,
    HTTPBearerAuth,
    MultiAuth,
    UnauthorizedError,
    hash_token,
)

SECRET_KEY = os.environ["SECRET_KEY"]
USERS = {"1": {"id": "1", "name": "alice"}}
TOKENS = {hash_token("user_alice-token"): "1"}


async def validate_token(token: str) -> dict:
    user_id = TOKENS.get(hash_token(token))
    if user_id is None:
        raise UnauthorizedError()
    return USERS[user_id]


async def validate_session(user_id: str) -> dict:
    if user_id not in USERS:
        raise UnauthorizedError()
    return USERS[user_id]


bearer = HTTPBearerAuth(validator=validate_token, prefix="user_")
session = APIKeyCookieAuth(
    name="__Host-session", validator=validate_session, secret_key=SECRET_KEY
)
auth = MultiAuth(bearer, session)

app = FastAPI()


@app.get("/me")
async def me(user: dict = Security(auth)):
    return user
  • A validator is a function you write: it receives the credential and returns the user, or raises to refuse it.
  • HTTPBearerAuth(..., prefix="user_") reads Authorization: Bearer user_... tokens.
  • APIKeyCookieAuth reads a signed cookie; your validator only sees the value once the signature checks out. SECRET_KEY must hold at least 32 random bytes, e.g. from secrets.token_urlsafe(32).
  • MultiAuth uses whichever one the request carries, and both appear in /docs.

What you get

  • Every standard scheme


    Bearer tokens, signed cookies, API keys, HTTP Basic, OAuth 2.0 and OpenID Connect.

    Guide

  • Several schemes, one route


    MultiAuth tries sources in order and documents all of them.

    Combining sources

  • Step-up authentication


    Demand a recent or stronger login on sensitive routes.

    Step-up

  • Fails closed


    Weak secrets, missing HTTPS and unenforceable scopes are refused, never skipped.

    Security model

Coming from fastapi.security, fastapi-users or AuthX? See the comparison.