No description
  • Gleam 97.5%
  • Shell 2.4%
Find a file
2026-03-20 09:00:19 -05:00
.opencode OpenCode configuration added with agents, commands, and skills 2026-03-19 11:29:21 -05:00
contracts first commit 2026-03-12 19:48:51 -05:00
dev first commit 2026-03-12 19:48:51 -05:00
docs Skills added and README.md detailed 2026-03-12 20:07:36 -05:00
scripts first commit 2026-03-12 19:48:51 -05:00
src Auth context facade and application layer implementation with use cases for users, roles, groups, and realms 2026-03-19 11:29:30 -05:00
test Test suite for auth context application layer with error mapping and use case coverage 2026-03-20 09:00:19 -05:00
.gitattributes first commit 2026-03-12 19:48:51 -05:00
.gitignore first commit 2026-03-12 19:48:51 -05:00
AGENTS.md OpenCode configuration added with agents, commands, and skills 2026-03-19 11:29:21 -05:00
docker-compose.yml first commit 2026-03-12 19:48:51 -05:00
Dockerfile first commit 2026-03-12 19:48:51 -05:00
e2e_output.txt first commit 2026-03-12 19:48:51 -05:00
gleam.toml first commit 2026-03-12 19:48:51 -05:00
manifest.toml first commit 2026-03-12 19:48:51 -05:00
openapi.yaml OpenCode configuration added with agents, commands, and skills 2026-03-19 11:29:21 -05:00
opencode.json OpenCode configuration added with agents, commands, and skills 2026-03-19 11:29:21 -05:00
POC.md OpenCode configuration added with agents, commands, and skills 2026-03-19 11:29:21 -05:00
README.auth_context.md OpenCode configuration added with agents, commands, and skills 2026-03-19 11:29:21 -05:00
README.md Skills added and README.md detailed 2026-03-12 20:07:36 -05:00

keycloak_wrapper

Package Version Hex Docs

A Gleam wrapper for the Keycloak REST API.

This library provides a type-safe, functional interface to interact with Keycloak's Admin REST API from your Gleam applications.

Tabla de contenidos

Requisitos previos

  • Gleam v1.0.0 o superior (recomendado v1.12+)
  • Erlang/OTP 27+ (viene con Gleam)
  • Docker y Docker Compose (para el entorno local)
  • curl (para verificaciones y obtener tokens)

Instalación como dependencia

Si quieres usar keycloak_wrapper en tu propio proyecto Gleam:

gleam add keycloak_wrapper

Quick start

import keycloak_wrapper/config
import keycloak_wrapper/auth
import keycloak_wrapper/users
import gleam/io

pub fn main() {
  // 1. Configurar cliente base
  let assert Ok(client) = config.new("http://localhost:8080", "master")

  // 2. Autenticarse como admin
  let credentials =
    auth.Password(client_id: "admin-cli", username: "admin", password: "admin")

  case auth.login(client, credentials) {
    Ok(authenticated_client) -> {
      io.println("Autenticado exitosamente!")

      // 3. Listar usuarios
      case users.list_users(authenticated_client, first: 0, max: 10, search: option.None) {
        Ok(user_list) -> io.println("Usuarios encontrados: " <> int.to_string(list.length(user_list)))
        Error(_) -> io.println("Error al listar usuarios")
      }
    }
    Error(_) -> io.println("Fallo en la autenticación")
  }
}

Despliegue local con Docker

El proyecto incluye un docker-compose.yml preconfigurado que levanta todos los servicios necesarios para desarrollo y pruebas locales.

Arquitectura de servicios

Servicio Puerto Descripción
keycloak 8080 Instancia de Keycloak 24.0.1 en modo desarrollo
keycloak-wrapper 8000 Servidor proxy que expone la API y el spec OpenAPI
swagger-ui 8081 Interfaz visual para explorar y probar la API

Paso 1 — Levantar el entorno completo

# Clonar el repositorio
git clone https://github.com/username/keycloak-wrapper.git
cd keycloak-wrapper

