Files
Portainer/authentik

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:

cd authentik
docker compose --env-file .env up -d

Variables de Entorno Importantes

Edita el archivo .env con tus valores:

# 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 ApplicationsCreate
  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 → ProviderCreate
  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 & StagesFlowsCreate
  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.

Si necesitas crear el stage de consentimiento:

  1. Ve a Flows & StagesStagesCreate
  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 OutpostsOutpostsCreate
  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:
    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 OutpostsOutposts
  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:

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):

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:

labels:
  traefik.http.routers.miapp.middlewares: "ths-authentik@docker"

O si definiste el middleware en archivo:

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:
    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 Outpostsauthentik 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:

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

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

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

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:

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

cd authentik
./create-auth-app.sh <dominio> [nombre] [slug]

Ejemplos:

# 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 DirectoryUsersCreate
  2. Completa los datos del usuario
  3. Asigna grupos si es necesario
  4. Haz clic en Create

Crear Grupos

  1. Ve a DirectoryGroupsCreate
  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 SystemSettingsEmail
  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 & StagesStages
  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 SystemProvidersCreate
  2. Selecciona el tipo (OAuth2, SAML, etc.)
  3. Configura según el proveedor externo (Google, GitHub, etc.)

🛠️ Troubleshooting

El outpost aparece como Unhealthy

# 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

🔒 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:

# 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:
    cd authentik
    docker compose --env-file .env pull
    docker compose --env-file .env up -d