- Gleam 97.5%
- Shell 2.4%
| .opencode | ||
| contracts | ||
| dev | ||
| docs | ||
| scripts | ||
| src | ||
| test | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| docker-compose.yml | ||
| Dockerfile | ||
| e2e_output.txt | ||
| gleam.toml | ||
| manifest.toml | ||
| openapi.yaml | ||
| opencode.json | ||
| POC.md | ||
| README.auth_context.md | ||
| README.md | ||
keycloak_wrapper
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
- keycloak_wrapper
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:
- Levanta Keycloak, keycloak-wrapper y Swagger UI con
docker-compose - Espera a que Keycloak esté saludable (healthcheck)
- Configura CORS en el cliente
admin-clipara que Swagger UI pueda autenticarse - 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
- Abre http://localhost:8081 en tu navegador
- Haz clic en el botón verde "Authorize" (candado) en la parte superior
- Pega el
access_tokenobtenido en el paso anterior en el campo de texto - Haz clic en "Authorize" y luego en "Close"
- 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óntemporary: 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:
- Levanta únicamente el contenedor de Keycloak
- Espera a que pase el healthcheck
- Ejecuta
gleam testdentro de un contenedor conENABLE_E2E=true - 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.