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.12.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.12-py3-none-any.whl (20.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: auth_guardian-0.1.12.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.12.tar.gz
Algorithm Hash digest
SHA256 9b417e20f044237400672328f7412ce5be9379111b388f064f20723b2ab05e1e
MD5 8d16baf9c8c81d358d09c021122088ca
BLAKE2b-256 65a96fb1a6dd4a82be44f6c4fd0f5a641de0ff649531b8ce713a3e1dcbe395ed

See more details on using hashes here.

File details

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

File metadata

  • Download URL: auth_guardian-0.1.12-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.12-py3-none-any.whl
Algorithm Hash digest
SHA256 9603f6e200b3ef79c9ab3fc56a450305dc18125bae8307841c6a0bac3adf8da6
MD5 839816ad70989481ef6fc1e2a48b5b58
BLAKE2b-256 595463e2c9bf2dbf6fad0a0c7c580ea7431ba9f09d1502667b50b4bfa27e4e11

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