Authentik con Docker: SSO y forward auth en Traefik
Configura Authentik 2026.5 con Docker Compose: secretos, usuario akadmin y forward auth en Traefik para proteger tus aplicaciones con un solo inicio de sesión.
Un inicio de sesión para todas las aplicaciones alojadas
Authentik es un servidor SSO (inicio de sesión único) autohospedado: los usuarios inician sesión una vez y todas las aplicaciones protegidas aceptan esa sesión en lugar de solicitar su propia contraseña. La instalación utiliza un archivo oficial de Docker Compose y dos secretos generados. La parte que requiere más trabajo viene después: apuntar un proxy inverso hacia él y proteger una aplicación existente mediante autenticación delegada.
Authentik se distribuye como tres servicios en ese archivo de Compose: una base de datos PostgreSQL, un proceso server y un proceso worker. El contenedor del servidor también ejecuta el outpost integrado, que es el componente que responde a «¿esta petición tiene una sesión iniciada?» para cada aplicación protegida. La versión 2026.5 es la versión actual en julio de 2026, y el proyecto solicita un host con al menos 2 núcleos de CPU y 2 GB de RAM. Considere esto el mínimo. PostgreSQL y el worker mantienen memoria ocupada después de que el servidor lleva un día funcionando.
Qué necesitas antes de empezar
Necesitas Docker Engine con el complemento Compose v2. Puedes confirmarlo con docker compose version. Si muestra un error en lugar de una versión, instala el complemento antes de continuar. Los conceptos básicos se explican en ejecutar aplicaciones con Docker Compose en un VPS. También necesitas un registro DNS A que apunte al servidor, auth.example.com en los ejemplos siguientes, porque Authentik construye sus URL de redirección a partir del nombre de host que utiliza el navegador.
Ejecuta la pila con un usuario normal que pertenezca al grupo docker, no como root. La pertenencia a ese grupo equivale a root en el host. Por tanto, asígnala a una sola cuenta de despliegue y a nadie más, siguiendo un enfoque similar al de cuentas de usuario con privilegios mínimos en un VPS.
Instalar con el archivo oficial de Compose
sudo install -d -o "$USER" -g "$USER" /opt/authentik
cd /opt/authentik
wget https://docs.goauthentik.io/compose.yml
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env
docker compose pull
docker compose up -ddocker compose ps debe mostrar tres contenedores. postgresql debe indicar healthy y server debe indicar worker y running. El primer arranque ejecuta las migraciones de la base de datos, por lo que debe esperar un minuto antes de que la interfaz web responda.
Ambos valores generados son importantes, por motivos distintos. PG_PASS es la contraseña de PostgreSQL y tiene un límite estricto de 99 caracteres. AUTHENTIK_SECRET_KEY firma las sesiones y los tokens, por lo que cambiarlo más adelante cierra la sesión de todos los usuarios e invalida todos los tokens de API emitidos. Mantenga .env con el modo 600 y guarde una copia en un lugar seguro, porque una base de datos restaurada sin su clave secreta correspondiente es una base de datos en la que nadie puede iniciar sesión.
El archivo de Compose lee ambos valores con el formato ${PG_PASS:?database password required}, lo que significa que Compose se niega a iniciar si falta el archivo. Ejecutar docker compose up -d desde el directorio incorrecto muestra required variable AUTHENTIK_SECRET_KEY is missing a value: secret key required y se detiene. Ese mensaje indica un problema de ruta, no un problema de configuración.
Los valores del entorno importantes
Todo lo demás va en el mismo archivo .env. Authentik convierte un guion bajo doble en una clave de configuración anidada, por lo que AUTHENTIK_EMAIL__HOST establece email.host. Un guion bajo simple se ignora sin mostrar ninguna advertencia. Esta es la causa más habitual de que un ajuste parezca no tener efecto.
AUTHENTIK_BOOTSTRAP_PASSWORDestablece la contraseña del usuarioakadminintegrado durante el primer arranque. Así nunca se escribe en un formulario web público.AUTHENTIK_BOOTSTRAP_EMAILyAUTHENTIK_BOOTSTRAP_TOKENestablecen del mismo modo la dirección de ese usuario y un token de API.COMPOSE_PORT_HTTPyCOMPOSE_PORT_HTTPScambian los puertos publicados de los valores predeterminados 9000 y 9443.AUTHENTIK_EMAIL__HOST,AUTHENTIK_EMAIL__PORT,AUTHENTIK_EMAIL__USERNAME,AUTHENTIK_EMAIL__PASSWORD,AUTHENTIK_EMAIL__USE_TLSyAUTHENTIK_EMAIL__FROMconfiguran el correo saliente. Sin estos valores, Authentik intenta usarlocalhosten el puerto 25. Por eso los mensajes de restablecimiento de contraseña terminan con un error de conexión en el registro del worker.AUTHENTIK_LOG_LEVEL=debugactiva el nivel de detalle necesario mientras un flujo de inicio de sesión funciona de forma incorrecta. Después, devuélvalo ainfo.AUTHENTIK_ERROR_REPORTING__ENABLEDesfalsede forma predeterminada. Establézcalo entruesólo si acepta enviar informes de errores al proveedor.
Estos son secretos almacenados en un archivo sin cifrar. Trate el directorio como cualquier otro almacén de credenciales. Un gestor de contraseñas, como una instancia de Vaultwarden autohospedada, es un lugar más adecuado para guardar la copia de recuperación que una nota en su portátil.
Primer inicio de sesión y la cuenta de administración
Abra http://SERVER_IP:9000 en un navegador. Authentik muestra el flujo de configuración inicial y le pide establecer una contraseña para el usuario akadmin predeterminado. Si ya configuró AUTHENTIK_BOOTSTRAP_PASSWORD, ese paso ya está completado y accederá directamente a la página de inicio de sesión.
Cree un usuario administrador normal para su uso en Directory y después en Users, añádalo al grupo authentik Admins e inicie sesión con esa cuenta. Deje akadmin como cuenta de emergencia, con una contraseña larga almacenada sin conexión. El trabajo diario con una cuenta integrada compartida destruye el registro de auditoría, porque todos los eventos indican akadmin y no muestran quién los generó. Este argumento también se aplica después de Authentik: algo como un sistema OneCLI autoalojado que proporciona a cada persona su propio agente sólo deja un registro legible si la identidad que llega pertenece a una sola persona y no es un inicio de sesión compartido por todo el equipo.
Colocar Authentik detrás de tu proxy inverso
Publicar el puerto 9000 en Internet funciona, pero necesitas TLS (seguridad de la capa de transporte) y un nombre de host real. Si ya utilizas la configuración de Traefik como proxy inverso para varias aplicaciones de Compose, conecta Authentik a la misma red externa proxy mediante un archivo de sustitución. Crea docker-compose.override.yml junto a compose.yml:
services:
server:
networks:
- default
- proxy
labels:
traefik.enable: "true"
traefik.docker.network: proxy
traefik.http.routers.authentik.rule: Host(`auth.example.com`)
traefik.http.routers.authentik.entrypoints: websecure
traefik.http.routers.authentik.tls.certresolver: le
traefik.http.services.authentik.loadbalancer.server.port: "9000"
networks:
proxy:
external: trueAplícalo con docker compose up -d. Compose combina automáticamente el archivo de sustitución, por lo que el servicio server conserva todo lo definido en el archivo oficial y añade las etiquetas. Compruébalo con curl -I https://auth.example.com/if/user/, que debería responder HTTP/2 200. Un 404 page not found de Traefik indica que el contenedor no está conectado a la red proxy, y Traefik no puede encaminar peticiones a un contenedor al que no puede acceder.
Cuando el nombre de host funcione, enlaza los puertos publicados a 127.0.0.1 en el archivo de sustitución, de modo que el único acceso sea a través del proxy.
Proteger una aplicación con forward auth
El proveedor de proxy de Authentik tiene tres modos, y elegir el incorrecto puede costar una hora. Proxy significa que el propio outpost reenvía el tráfico a la aplicación upstream. Forward auth (single application) significa que su propio reverse proxy sigue gestionando el tráfico y sólo pregunta a Authentik si la solicitud tiene una sesión iniciada. Forward auth (domain level) protege todas las aplicaciones de un mismo dominio principal con un único proveedor, pero impide definir reglas de autorización específicas para cada aplicación. Con Traefik delante, debe usar forward auth (single application). Si quiere una aplicación concreta para practicar, algo como un espacio de trabajo AFFiNE autohospedado es un buen primer candidato, porque es el tipo de herramienta interna que quiere que sea accesible desde sus propios dispositivos y desde ningún otro lugar. Una herramienta de equipo hace que el caso sea aún más claro: coloque un sistema de soporte Chatwoot autohospedado detrás del mismo proveedor para que todos los usuarios que responden a la bandeja de entrada inicien sesión una vez al día en lugar de compartir otra contraseña.
En la interfaz web, abra Applications y después Providers, cree un Proxy Provider, seleccione el modo forward auth single application y establezca el host externo en https://app.example.com. Cree una Application que apunte a ese proveedor. Después abra Outposts, edite authentik Embedded Outpost y añada la nueva aplicación a sus aplicaciones seleccionadas. El outpost sólo responde para las aplicaciones que tiene asignadas. Por eso, si omite este último paso, un proveedor configurado correctamente no devuelve ninguna respuesta.
Defina el middleware una sola vez, en el contenedor de Authentik, y haga referencia a él desde cada aplicación protegida:
traefik.http.middlewares.authentik.forwardauth.address: http://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,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-versionauthResponseHeaders es la lista de cabeceras que Traefik copia de la respuesta de Authentik en la petición que envía al upstream. Si la omite, la aplicación sigue protegida, pero nunca sabe quién es el usuario. Por tanto, cualquier componente que lea X-authentik-username para iniciar sesión automáticamente permanece sin autenticar. Esta diferencia es más evidente delante de una aplicación que mantiene su propio inicio de sesión, como un rastreador de entrenamientos openGym autohospedado y su inicio de sesión con passkey, donde las cabeceras determinan si la misma página muestra una solicitud o dos.
La aplicación protegida necesita dos routers, no uno:
labels:
traefik.enable: "true"
traefik.http.routers.myapp.rule: Host(`app.example.com`)
traefik.http.routers.myapp.entrypoints: websecure
traefik.http.routers.myapp.tls.certresolver: le
traefik.http.routers.myapp.middlewares: authentik@docker
traefik.http.routers.myapp-auth.rule: Host(`app.example.com`) && PathPrefix(`/outpost.goauthentik.io/`)
traefik.http.routers.myapp-auth.entrypoints: websecure
traefik.http.routers.myapp-auth.tls.certresolver: le
traefik.http.routers.myapp-auth.priority: "15"
traefik.http.routers.myapp-auth.service: authentikEl segundo router es la parte que todo el mundo omite. Después de iniciar sesión, Authentik devuelve el navegador a una ruta bajo /outpost.goauthentik.io/ en el hostname de la aplicación, no en auth.example.com. Sin un router que envíe ese prefijo de ruta al servicio de Authentik, la petición llega a la aplicación, que responde con 404, y el inicio de sesión nunca termina. El valor superior de priority hace que la regla de ruta específica tenga prioridad sobre la regla Host() simple del mismo dominio.
Pruébelo en una ventana privada del navegador. Debería ser redirigido a auth.example.com, iniciar sesión y volver a la aplicación. docker compose logs -f server, en el lado de Authentik, muestra un evento de autorización por intento. Esto permite comprobar si la petición llegó a Authentik.
Los fallos que encontrará realmente
Bucle de redirección infinito entre la aplicación y la página de inicio de sesión. El host externo configurado en el proveedor no coincide con el que usa el navegador. Normalmente, http:// en el proveedor no coincide con https:// en la barra de direcciones. La cookie de sesión se establece entonces para un origen diferente, por lo que cada vuelta se interpreta como una nueva solicitud anónima. Corrija el host externo y elimine las cookies de ambos dominios antes de volver a probar.
404 en /outpost.goauthentik.io/start. Falta el router de outpost o su prioridad es menor que la del router general para ese host.
La aplicación carga sin solicitar un inicio de sesión. La etiqueta middlewares hace referencia a un middleware que no existe. Traefik no muestra una advertencia en este caso, por lo que un error tipográfico en authentik@docker simplemente hace que no se ejecute ningún middleware. Abra el panel de Traefik y confirme que el router incluye el middleware.
403 de Authentik después de un inicio de sesión correcto. El usuario está autenticado, pero no autorizado. La aplicación tiene asociada una política o exige pertenecer a un grupo que este usuario no cumple. El registro Events de la interfaz de administración indica la política que denegó el acceso.
Cuándo encaja mejor Keycloak
Keycloak es el proyecto más antiguo, respaldado por Red Hat, y es la opción más sólida para los casos clásicos de identidad empresarial: federación SAML intensiva, gestión de inicios de sesión mediante varios proveedores de identidad externos a la vez y exportación e importación de realms como ruta de migración documentada. Para algunas organizaciones, el soporte comercial que lo respalda también es importante sobre el papel. La contrapartida es que Keycloak no incluye su propio proxy. Por tanto, para proteger una aplicación que no admite OIDC (OpenID Connect), hay que ejecutar junto a él una herramienta como oauth2-proxy. El proveedor de proxy integrado de Authentik ya incluye esa función y está integrado con el resto del sistema. Por eso, la mayoría de los usuarios que administran por su cuenta un conjunto heterogéneo de aplicaciones terminan eligiendo Authentik.
Copias de seguridad y actualizaciones
Tres elementos permiten restaurar el servicio: la base de datos de PostgreSQL, el directorio ./data y .env.
cd /opt/authentik
docker compose exec -T postgresql pg_dump -U authentik authentik | gzip > authentik-$(date +%F).sql.gzGuarde juntos ese volcado y .env. El volcado por sí solo no basta, porque la clave secreta que protege los datos de sesión y de tokens se encuentra en .env.
Las actualizaciones consisten en cambiar una etiqueta. Establezca AUTHENTIK_TAG en .env con la versión que quiera y, después, ejecute docker compose pull seguido de docker compose up -d. Lea primero las notas de la versión, porque Authentik usa versiones basadas en fechas y algunas versiones incluyen migraciones que requieren actualizar desde la versión anterior. Cree el volcado de la base de datos antes de hacer pull, no después.
FAQ
¿Authentik es gratuito para alojarlo uno mismo?
La edición de código abierto es gratuita e incluye todo lo descrito anteriormente: el proveedor de proxy, la autenticación delegada, OIDC (OpenID Connect), SAML y el motor de flujos. Un nivel empresarial de pago añade soporte y algunas funciones empresariales, pero nada de lo descrito aquí requiere una licencia.
¿Necesito Traefik para usar Authentik?
No. La autenticación delegada funciona con nginx mediante auth_request y con Caddy mediante forward_auth. El patrón es el mismo en todos los casos: el reverse proxy consulta a Authentik para cada petición, y el prefijo de ruta /outpost.goauthentik.io/ del hostname protegido debe dirigir las peticiones a Authentik en lugar de a la aplicación.
¿Por qué mi aplicación protegida alterna indefinidamente entre el inicio de sesión y el error?
El host externo configurado en el proveedor de proxy no coincide con la URL que usa el navegador, normalmente http frente a https. La cookie de sesión se emite para un origen y se lee en otro, por lo que Authentik recibe una petición anónima cada vez. Corrija el host externo y borre las cookies de ambos hostnames antes de volver a probar.
¿Cuánta RAM necesita Authentik?
El mínimo documentado es de 2 núcleos de CPU y 2 GB de RAM a fecha de julio de 2026, para PostgreSQL, el servidor y el worker en conjunto. En un equipo con 2 GB, el worker es el primer proceso que el kernel termina cuando hay presión de memoria. El síntoma es que las tareas en segundo plano y el correo saliente dejan de funcionar, mientras la página de inicio de sesión sigue funcionando. Asígnele 4 GB si el mismo servidor también ejecuta las aplicaciones que está protegiendo.