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)
| File | Size | Uploaded | |
|---|---|---|---|
| fastapi_auth_keycloak-0.9.0.tar.gz | 11.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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