Implementing Keycloak with Python FastAPI & PostgreSQL for Secure Authentication

Implementing Keycloak with Python FastAPI & PostgreSQL for Secure Authentication

Introduction

Authentication and authorization are at the heart of any modern web application. Instead of reinventing the wheel with custom auth systems, developers increasingly rely on proven, open-source Identity and Access Management (IAM) solutions like Keycloak. In this article, we’ll walk through integrating Keycloak with a Python FastAPI application using PostgreSQL as the database. Our focus will be on security best practices, scalable architecture, and professional coding standards.

Why Keycloak?

Description: Keycloak is an Open Source Identity and Access Management solution that supports Single Sign-On (SSO), OAuth2, OpenID Connect (OIDC), and more. It provides:

  • Centralized authentication
  • Multi-factor authentication (MFA)
  • Role-based access control (RBAC)
  • Integration with LDAP and social logins

Using Keycloak ensures fewer security vulnerabilities, faster development, and better compliance with modern security standards like OAuth 2.0 and OpenID Connect.

System Architecture Overview

Article content
(Sequence Diagram)

Description: Our setup will follow this architecture:

  1. FastAPI – Application server
  2. Keycloak – Authentication and token management
  3. PostgreSQL – Persistent data storage
  4. Keycloak Admin API – For managing users, roles, and groups programmatically

Flow:

  • User tries to access FastAPI endpoint.
  • FastAPI redirects to Keycloak for login.
  • Keycloak issues an access token and refresh token.
  • FastAPI validates the token before allowing access.
  • PostgreSQL stores application-specific data.

Setting up Keycloak

Description: Before coding, ensure Keycloak is running. You can use Docker for a quick start.

Docker Command:

docker run -d --name keycloak \
  -e KEYCLOAK_ADMIN=admin \
  -e KEYCLOAK_ADMIN_PASSWORD=admin \
  -p 8080:8080 \
  quay.io/keycloak/keycloak:25.0.1 start-dev        

Steps in Keycloak Admin Console:

  1. Create a new Realm (e.g., fastapi-realm).
  2. Create a Client (e.g., fastapi-client) with:
  3. Create Roles (e.g., admin, user).
  4. Create a User and assign a role.

FastAPI Project Setup

Description: We’ll create a FastAPI application that connects to PostgreSQL and validates JWT tokens from Keycloak.

Install dependencies:

pip install fastapi uvicorn python-keycloak psycopg2-binary SQLAlchemy python-jose        

Folder Structure:

app/
 ├── main.py
 ├── config.py
 ├── database.py
 ├── auth/
 │    ├── keycloak_utils.py
 │    ├── dependencies.py
 └── models.py        

Connecting to PostgreSQL

Description: We’ll use SQLAlchemy for ORM and psycopg2 as the driver.

# database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import os

DB_URL = os.getenv("DATABASE_URL", "postgresql://user:password@localhost:5432/fastapi_db")

engine = create_engine(DB_URL)
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)
Base = declarative_base()        

Security Tip:

  • Use environment variables for credentials.
  • Never commit secrets to version control.

Integrating Keycloak in FastAPI

Description: We’ll use python-keycloak to interact with Keycloak’s API and python-jose for token validation.

# auth/keycloak_utils.py
from keycloak import KeycloakOpenID
import os

KEYCLOAK_SERVER = os.getenv("KEYCLOAK_SERVER", "http://localhost:8080/")
KEYCLOAK_REALM = os.getenv("KEYCLOAK_REALM", "fastapi-realm")
KEYCLOAK_CLIENT_ID = os.getenv("KEYCLOAK_CLIENT_ID", "fastapi-client")
KEYCLOAK_CLIENT_SECRET = os.getenv("KEYCLOAK_CLIENT_SECRET", "your-client-secret")

keycloak_openid = KeycloakOpenID(
    server_url=f"{KEYCLOAK_SERVER}realms/{KEYCLOAK_REALM}",
    client_id=KEYCLOAK_CLIENT_ID,
    realm_name=KEYCLOAK_REALM,
    client_secret_key=KEYCLOAK_CLIENT_SECRET,
)        

Token Validation Middleware

Description: This middleware checks for the Bearer token and validates it.

# auth/dependencies.py
from fastapi import Depends, HTTPException, status
from jose import JWTError, jwt
from .keycloak_utils import keycloak_openid

def get_current_user(token: str):
    try:
        options = {"verify_aud": False}
        decoded_token = keycloak_openid.decode_token(token, key=keycloak_openid.public_key(), options=options)
        return decoded_token
    except JWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication credentials"
        )        

Example Protected Route

Description: This endpoint requires a valid Keycloak-issued token.

# main.py
from fastapi import FastAPI, Depends
from auth.dependencies import get_current_user

app = FastAPI()

@app.get("/secure-data")
def secure_data(user=Depends(get_current_user)):
    return {"message": f"Hello {user['preferred_username']}, secure content here!"}        

Testing:

Obtain an access token from Keycloak:

curl -X POST "http://localhost:8080/realms/fastapi-realm/protocol/openid-connect/token" \
-d "client_id=fastapi-client" \
-d "client_secret=YOUR_SECRET" \
-d "grant_type=password" \
-d "username=youruser" \
-d "password=yourpass"        
curl -H "Authorization: Bearer <ACCESS_TOKEN>" http://localhost:8000/secure-data        

Screenshots:

Admin panel login:

Article content
Article content

Security Best Practices

Description: To maintain a high-security standard:

  • Use HTTPS in production.
  • Rotate client secrets periodically.
  • Implement role-based access control (RBAC) in FastAPI endpoints.
  • Enable MFA in Keycloak.
  • Limit token lifespan and use refresh tokens securely.
  • Validate audience (aud) and issuer (iss) claims in JWT.

Conclusion

Description: By integrating Keycloak with FastAPI and PostgreSQL, you get a scalable, secure, and standards-compliant authentication system without reinventing the wheel. This approach keeps your application flexible, future-proof, and enterprise-ready.

#FastAPI #Keycloak #OAuth2 #OpenIDConnect #PythonDevelopment #PostgreSQL #APISecurity #JWT #SingleSignOn #BackendDevelopment #PythonTips #WebSecurity #Authentication #IdentityManagement #DevSecOps









To view or add a comment, sign in

More articles by Jayaprakash Attupurath

Others also viewed

Explore content categories