Skip to content

Authentik — one login for several services

Authentik is an identity provider: one account, one login page, and any number of services behind it. Traefik can delegate authentication to it without the service being changed at all, and applications that speak OAuth2, OIDC or SAML can use it directly.

Last run on a host 8 Nov 2026 · data restored from a backup

Pinned at 2026.8.5 (released 21 Oct 2026) · the newest upstream release

In the upstream images: 2 CRITICAL · 47 HIGH with a published fix — per image

To try it: Docker, nothing else. See Try it locally.

To deploy it behind the proxy: Traefik running, a domain, and SMTP credentials.

On your own machine, with no proxy, domain or certificate. From core/authentik/:

Terminal window
cp .env.local.example .env.local
# The secrets ship empty; generate the ones this stack needs
{
echo "DB_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')"
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')"
} >> .env.local
docker compose -f docker-compose.local.yml --env-file .env.local up -d

Then open http://localhost:9000. Stop it again with the same command and down.

Five containers: the web server, a background worker, PostgreSQL, Redis, and a one-shot init container that runs for half a second at every start. The database and Redis sit only on the stack’s internal network. The worker also joins an outbound network, because it sends mail and runs the version check; nothing reaches it from outside.

From core/authentik/:

  1. Copy the environment file and set APP_TRAEFIK_HOST, TZ and the SMTP_* block:

    Terminal window
    cp .env.example .env
  2. Generate the secrets:

    Terminal window
    mkdir -p .secrets
    openssl rand -base64 32 | tr -d '\n' > .secrets/db_pwd.txt
    openssl rand -base64 60 | tr -d '\n' > .secrets/authentik_secret_key.txt
    printf '%s' 'YOUR-SMTP-PASSWORD' > .secrets/smtp_password.txt

    Authentik reads values written as file://…, so no entrypoint wrapper is involved.

  3. Start it. No sudo on the host is needed — the init container creates the bind-mount directories and hands them to UID 1000 before the server and worker start:

    Terminal window
    docker compose up -d
    docker compose logs authentik-server --follow

    Wait for Startup complete.

  4. Over the VPN, open the root URL https://<APP_TRAEFIK_HOST>/, which starts the setup flow, and create the administrator. Since 2026.5 Authentik refuses /if/flow/initial-setup/ when it is opened directly. The flow stops working once an administrator exists.

  5. Open the route, so users can log in from anywhere:

    Terminal window
    sed -i 's/^APP_TRAEFIK_ACCESS=.*/APP_TRAEFIK_ACCESS=access-public/' .env
    docker compose up -d
Terminal window
docker compose ps # five services
curl -fsSI https://<APP_TRAEFIK_HOST>/-/health/live/ # 200
curl -fsSI https://<APP_TRAEFIK_HOST>/-/health/ready/ # 200

Then trigger a password reset for a test account and confirm the mail arrives. Password resets, invitations and event notifications all fail silently when SMTP is wrong, and nothing else surfaces it.

Traefik asks Authentik about every request first. An authenticated user passes through; anyone else is redirected to the login page. The service itself is not modified and does not need to support any of this.

  1. In core/traefik/.env, set AUTHENTIK_FORWARD_AUTH_ENABLED=true, then render — the file it produces is dynamic configuration and needs no restart:

    Terminal window
    cd core/traefik
    bash ops/scripts/validate.sh && bash ops/scripts/render.sh && bash ops/scripts/validate.sh

    The middleware is then available to any router as auth-authentik@file. No template is edited.

  2. In the Authentik interface under Applications → Outposts, confirm the embedded outpost exists and is healthy. No extra container is required. Edit it and set authentik_host to https://<APP_TRAEFIK_HOST>: left empty, the outpost sends unauthenticated visitors to a login page on http://localhost/… that no browser reaches.

  3. Create a provider and an application in Authentik for the service you are protecting, then set APP_TRAEFIK_AUTH=auth-authentik@file in that service’s .env — the router’s auth position, the fourth of its four — and redeploy it with docker compose up -d.

If Traefik cannot reach the outpost, the request is refused — forward-auth fails closed, so an Authentik outage locks people out of the protected services rather than letting them through: 500, never 200, with and without a valid session.

The middleware address does not have to be on this host. One Authentik instance can protect services on several machines, as long as Traefik can reach it.

The per-application steps, including the variant that protects only part of a service, are in core/authentik/README.md.

Database PostgreSQL, container authentik-db, database authentik, user authentik
Password .secrets/db_pwd.txt
State volumes/postgres · volumes/data · volumes/certs · volumes/custom-templates
Also needed .secrets/authentik_secret_key.txt
Rebuildable volumes/redis
Quiescing Not needed — the dump is consistent on its own.

For borgmatic:

postgresql_databases:
- name: authentik
username: authentik
# The server's own client, inside its container
pg_dump_command: docker exec authentik-db pg_dump
pg_restore_command: docker exec -i authentik-db pg_restore
psql_command: docker exec -i authentik-db psql

This is the stack whose loss cascades. Every service behind it depends on it, so a failed restore locks people out of all of them at once rather than out of Authentik alone. Rehearse this restore before the services that sit behind it.

Two files outside the database decide whether a restore works. authentik_secret_key.txt derives session and token values — without it every session and issued token is invalid. volumes/certs holds the signing keypairs, and without them SAML assertions no longer validate against the metadata that relying parties already hold.

Restore order: database, then authentik-server, then worker.

  1. Read the release notes. Authentik uses date-based versions and ships schema migrations.

  2. Back up the database, volumes/certs and the secret key together.

  3. Raise APP_TAG in .env, then:

    Terminal window
    docker compose pull && docker compose up -d
    docker compose logs authentik-server --follow
  4. Log in, then load one service that sits behind the middleware. A migration that changed the outpost or provider configuration shows up there rather than in Authentik itself.

Someone else became the administrator. /if/flow/initial-setup/ was reachable before you used it. There is no recovery other than rebuilding the instance.

Password resets and invitations never arrive. SMTP is wrong. The flows report success regardless, so test with a real account after any mail change.

PermissionError on start after moving volumes. The init container fixes ownership on the paths it knows about. If mount paths changed, update them for both authentik-server and worker — they share volumes/data and volumes/custom-templates.

Everyone is signed out after an upgrade. AUTHENTIK_SECRET_KEY changed. Rotating it invalidates every session and API token, so it needs a maintenance window.