Files
Portainer/authentik/README.md
T
2026-07-25 11:20:27 +00:00

589 lines
20 KiB
Markdown

# Authentik - Sistema de Autenticación SSO
Authentik es un sistema de autenticación y autorización de código abierto que proporciona Single Sign-On (SSO) para tus aplicaciones.
## 📋 Descripción
Este stack despliega Authentik configurado para funcionar con Traefik mediante **Forward Authentication**, protegiendo tus servicios con autenticación centralizada.
## 🚀 Despliegue
### Desde Docker Compose
Asegurate de tener `authentik/.env` configurado y despliega:
```bash
cd authentik
docker compose --env-file .env up -d
```
### Variables de Entorno Importantes
Edita el archivo `.env` con tus valores:
```env
# Secretos (genera valores aleatorios seguros)
AUTHENTIK_SECRET_KEY=tu-clave-secreta-aleatoria
AUTHENTIK_POSTGRESQL_PASSWORD=tu-password-db-aleatorio
# Dominio de Authentik
AUTHENTIK_DOMAIN=auth.tudominio.com
# Email y SMTP (opcional pero recomendado)
AUTHENTIK_EMAIL__HOST=smtp.tudominio.com
AUTHENTIK_EMAIL__PORT=587
AUTHENTIK_EMAIL__USERNAME=noreply@tudominio.com
AUTHENTIK_EMAIL__PASSWORD=tu-password-email
AUTHENTIK_EMAIL__FROM=noreply@tudominio.com
```
## ⚙️ Configuración Post-Instalación
Una vez desplegado Authentik, accede a su interfaz web en `https://auth.tudominio.com` y completa la configuración inicial.
### 1. Acceso Inicial
- Usuario por defecto: `akadmin`
- Contraseña: La que configures en el primer acceso
- Cambia la contraseña inmediatamente
### 2. Crear Applications (Aplicaciones)
Para cada servicio que quieras proteger (ej: Traefik Dashboard, Gitea, Dozzle, etc.):
1. Ve a **Applications****Create**
2. Completa el formulario:
- **Name**: `Mi App` (nombre descriptivo)
- **Slug**: `miapp` (identificador único en minúsculas)
- **Provider**: (lo crearás en el siguiente paso - déjalo vacío por ahora)
- **Policy engine mode**: `any` (permite acceso si alguna política coincide)
- **UI settings**: Configura el icono y apariencia (opcional)
3. Haz clic en **Create**
### 3. Crear Providers de tipo Forward Auth
Los providers conectan tus aplicaciones con Authentik. Para Forward Auth con Traefik:
1. Ve a **Applications** → Tu aplicación → **Provider****Create**
2. Selecciona tipo: **Proxy Provider**
3. Completa el formulario:
- **Name**: `Mi App Provider`
- **Authorization flow**: Selecciona `default-provider-authorization-implicit-consent` (créalo si no existe - ver paso 4)
- **Type**: **Forward auth (single application)**
- **External host**: `https://miapp.tudominio.com` (URL completa de tu servicio)
- **Internal host**: `http://miapp:8080` (opcional - URL interna si Authentik debe hacer reverse proxy)
- **Internal host SSL validation**: Desactivado (si usas HTTP interno)
4. **Advanced settings**:
- **Token validity**: `hours=24` (duración de la sesión)
- **Cookie domain**: `.tudominio.com` (permite SSO entre subdominios)
5. Haz clic en **Create**
6. Vuelve a la aplicación y selecciona el provider que acabas de crear
### 4. Crear Authorization Flow (Implicit)
El authorization flow de tipo **implicit** permite autorización sin pantalla de consentimiento explícita:
#### Opción A: Usar el flow por defecto
Authentik suele incluir un flow llamado `default-provider-authorization-implicit-consent`. Si existe, úsalo directamente en tus providers.
#### Opción B: Crear un flow personalizado
Si necesitas crear uno nuevo:
1. Ve a **Flows & Stages****Flows****Create**
2. Completa el formulario:
- **Name**: `Authorization Flow Implicit`
- **Title**: `Redirecting to application`
- **Slug**: `default-provider-authorization-implicit-consent`
- **Designation**: **Authorization**
- **Authentication**: `Require authentication` (el usuario debe estar autenticado)
- **Behavior settings**:
- **Layout**: `content_left` o el que prefieras
3. Haz clic en **Create**
#### Añadir Stages al Flow
1. Abre el flow que acabas de crear
2. Ve a la pestaña **Stage Bindings**
3. Añade el stage de consentimiento (opcional):
- Haz clic en **Bind existing stage**
- Selecciona `default-provider-authorization-consent` (o crea uno nuevo)
- **Order**: 10
- **Evaluate on plan**: Activado
- **Re-evaluate policies**: Activado
> **Nota**: Para implicit consent, puedes crear un flow sin stages de consentimiento, lo que permite autorización automática.
#### Crear Stage de Consent (si no existe)
Si necesitas crear el stage de consentimiento:
1. Ve a **Flows & Stages****Stages****Create**
2. Tipo: **Consent Stage**
3. Completa:
- **Name**: `default-provider-authorization-consent`
- **Mode**: `always_require` o `hidden` (para implicit)
- **Consent expire in**: `weeks=4` (duración del consentimiento)
4. Haz clic en **Create**
### 5. Configurar Outpost
Los **outposts** son los componentes que ejecutan los providers y procesan las peticiones de autenticación:
1. Ve a **Outposts****Outposts****Create**
2. Completa el formulario:
- **Name**: `authentik-embedded-outpost` (o el nombre que prefieras)
- **Type**: **Proxy**
- **Integration**: Déjalo vacío (el outpost embedded usa la integración por defecto)
3. **Applications**: Selecciona todas las aplicaciones que creaste (Traefik, Gitea, Dozzle, etc.)
4. **Configuration**:
```yaml
authentik_host: https://auth.tudominio.com
authentik_host_insecure: false
log_level: info
object_naming_template: ak-outpost-%(name)s
docker_network: proxy
docker_labels:
traefik.enable: "true"
```
5. Haz clic en **Create**
#### Verificar Estado del Outpost
1. Ve a **Outposts** → **Outposts**
2. Verifica que tu outpost aparece en estado **Healthy** (saludable)
3. Si aparece como **Unhealthy**:
- Verifica los logs: `docker logs authentik-worker`
- Asegúrate de que el contenedor puede comunicarse con el servidor de Authentik
- Verifica la red Docker `proxy`
### 6. Configurar Middleware en Traefik
Para que Traefik use Authentik como forward auth, necesitas configurar el middleware.
#### Opción A: Middleware en el stack de Authentik
Añade las siguientes labels al servicio `authentik-server` en el `docker-compose.yml`:
```yaml
labels:
# Middleware de Forward Auth
traefik.http.middlewares.authentik.forwardauth.address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: "true"
traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: "X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid"
```
#### Opción B: Middleware en archivo de configuración de Traefik
En el archivo de configuración dinámica de Traefik (`dynamic.yml`):
```yaml
http:
middlewares:
authentik:
forwardAuth:
address: "http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
trustForwardHeader: true
authResponseHeaders:
- "X-authentik-username"
- "X-authentik-groups"
- "X-authentik-email"
- "X-authentik-name"
- "X-authentik-uid"
```
### 7. Proteger Servicios con Authentik
Una vez configurado el middleware, añade la label a los servicios que quieras proteger:
```yaml
labels:
traefik.http.routers.miapp.middlewares: "ths-authentik@docker"
```
O si definiste el middleware en archivo:
```yaml
labels:
traefik.http.routers.miapp.middlewares: "authentik@file"
```
### 7.1 Patrón recomendado para nuevas apps
En este repositorio, **proteger un servicio con `ths-authentik@docker` no es suficiente por sí solo**. Además del middleware en Traefik, debes crear en Authentik:
1. un **Proxy Provider**
2. una **Application**
3. y asociar ese provider al **`authentik Embedded Outpost`**
Si falta cualquiera de esas piezas, el síntoma típico es ver una página de Authentik con **`Not Found`** al entrar al dominio protegido.
#### Patrón que seguimos
Para una nueva app publicada detrás de Traefik, usa este esquema:
1. **En el stack Docker del servicio**
- Añade el router de Traefik para el dominio final
- Añade el middleware:
```yaml
labels:
traefik.http.routers.mi-app.middlewares: "ths-authentik@docker"
```
2. **En Authentik crea un Proxy Provider**
- **Name**: `Provider for Mi App`
- **Mode**: `forward_single`
- **External host**: `https://mi-app.tudominio.com`
- **Authorization flow**: el mismo flow compartido que ya usan las demás apps protegidas
- **Intercept header authentication**: activado
3. **En Authentik crea una Application**
- **Name**: `Mi App`
- **Slug**: `mi-app`
- **Provider**: el provider creado en el paso anterior
- **Launch URL**: `https://mi-app.tudominio.com`
- **Group**: la categoría que te convenga en el portal de Authentik
4. **Añade el provider al `authentik Embedded Outpost`**
- Ve a **Outposts** → **authentik Embedded Outpost**
- Añade el nuevo provider a la lista de aplicaciones/providers publicados por el outpost
#### Qué copiar de una app existente
Si ya tienes una app similar funcionando, lo más seguro es **replicar su patrón**:
- reutiliza el mismo **authorization flow**
- reutiliza el mismo **mode** (`forward_single`)
- deja `authentication_flow` vacío si el patrón existente también lo deja vacío
- mantén `intercept_header_auth` activado si sigues el patrón actual del repositorio
Las referencias más claras en este entorno son:
- `Provider for Homepage`
- `Provider for Dozzle`
- `PiHole`
#### Checklist rápida antes de dar una app por buena
1. El servicio responde internamente por su puerto/URL local
2. Traefik tiene el router correcto para el dominio
3. El router usa `ths-authentik@docker`
4. Existe un **Proxy Provider** con el **External host** exacto
5. Existe una **Application** enlazada a ese provider
6. El provider está añadido al **Embedded Outpost**
7. El outpost está **Healthy**
8. El dominio resuelve DNS hacia el servidor
#### Verificación rápida
Desde el host, una app bien enlazada con Authentik suele devolver un `302` hacia Authentik cuando no hay sesión:
```bash
curl -k -I https://mi-app.tudominio.com
```
Si ves:
- **`302` a `/application/o/authorize/`** → el patrón está bien enlazado
- **página `Not Found` de Authentik** → falta provider/app/outpost o están mal enlazados
- **`404/502` de Traefik** → problema de router, servicio o resolución
### 7.2 Automatizar con la API (sin usar la UI)
Se puede crear una aplicación completa (Provider + Application + Outpost) mediante la API REST de Authentik sin tocar la interfaz web. Esto es útil para automatizar despliegues o cuando ya conoces el patrón exacto.
#### Patrón de llamadas API
El script `create-auth-app.sh` encapsula estas 3 llamadas:
**1. Crear Proxy Provider**
```bash
curl -sk -X POST "https://auth.tudominio.com/api/v3/providers/proxy/" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"name": "Provider for Mi App",
"authentication_flow": null,
"authorization_flow": "<FLOW_UUID>",
"invalidation_flow": "<INVAL_FLOW_UUID>",
"property_mappings": ["<UUID1>","<UUID2>","<UUID3>","<UUID4>","<UUID5>"],
"external_host": "https://mi-app.midominio.com",
"internal_host": "",
"internal_host_ssl_validation": true,
"mode": "forward_single",
"intercept_header_auth": true,
"cookie_domain": "",
"access_token_validity": "hours=1",
"refresh_token_validity": "days=30"
}'
```
**2. Crear Application**
```bash
curl -sk -X POST "https://auth.tudominio.com/api/v3/core/applications/" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"name": "Mi App",
"slug": "mi-app",
"provider": <PROVIDER_PK>,
"policy_engine_mode": "any",
"meta_launch_url": "https://mi-app.midominio.com"
}'
```
**3. Añadir al Embedded Outpost**
```bash
curl -sk -X PATCH "https://auth.tudominio.com/api/v3/outposts/instances/<OUTPOST_UUID>/" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{"providers": [<existing_pks>, <new_pk>]}'
```
> Los UUIDs de los flows (`FLOW_UUID`, `INVAL_FLOW_UUID`) y property mappings se copian de un provider existente. El script los obtiene automáticamente.
#### Generar un token de API
El script genera un token temporal automáticamente mediante `ak shell` dentro del contenedor. Si quieres hacerlo manual:
```bash
docker exec ths-authentik-server bash -c 'echo "
from authentik.core.models import Token, User
u = User.objects.filter(username=\"akadmin\").first()
t, _ = Token.objects.update_or_create(user=u, identifier=\"mi-script\",
defaults={\"intent\": \"api\", \"expiring\": True})
print(t.key)
" | ak shell 2>/dev/null' | tail -1
```
### 7.3 Script automatizado: `create-auth-app.sh`
El script `create-auth-app.sh` en este directorio automatiza todo el proceso. Basta con pasarle el dominio y opcionalmente el nombre y slug.
#### Uso
```bash
cd authentik
./create-auth-app.sh <dominio> [nombre] [slug]
```
**Ejemplos:**
```bash
# Especificando todo
./create-auth-app.sh crowdsec.sherlockhomeless.net CrowdSec crowdsec
# Solo dominio (nombre y slug se derivan automáticamente)
./create-auth-app.sh mi-app.sherlockhomeless.net
# → nombre: "Mi App", slug: "mi-app"
# Con nombre personalizado pero slug automático
./create-auth-app.sh dashboard.sherlockhomeless.net "Mi Dashboard"
# → nombre: "Mi Dashboard", slug: "dashboard"
```
#### Qué hace el script
| Paso | Acción |
|------|--------|
| 1 | Genera un token temporal de API usando `ak shell` |
| 2 | Localiza el authorization flow `default-provider-authorization-implicit-consent` |
| 3 | Crea un **Proxy Provider** (o lo salta si ya existe para ese `external_host`) |
| 4 | Crea una **Application** (o la salta si ya existe ese slug) |
| 5 | Localiza el **Embedded Outpost** |
| 6 | Añade el provider al outpost (o lo salta si ya está asociado) |
| Verificación | Comprueba que el dominio redirige a Authentik (HTTP 302) |
#### Requisitos
- Contenedor `ths-authentik-server` corriendo y healthy
- `jq` instalado (`sudo apt install jq`)
- El archivo `.env` en el directorio `authentik/` (opcional, para leer `AUTHENTIK_DOMAIN`)
#### Idempotencia
El script es seguro re-ejecutarlo. Si el provider, aplicación o asociación ya existen, los salta y continúa. Ideal para usarlo en despliegues repetibles o CI/CD.
#### Salida esperada
```
=========================================
Authentik — Crear Application
=========================================
Dominio: crowdsec.sherlockhomeless.net
External host: https://crowdsec.sherlockhomeless.net
Nombre app: CrowdSec
Slug: crowdsec
=========================================
[1/6] Generando token temporal de API...
Token obtenido correctamente.
[2/6] Buscando authorization flow (implicit-consent)...
Flow UUID: 08080511-9d73-45f4-b394-19b5a2452422
[3/6] Verificando si ya existe un provider...
Provider creado: pk=39
[4/6] Verificando si ya existe la aplicación...
Aplicación creada: pk=51f0c37d-...
[5/6] Buscando el Embedded Outpost...
Outpost UUID: 27a4dc69-cefa-4575-b853-caed79515a13
[6/6] Añadiendo provider al outpost...
Provider añadido al outpost.
=========================================
Verificación
=========================================
OK: https://crowdsec.sherlockhomeless.net redirige a Authentik (302)
=========================================
Resumen
=========================================
Provider: Provider for CrowdSec (pk=39)
Application: CrowdSec (slug=crowdsec, pk=51f0c37d-...)
Outpost: authentik Embedded Outpost (...)
URL: https://crowdsec.sherlockhomeless.net
=========================================
```
#### Casos especiales
- **Servicios con widget en Homepage**: una cosa es proteger la UI pública con Authentik y otra la URL interna que Homepage usa para el widget. Homepage normalmente debe hablar con la app por red Docker interna, no pasando por el login web.
- **Servicios con auth propia + Homepage widget**: a menudo conviene dejar la UI pública protegida por Authentik, pero el widget de Homepage apuntando a la URL interna con credenciales/API key propias.
## 🔐 Gestión de Usuarios y Grupos
### Crear Usuarios
1. Ve a **Directory** → **Users** → **Create**
2. Completa los datos del usuario
3. Asigna grupos si es necesario
4. Haz clic en **Create**
### Crear Grupos
1. Ve a **Directory** → **Groups** → **Create**
2. Nombre del grupo (ej: `admins`, `users`)
3. Añade usuarios al grupo
4. Haz clic en **Create**
### Crear Políticas de Acceso
Para controlar quién puede acceder a cada aplicación:
1. Ve a **Applications** → Tu aplicación → **Policy / Group / User Bindings**
2. Haz clic en **Bind existing policy/group/user**
3. Selecciona un grupo (ej: `admins`)
4. **Order**: 0 (menor número = mayor prioridad)
5. Haz clic en **Create**
## 🔧 Configuración Avanzada
### Configurar Múltiples Dominios (SSO entre subdominios)
En la configuración del provider:
- **Cookie domain**: `.tudominio.com` (con el punto inicial)
- Esto permite que la sesión se comparta entre todos los subdominios
### Configurar Email (SMTP)
Para notificaciones y recuperación de contraseñas:
1. Ve a **System** → **Settings** → **Email**
2. Configura los parámetros SMTP (o usa las variables de entorno en `.env`)
### Configurar Autenticación de Dos Factores (2FA)
1. Ve a **Flows & Stages** → **Stages**
2. Crea stages de tipo **Authenticator Validation Stage** (TOTP, WebAuthn, etc.)
3. Añade estos stages a tu authentication flow
### Integración con Proveedores Externos (OAuth, SAML)
1. Ve a **System** → **Providers** → **Create**
2. Selecciona el tipo (OAuth2, SAML, etc.)
3. Configura según el proveedor externo (Google, GitHub, etc.)
## 🛠️ Troubleshooting
### El outpost aparece como Unhealthy
```bash
# Ver logs del worker
docker logs authentik-worker
# Ver logs del servidor
docker logs authentik-server
# Verificar conectividad de red
docker exec authentik-server ping authentik-postgresql
docker exec authentik-server ping authentik-redis
```
### Los servicios no están protegidos
1. Verifica que el middleware de Traefik esté correctamente configurado
2. Comprueba que las labels en el servicio están correctas
3. Verifica los logs de Traefik: `docker logs traefik`
4. Asegúrate de que el provider está asociado a la aplicación
5. Verifica que el outpost esté en estado **Healthy**
### Error "Invalid redirect_uri"
1. Verifica que el **External host** en el provider coincide exactamente con la URL del servicio
2. Asegúrate de incluir el protocolo (`https://`)
3. No incluyas barras finales
### Sesiones no persisten / Se desconecta constantemente
1. Verifica que el **Cookie domain** esté configurado correctamente (`.tudominio.com`)
2. Comprueba que Redis esté funcionando: `docker logs authentik-redis`
3. Aumenta el **Token validity** en el provider
### No puedo acceder al panel de Authentik
1. Accede directamente por IP: `http://IP-servidor:9000`
2. Verifica los logs: `docker logs authentik-server`
3. Comprueba que el dominio DNS está configurado correctamente
4. Verifica que Traefik está redirigiendo correctamente
## 📚 Recursos Adicionales
- [Documentación oficial de Authentik](https://goauthentik.io/docs/)
- [Authentik con Traefik](https://goauthentik.io/docs/providers/proxy/forward_auth)
- [Configuración de Flows](https://goauthentik.io/docs/flow/)
- [Configuración de Outposts](https://goauthentik.io/docs/outposts/)
## 🔒 Seguridad
- **Cambia inmediatamente** el password por defecto de `akadmin`
- Genera valores **aleatorios** para `AUTHENTIK_SECRET_KEY` y `AUTHENTIK_POSTGRESQL_PASSWORD`
- Habilita **2FA** para usuarios administradores
- Realiza **backups regulares** de la base de datos PostgreSQL
- Mantén Authentik **actualizado** a la última versión
## 💾 Backups
Para hacer backup de la configuración de Authentik:
```bash
# Backup de la base de datos PostgreSQL
docker exec authentik-postgresql pg_dump -U authentik authentik > authentik_backup.sql
# Backup de Redis (sesiones)
docker exec authentik-redis redis-cli --rdb /data/dump.rdb
```
## 🔄 Actualizaciones
1. Edita `.env` y actualiza las versiones de las imagenes si es necesario.
2. Ejecuta:
```bash
cd authentik
docker compose --env-file .env pull
docker compose --env-file .env up -d
```