Skip to main content

Keycloak Authentication Backend for FastAPI

Provides Starlette/FastAPI Authentication backend modules for Keycloak.

Install

pip install fastapi-auth-keycloak

Examples

from fastapi import FastAPI, HTTPException, Request, status
from fastapi_auth_keycloak import KeycloakUser, KeycloakAuthBackend
from starlette.datastructures import Secret
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware

backend = KeycloakAuthBackend(
    url="https://my-keycloak.com/",
    realm="my-realm",
    client_id="70a82a5a-b671-4acb-9ecf-b5dcce0305e3",
    client_secret=Secret("<client-secret>"),
    audience="my_aud", # This can be a list of accepted audiences, or an empty list for any
    # authentication_required=False, <- Set this to allow unauthenticated requests; defaults to `True`
)

app = FastAPI()
app.add_middleware(AuthenticationMiddleware, backend=backend)

@app.get("/user/name")
def get_current_user_identity(request: Request):
    return request.user.display_name

@app.get("/privileged/area")
def get_privileged_data(request: Request):
    if not request.auth.has_role(client="alpha-app", role="super-user"):
        raise HTTPException(status.HTTP_401_UNAUTHORIZED, "User not authenticated.")

    return {"OMG TOP SECRET"}

@app.get("/no-homers")
def get_no_homers_data(request: Request):
    if request.user.groups is not None and "/homers/simpson" in request.user.groups:
        raise HTTPException(status.HTTP_401_UNAUTHORIZED, "User not authenticated.")

    return {"Welcome Homer Glumplich!"}

UMA Authorization

This module supports using User-Managed Access (UMA) 2.0 Grant for OAuth 2.0 Authorization to authorize access to resources via the KeycloakAuthCredentials object, provided via Request.auth.

If the user's JWT does not currently authorize them to access the specified resource and scope(s) if provided, the authorize method will throw an HTTP 401 response with a WWW-Authenticate header to indicate to the client that they should obtain a UMA 2.0-compliant Requesting Party Token (RPT, of type urn:ietf:params:oauth:grant-type:uma-ticket) to be authorized to access the resource. See the specification for details.

from fastapi import FastAPI, HTTPException, Request, status
from fastapi_auth_keycloak import KeycloakUser, KeycloakAuthBackend
from starlette.datastructures import Secret
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware

backend = KeycloakAuthBackend(
    url="https://my-keycloak.com/",
    realm="my-realm",
    client_id="70a82a5a-b671-4acb-9ecf-b5dcce0305e3",
    client_secret=Secret("<client-secret>"),
    audience="my_aud",
)

app = FastAPI()
app.add_middleware(AuthenticationMiddleware, backend=backend)

@app.get("/user/name")
def get_current_user_identity(request: Request):
    return request.user.display_name

@app.get("/privileged/area")
def get_privileged_data(request: Request):
    # Assert user is authorized
    request.auth.authorize(resource_name="privileged_data", scope="privileged_data:read")
    return {"What privilege!"}

You can also authorize by a specific Resource Id if you have it:

@app.get("/privileged/area/{id}")
def get_privileged_data(request: Request, id: str):
    request.auth.authorize_by_id(resource_id=id, scope="privileged_data:read")
    return {f"Looks like you are allowed to see area {id}!"}

FastAPI-Auth also provides a UMAAuthorize class that can be used as a FastAPI dependency to authorize endpoint resources:

from fastapi import Depends
from fastapi_auth_keycloak.uma import UMAAuthorized
from typing_extensions import Annotated

@app.post("/privileged/area")
def add_privileged_data(
    authorized: Annotated[UMAAuthorize, Depends(UMAAuthorize("privileged_data", "privileged_data:write"))]
):
    # The dependency has already asserted the user is authorized, so you can jump straight to your endpoint logic.
    # You can also access the user and auth objects from the injected object:
    user_id = authorized.user.identity
    scopes = authorized.auth.scopes

If you need to check other Keycloak-specific (e.g., not OAuth2 or UMA2 standard) claims, you can instead use the KeycloakUMAAuthorize dependency:

from fastapi import Depends
from fastapi_auth_keycloak import KeycloakUMAAuthorized
from typing_extensions import Annotated

@app.post("/privileged/area")
def add_privileged_data(
    authorized: Annotated[KeycloakUMAAuthorized, Depends(KeycloakUMAAuthorized("privileged_data", "privileged_data:write"))]
):
    # Also check if a user has a specific client role:
    if authorized.auth.has_role(client="my_realm_client", role="my_client_role"):
        # Do other stuff
        ...

Basic JWT

This library also provides an Auth Backend for barebones JWTs:

from fastapi import FastAPI, HTTPException, Request, status
from fastapi_auth_keycloak import PublicKey
from fastapi_auth_keycloak.jwt import JWTUser, JWTAuthBackend
from starlette.middleware import Middleware
from starlette.middleware.authentication import AuthenticationMiddleware

backend = JWTAuthBackend(
    algorithms=["RS256"],
    audience="my_aud", # This can be a list of accepted audiences, or an empty list for any
    key=PublicKey("<public key>"),
    # authentication_required=False, <- Set this to allow unauthenticated requests; defaults to `True`
)

app = FastAPI()
app.add_middleware(AuthenticationMiddleware, backend=backend)

@app.get("/user/identity")
def get_current_user_identity(request: Request):
    return request.user.identity

Contributing

This package utilizes Poetry for dependency management and pre-commit for ensuring code formatting is automatically done and code style checks are performed.

git clone https://github.com/Daveography/fastapi-auth-keycloak.git fastapi-auth-keycloak
cd fastapi-auth-keycloak
pip install poetry
poetry install
poetry run pre-commit install
poetry run pre-commit autoupdate

Metadata

Release files for fastapi-auth-keycloak 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastapi-auth-keycloak 0.9.0
File Size Uploaded
fastapi_auth_keycloak-0.9.0.tar.gz 11.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastapi-auth-keycloak 0.9.0
File Interpreter ABI Platform
fastapi_auth_keycloak-0.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.4 kB

Release files / fastapi_auth_keycloak-0.9.0.tar.gz

Download URL fastapi_auth_keycloak-0.9.0.tar.gz
Size 11.8 kB
Tags Source
SHA-256 checksum
How to use checksums
790db48fe795ba1bf6b765a5a8a86dcdf9cf4adeeda8dcdb0ac60b9fc0619bcc
BLAKE2b-256 checksum
How to use checksums
6b7d855638909b5e62665f16d6590dec313e9e8bc76efed032c9add534bf46d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 4, 2025.

Transparency log

Release files / fastapi_auth_keycloak-0.9.0-py3-none-any.whl

Download URL fastapi_auth_keycloak-0.9.0-py3-none-any.whl
Size 19.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4309c9d209562d4bbba4de2890ec0cff465626cd235c644d7b047be261b04295
BLAKE2b-256 checksum
How to use checksums
77c54ddf2c47030eae1208015cd14d72933dfe01a72af588f454cb45787da1e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 4, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 release files

0.8.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page