Skip to main content

Libreria de autenticacion OIDC con Keycloak para FastAPI

Project description

Auth Guardian

auth-guardian es una libreria Python para integrar autenticacion OIDC con Keycloak en FastAPI, con enfoque de seguridad, revocacion inmediata y configuracion simple.

Qué resuelve

  • Flujo OIDC (/login, /oidc/callback, /logout) sin implementarlo a mano.
  • Proteccion de endpoints autenticados.
  • Control de acceso por roles.
  • Validacion de access token por introspection contra Keycloak (default).
  • Revocacion inmediata en logout (refresh token revoke + invalidacion por introspection).

Instalación

pip install auth-guardian

Variables obligatorias

La libreria falla al iniciar si falta alguna variable requerida y registra un log claro indicando cual falta.

  • KEYCLOAK_BASE_URL
  • KEYCLOAK_REALM
  • KEYCLOAK_CLIENT_ID
  • KEYCLOAK_CLIENT_SECRET

Ejemplo de .env minimo:

KEYCLOAK_BASE_URL=
KEYCLOAK_REALM=
KEYCLOAK_CLIENT_ID=
KEYCLOAK_CLIENT_SECRET=

Configuración recomendada en Keycloak

Para el cliente que usa la API:

  1. Crear cliente OIDC.
  2. Activar autenticacion de cliente (Client authentication / confidential client).
  3. Configurar Client Secret.
  4. Configurar redirect URI de la app para callback OIDC.
  5. Verificar roles en realm/client segun tu modelo de autorizacion.

Nota: KEYCLOAK_CLIENT_SECRET se usa para introspection y tambien, por defecto, para firmar/verificar state anti-CSRF.

Integración rápida con FastAPI

from fastapi import Depends, FastAPI
from auth_guardian import AuthGuardian, create_auth_router

app = FastAPI()
auth = AuthGuardian()

app.include_router(
    create_auth_router(
        auth=auth,
        login_redirect_url="/dashboard",
        logout_redirect_url="/login",
    )
)

@app.get("/health")
async def health() -> dict[str, str]:
    return {"status": "ok"}

@app.get("/ejemplo/v1")
async def ejemplo_v1(user: dict = Depends(auth.get_current_user)):
    return {
        "mensaje": f"Hola {user.get('preferred_username')}",
        "email": user.get("email"),
    }

@app.get("/ejemplo/v2")
async def ejemplo_v2(user: dict = Depends(auth.require_role("admin"))):
    return {"mensaje": "Acceso permitido para rol admin"}

Con esto tienes:

  • GET /login
  • GET /oidc/callback
  • GET /logout
  • Proteccion por usuario autenticado y por rol.

Flujo visual (imágenes)

1) Login OIDC

sequenceDiagram
    participant U as Usuario
    participant A as API FastAPI
    participant K as Keycloak

    U->>A: GET /login
    A->>K: Redirect Authorization Request
    K-->>U: Login UI
    U->>K: Credenciales
    K-->>A: Redirect /oidc/callback?code=...
    A->>K: Exchange code por tokens
    K-->>A: access_token + refresh_token
    A-->>U: Set cookies + redirect app

2) Request protegido (introspection)

sequenceDiagram
    participant C as Cliente
    participant A as API
    participant K as Keycloak

    C->>A: Request con token
    A->>K: POST /token/introspect
    K-->>A: { active: true/false }
    alt active=true
        A-->>C: 200 OK
    else active=false
        A-->>C: 401 Unauthorized
    end

3) Logout

sequenceDiagram
    participant U as Usuario
    participant A as API
    participant K as Keycloak

    U->>A: GET /logout
    A->>K: POST /revoke (refresh_token)
    K-->>A: 200/204
    A-->>U: Delete cookies + redirect

Validación de token

AuthGuardian usa introspection por defecto:

Modo Comportamiento
introspection (default) Valida cada request contra Keycloak (/token/introspect)

Notas operativas:

  • Si active=false, responde 401.
  • Si Keycloak no está disponible, responde 503 sin filtrar detalles internos.
  • Si cae la API de Keycloak, introspection falla aunque la BD de Keycloak siga arriba.

Troubleshooting

Falta una variable obligatoria

Síntoma:

  • Error al iniciar con mensaje Missing required configuration variables.

Accion:

  • Completar las variables Keycloak requeridas en entorno.

Introspection devuelve 401 o 403

Síntoma:

  • Error relacionado a introspection denegada.

Accion:

  • Verificar KEYCLOAK_CLIENT_SECRET.
  • Verificar que el cliente en Keycloak tenga autenticacion de cliente habilitada.

Redirect URI o callback incorrecto

Síntoma:

  • Login falla en callback o mismatch en Keycloak.

Accion:

  • Revisar la configuracion de redirect URI del cliente en Keycloak.
  • Si estas detras de proxy, revisar cabeceras Host y X-Forwarded-*.

API pública estable

  • AuthGuardian
  • create_auth_router
  • extract_client_roles(payload, client_id)
  • AuthConfig
  • AuthTokenValidator
  • AuthOIDCClient
  • KeycloakAuthError
  • TokenValidationError
  • KeycloakAPIError

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

auth_guardian-0.1.11.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

auth_guardian-0.1.11-py3-none-any.whl (20.7 kB view details)

Uploaded Python 3

File details

Details for the file auth_guardian-0.1.11.tar.gz.

File metadata

  • Download URL: auth_guardian-0.1.11.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for auth_guardian-0.1.11.tar.gz
Algorithm Hash digest
SHA256 5bdcc5736857f3847bcfed55acc101abf6c78600b5d73d8444b05a83ab913bf0
MD5 e713a9b98b780fae4f4911dbbc1c90e8
BLAKE2b-256 96ee49a263c1200d5f6bf9e1a67b2da452a9273ae75a3776dc8c969233345773

See more details on using hashes here.

File details

Details for the file auth_guardian-0.1.11-py3-none-any.whl.

File metadata

  • Download URL: auth_guardian-0.1.11-py3-none-any.whl
  • Upload date:
  • Size: 20.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for auth_guardian-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 a2e8a35bbe094420ec8f80fc9a64a5927a35cfd34c39dad2a9dca39d36385a7a
MD5 ad09e48b7c9fa9dbb2f3d59abf7abc4e
BLAKE2b-256 2f8fa1222995a8b717ff2a17eceee7a14379228973b988ef6edbdeee097b1bcd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page