Saltar a contenido

C4 Component — Keycloak

Keycloak 26.x actúa como el Identity Provider central de la plataforma. Este documento descompone su contenedor en componentes internos, describe las responsabilidades de cada uno y muestra cómo se relacionan para servir los flujos de autenticación de los realms realm-internal y realm-partners.

Componentes internos de Keycloak

flowchart TB
    subgraph Realm["Realm Context (realm-internal / realm-partners)"]
        AE["Authentication Engine\n────────────────\n• Flujos de autenticación\n• Browser Flow / Direct Grant\n• MFA (TOTP, WebAuthn)\n• PKCE enforced"]

        TS["Token Service\n────────────────\n• Emite access_token, id_token\n• refresh_token lifecycle\n• Revocación (backchannel)\n• Firma RS256 / ES256"]

        CR["Client Registry\n────────────────\n• partner-portal-app (public)\n• partner-service-m2m (confidential)\n• internal-portal (hybrid)\n• Redirect URIs / Scopes"]

        US["User Storage SPI\n────────────────\n• JDBC → PostgreSQL\n• Usuarios locales\n• Grupos / Roles\n• Atributos personalizados"]

        IB["Identity Broker\n────────────────\n• SAML 2.0 SP/IdP\n• OIDC externo (Google, Azure AD)\n• Mapeo de atributos\n• Account linking"]

        ES["Event System\n────────────────\n• Login events\n• Admin events\n• Listeners (log, webhook)"]
    end

    subgraph Admin["Plano de administración"]
        AA["Admin REST API\n/admin/realms/{realm}/*"]
        AC["Admin Console\n(UI web embebida)"]
        AA <--> AC
    end

    subgraph TLS["Plano de exposición"]
        OIDC["OIDC Endpoints\n/realms/{realm}/protocol/openid-connect/*"]
        SAML["SAML Endpoints\n/realms/{realm}/protocol/saml"]
        WK["Well-known\n/.well-known/openid-configuration\n/protocol/openid-connect/certs"]
    end

    AE --> TS
    AE --> US
    AE --> CR
    AE --> IB
    AE --> ES
    TS --> US
    AA --> AE
    AA --> CR
    AA --> US
    OIDC --> AE
    SAML --> IB
    WK --> TS

    US -->|JDBC| DB[(PostgreSQL 16)]
    TS -->|persiste sesiones| DB

Tabla de responsabilidades

Componente Responsabilidad principal Configuración clave
Authentication Engine Ejecuta flujos de autenticación configurables. Evalúa credenciales, MFA y condiciones de políticas. Authentication Flows > Browser Flow
Token Service Genera tokens JWT firmados con clave asimétrica del realm. Gestiona ciclo de vida de refresh tokens y revocación via backchannel logout. Realm Settings > Keys > RSA-generated
Client Registry Registra y valida clientes OAuth2. Controla el tipo de acceso (public/confidential), scopes permitidos y URIs de redirección. Clients > partner-portal-app
User Storage SPI Persiste y consulta usuarios en PostgreSQL mediante el proveedor JDBC integrado de Keycloak. Soporta atributos de extensión para datos de negocio. User Federation > jpa
Identity Broker Permite a usuarios autenticarse con un IDP externo y vincular su cuenta al realm de Keycloak. Identity Providers > SAML / OIDC
Event System Registra eventos de login, logout, errores de autenticación y cambios administrativos. Útil para auditoría y alertas. Events > Event Listeners
Admin REST API API REST completa para automatizar la gestión: crear realms, clientes, usuarios, asignar roles. Usada por pipelines CI/CD. Bearer token con rol realm-admin
Admin Console Interfaz web embebida en Keycloak para administración interactiva. Consume la Admin REST API internamente. /admin path

Endpoints OIDC principales

Endpoint Ruta Uso
Authorization /realms/{realm}/protocol/openid-connect/auth Inicio de Authorization Code Flow
Token /realms/{realm}/protocol/openid-connect/token Emisión de tokens (todos los grants)
Introspect /realms/{realm}/protocol/openid-connect/token/introspect Validación activa de token (M2M)
JWKS /realms/{realm}/protocol/openid-connect/certs Claves públicas para verificación JWT
UserInfo /realms/{realm}/protocol/openid-connect/userinfo Claims del usuario autenticado
Logout /realms/{realm}/protocol/openid-connect/logout Revocación de sesión y tokens
Discovery /realms/{realm}/.well-known/openid-configuration Metadatos del servidor OIDC

Configuración de clientes de referencia

# partner-portal-app — SPA pública con PKCE
client_id: partner-portal-app
access_type: PUBLIC
standard_flow_enabled: true
pkce_code_challenge_method: S256
valid_redirect_uris:
  - "https://partners.ejemplo.com/*"
web_origins:
  - "https://partners.ejemplo.com"
default_scopes: [openid, profile, email, roles]

# partner-service-m2m — servicio backend confidencial
client_id: partner-service-m2m
access_type: CONFIDENTIAL
service_accounts_enabled: true
standard_flow_enabled: false
default_scopes: [partner.read, partner.write]

Configuración de Token Service en Keycloak

Realm Settings > Tokens:
  Access Token Lifespan:         5 minutos
  Refresh Token Lifespan:        30 minutos
  SSO Session Idle:              30 minutos
  SSO Session Max:               10 horas
  Offline Session Idle:          30 días

Realm Settings > Keys:
  Active RSA provider:           rsa-generated (keysize: 2048)
  Signing Algorithm:             RS256
  Rotation: manual (via Keycloak Admin)

Flujo interno: Authorization Code con PKCE

sequenceDiagram
    actor SPA as partner-portal-app (SPA)
    participant AE as Authentication Engine
    participant CR as Client Registry
    participant US as User Storage
    participant TS as Token Service

    SPA->>AE: GET /auth?response_type=code&code_challenge=...
    AE->>CR: Validar client_id, redirect_uri, PKCE method
    CR-->>AE: Client válido, PKCE enforced
    AE-->>SPA: Renderizar login form

    SPA->>AE: POST credenciales (username, password)
    AE->>US: Verificar credenciales en PostgreSQL
    US-->>AE: Usuario válido, roles cargados
    AE-->>SPA: Redirect con authorization_code

    SPA->>AE: POST /token (code + code_verifier)
    AE->>AE: Verificar code_verifier vs code_challenge (SHA-256)
    AE->>TS: Emitir access_token + id_token + refresh_token
    TS-->>SPA: { access_token (JWT RS256), id_token, refresh_token }

Configuración de PostgreSQL como User Storage

Keycloak 26.x utiliza su proveedor JPA interno conectado a PostgreSQL. Las variables de entorno críticas en compose.yml:

environment:
  KC_DB: postgres
  KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
  KC_DB_USERNAME: keycloak
  KC_DB_PASSWORD: ${KC_DB_PASSWORD}
  KC_HOSTNAME: auth.ejemplo.com
  KC_HTTPS_CERTIFICATE_FILE: /opt/keycloak/conf/tls.crt
  KC_HTTPS_CERTIFICATE_KEY_FILE: /opt/keycloak/conf/tls.key
  KC_LOG_LEVEL: INFO

Consideraciones de alta disponibilidad (futuro)

Alcance MVP

En MVP se despliega un único nodo Keycloak. Para producción con HA se requiere:

  • Configurar KC_CACHE: ispn con JGroups para clustering
  • Usar un load balancer con sticky sessions o session replication
  • Externalizar el almacenamiento de sesiones a Infinispan externo
  • Configurar health checks: GET /health/ready y GET /health/live