# Dar permisos a los scripts
chmod +x scripts/*.sh

# Levantar todo el entorno (Keycloak + Wrapper + Swagger UI)
./scripts/start-dev-env.sh

El script hace lo siguiente:

  1. Levanta Keycloak, keycloak-wrapper y Swagger UI con docker-compose
  2. Espera a que Keycloak esté saludable (healthcheck)
  3. Configura CORS en el cliente admin-cli para que Swagger UI pueda autenticarse
  4. Muestra las URLs de acceso

Primera ejecución: Docker descargará las imágenes necesarias (~500MB para Keycloak, ~200MB para Gleam). Las ejecuciones posteriores serán mucho más rápidas.

Paso 2 — Verificar que todo está corriendo

# Healthcheck del wrapper
curl -s http://localhost:8000/api/status
# Respuesta esperada: {"status": "ok"}

# Healthcheck de Keycloak
curl -s http://localhost:8080/health/ready
# Respuesta esperada: {"status": "UP", ...}

# Ver los logs de todos los servicios
docker-compose logs -f

Paso 3 — Obtener un token de administrador

Para interactuar con los endpoints /admin/ necesitas un Bearer token. Obtén uno con:

curl -s -X POST http://localhost:8000/realms/master/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password" \
  -d "client_id=admin-cli" \
  -d "username=admin" \
  -d "password=admin"

La respuesta incluye un campo access_token que puedes usar como Bearer token:

# Ejemplo de uso del token
export TOKEN="<pega aquí el access_token>"

curl -s http://localhost:8000/admin/realms/master/users \
  -H "Authorization: Bearer $TOKEN"

Nota: Los tokens expiran después de unos minutos. Si recibes un 401 Unauthorized, genera un nuevo token.

Paso 4 — Usar Swagger UI

  1. Abre http://localhost:8081 en tu navegador
  2. Haz clic en el botón verde "Authorize" (candado) en la parte superior
  3. Pega el access_token obtenido en el paso anterior en el campo de texto
  4. Haz clic en "Authorize" y luego en "Close"
  5. Ahora puedes ejecutar cualquier endpoint directamente desde Swagger UI

Importante: Todas las peticiones desde Swagger UI pasan a través del proxy keycloak-wrapper (puerto 8000), que las reenvía a Keycloak (puerto 8080). Esto permite probar la API exactamente como la consumirían tus aplicaciones.

Paso 5 — Crear un usuario con contraseña

Desde Swagger UI o con curl, puedes crear un usuario con una contraseña temporal en una sola llamada:

curl -s -X POST http://localhost:8000/admin/realms/master/users \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "nuevo_usuario",
    "email": "usuario@example.com",
    "firstName": "Nombre",
    "lastName": "Apellido",
    "enabled": true,
    "emailVerified": true,
    "credentials": [{
      "type": "password",
      "value": "mi_contraseña_temporal",
      "temporary": true
    }]
  }'
  • temporary: true — El usuario deberá cambiar su contraseña en el primer inicio de sesión
  • temporary: false — La contraseña es permanente

Si el usuario ya existe y necesitas resetear su contraseña:

curl -s -X PUT http://localhost:8000/admin/realms/master/users/{user_id}/reset-password \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "password",
    "value": "nueva_contraseña",
    "temporary": false
  }'

Para verificar que el usuario puede autenticarse:

curl -s -X POST http://localhost:8080/realms/master/protocol/openid-connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password" \
  -d "client_id=admin-cli" \
  -d "username=nuevo_usuario" \
  -d "password=mi_contraseña_temporal"

Detener el entorno

# Detiene todos los contenedores y elimina volúmenes
./scripts/stop-dev-env.sh

# O manualmente:
docker-compose down -v

Swagger UI y OpenAPI

El wrapper expone una especificación OpenAPI que documenta todos los endpoints disponibles.

URL Descripción
http://localhost:8081 Swagger UI (interfaz visual interactiva)
http://localhost:8000/openapi.yaml Especificación YAML directa
http://localhost:8000/api/status Healthcheck del wrapper

La especificación incluye endpoints para:

  • Auth — Obtener tokens (password grant, client credentials)
  • Users — CRUD de usuarios, asignación de contraseñas
  • Realms — Gestión de realms
  • Clients — Gestión de clientes OAuth2/OIDC
  • Groups — Gestión de grupos y membresías
  • Roles — Gestión de roles y asignaciones

Tests E2E automatizados

El proyecto incluye tests End-to-End que se ejecutan contra una instancia real de Keycloak en Docker.

# Ejecuta el ciclo completo: levanta Keycloak → corre tests → limpia todo
./scripts/run-e2e.sh

El script run-e2e.sh:

  1. Levanta únicamente el contenedor de Keycloak
  2. Espera a que pase el healthcheck
  3. Ejecuta gleam test dentro de un contenedor con ENABLE_E2E=true
  4. Limpia todos los contenedores y volúmenes al terminar

Los tests E2E cubren operaciones CRUD completas para: Users, Clients, Realms, Groups, Roles, y el ciclo de vida de contraseñas.

Tests unitarios

Para ejecutar solo los tests unitarios (sin necesidad de Docker ni Keycloak):

gleam test

Los tests E2E se saltan automáticamente si la variable ENABLE_E2E no está configurada como true.

Shell interactivo del wrapper

Si necesitas ejecutar comandos dentro del contenedor del wrapper (ej. gleam test, gleam shell):

# Requiere que el entorno de desarrollo esté corriendo
./scripts/wrapper-shell.sh

Arquitectura del proyecto

keycloak-wrapper/
├── src/keycloak_wrapper/
│   ├── auth.gleam          # Autenticación y tokens
│   ├── config.gleam        # Configuración del cliente
│   ├── users.gleam         # CRUD de usuarios y contraseñas
│   ├── realms.gleam        # Gestión de realms
│   ├── clients.gleam       # Gestión de clientes OAuth2
│   ├── groups.gleam        # Gestión de grupos
│   ├── roles.gleam         # Gestión de roles
│   ├── server.gleam        # Servidor HTTP (proxy + OpenAPI)
│   └── internal/
│       └── http_utils.gleam # Utilidades HTTP internas
├── test/
│   ├── e2e/                # Tests E2E contra Keycloak real
│   └── *_test.gleam        # Tests unitarios
├── scripts/                # Scripts de automatización
├── docs/                   # Documentación adicional (ADRs, RFs, etc.)
├── docker-compose.yml      # Orquestación de servicios
├── Dockerfile              # Imagen del wrapper
├── openapi.yaml            # Especificación OpenAPI
└── gleam.toml              # Configuración del proyecto Gleam

Para más detalles sobre los principios de diseño, consulta la documentación de arquitectura.

Módulos disponibles

Módulo Descripción
keycloak_wrapper/config Crear y configurar el cliente base (KeycloakClient)
keycloak_wrapper/auth Autenticación: login, get_token (Password y Client Credentials)
keycloak_wrapper/users CRUD de usuarios, set_user_password, crear con credenciales
keycloak_wrapper/realms CRUD de realms
keycloak_wrapper/clients CRUD de clientes OAuth2/OIDC
keycloak_wrapper/groups CRUD de grupos, membresías de usuarios
keycloak_wrapper/roles CRUD de roles, asignaciones a usuarios

Solución de problemas

401 Unauthorized al usar Swagger UI

Debes autenticarte primero. Haz clic en el botón "Authorize" en Swagger UI y pega un Bearer token válido. Los tokens expiran — genera uno nuevo si es necesario (ver Paso 3).

403 Forbidden desde Swagger UI

Esto ocurre si CORS no está configurado. El script start-dev-env.sh lo configura automáticamente. Si levantaste los servicios manualmente, ejecuta:

./scripts/setup-cors.sh

Keycloak no inicia

Verifica que Docker esté corriendo y que el puerto 8080 no esté en uso:

# Ver si hay algo usando el puerto
lsof -i :8080

# Ver los logs de Keycloak
docker-compose logs keycloak

Los tests E2E se saltan

Los tests E2E requieren la variable de entorno ENABLE_E2E=true. Usa el script run-e2e.sh que la configura automáticamente, o expórtala manualmente:

export ENABLE_E2E=true
gleam test

El wrapper no conecta con Keycloak

Dentro de Docker, los servicios se comunican por nombre de servicio (http://keycloak:8080). Desde tu máquina host, usa http://localhost:8080. El wrapper detecta automáticamente el contexto usando la variable KEYCLOAK_URL.

Contributing

Contributions are welcome! Please ensure your code passes formatting checks and tests before submitting a PR.

gleam format --check
gleam test

# Para ejecutar la suite completa incluyendo E2E:
./scripts/run-e2e.sh

Further documentation can be found at https://hexdocs.pm/keycloak_wrapper.