A lightweight library to secure FastAPI APIs using Keycloak, enabling Role-Based Access Control (RBAC) with minimal configuration.
- Simple integration with Keycloak for FastAPI applications.
- Built-in support for Role-Based Access Control (RBAC) using Keycloak roles.
- Works seamlessly with both realm roles and client roles.
- Automatically decodes and validates JWT tokens.
- Python: 3.12 or higher
- FastAPI: 0.115.6 or higher
- Keycloak: 5.1.1 or higher
Install the library using pip:
pip install fastapi-keycloak-auth
Start by initializing the KeycloakAuth
instance with your Keycloak server configuration.
There are two ways that you can use to initialize the KeycloakAuth
instance:
-
Providing keycloak configurations as arguments in the initializer
from keycloak_auth.keycloak_auth import KeycloakAuth auth = KeycloakAuth( server_url=KEYCLOAK_URL, client_id=KEYCLOAK_CLIENT_ID, realm_name=KEYCLOAK_REALM_NAME, client_secret_key=KEYCLOAK_CLIENT_SECRET, use_resource_access=True )
Replace
KEYCLOAK_URL
,KEYCLOAK_CLIENT_ID
,KEYCLOAK_REALM_NAME
, andKEYCLOAK_CLIENT_SECRET
with your Keycloak instance details.server_url
: The URL of your Keycloak server. Ex:http://localhost:8080/auth/
client_id
: The client ID of your Keycloak client.realm_name
: The name of your Keycloak realm.client_secret_key
: The client secret of your Keycloak client.use_resource_access
: Set toTrue
if you want to use client roles in RBAC instead of realm roles (Default is set toFalse
).
-
Setting up Keycloak configurations as environmental variables (This method is recommended when this application is running in a containerized environment)
from keycloak_auth.keycloak_auth import KeycloakAuth import os os.environ['KEYCLOAK_URL'] = KEYCLOAK_URL os.environ['KEYCLOAK_CLIENT_ID'] = KEYCLOAK_CLIENT_ID os.environ['KEYCLOAK_REALM_NAME'] = KEYCLOAK_REALM_NAME os.environ['KEYCLOAK_CLIENT_SECRET'] = KEYCLOAK_CLIENT_SECRET auth = KeycloakAuth()
Replace
KEYCLOAK_URL
,KEYCLOAK_CLIENT_ID
,KEYCLOAK_REALM_NAME
, andKEYCLOAK_CLIENT_SECRET
with your Keycloak instance details.KEYCLOAK_URL
: The URL of your Keycloak server. Ex:http://localhost:8080/auth/
KEYCLOAK_CLIENT_ID
: The client ID of your Keycloak client.KEYCLOAK_REALM_NAME
: The name of your Keycloak realm.KEYCLOAK_CLIENT_SECRET
: The client secret of your Keycloak client.
Use the RolesAllowed
decorator to protect your FastAPI routes based on roles defined in Keycloak.
You can pass a list of roles that are allowed to access the route.
Important Note: make sure to add authorization: str | None = Header(default=None)
as a parameter in the route function to receive the JWT token.
Otherwise, the library will not be able to decode and validate the token.
from fastapi import FastAPI, Header
from keycloak_auth.keycloak_auth import KeycloakAuth
app = FastAPI()
auth: KeycloakAuth = KeycloakAuth(
server_url=KEYCLOAK_URL,
client_id=KEYCLOAK_CLIENT_ID,
realm_name=KEYCLOAK_REALM_NAME,
client_secret_key=KEYCLOAK_CLIENT_SECRET,
use_resource_access=True
)
@app.get('/admin')
@auth.RolesAllowed(['admin'])
async def admin_route(authorization: str | None = Header(default=None)):
return {'message': 'Hello Admin'}
@app.get('/user')
@auth.RolesAllowed(['admin', 'user'])
async def user_route(authorization: str | None = Header(default=None)):
return {'message': 'Hello User'}
-
You can also use the
KeycloakAuth
instance to decode and validate JWT tokens manually.from keycloak_auth.keycloak_auth import KeycloakAuth auth = KeycloakAuth() token = auth.current_token
-
You can use the
KeycloakAuth
instance to get the current user's profile.from keycloak_auth.keycloak_auth import KeycloakAuth auth = KeycloakAuth() user = auth.get_user_info()
The library automatically raises HTTPException for errors such as:
401 Unauthorized
: When the token is missing or expired.403 Forbidden
: When the user does not have sufficient permissions.- For advanced scenarios, you can implement additional error handling logic in your application.
This project is licensed under the MIT License - see the LICENSE file for details.