Skip to content

Single sign-on

Two separate questions:

  1. Access: who may reach the app at all. With Authentik, nginx checks every request against Authentik (forward auth); only the groups you choose get through. This works for any app.
  2. Account in the app: once through, who are you inside the app? Single sign-on means you are your Authentik user there too, with no second login.

Deployer automates the second question as far as each app allows.

Methods

Method How it works What the app must support Inside the app
OpenID Connect The app signs you in with Authentik. Deployer creates a confidential OAuth2/OIDC provider dp-<app>-sso (redirect URIs: any path of the app's domain, signed with Authentik's certificate, scopes openid/email/profile) and an application bound to the same groups. An OIDC / "generic OAuth2" setting (environment variables, config file or admin page) your Authentik user, created on first login
SAML 2.0 Deployer creates a SAML provider dp-<app>-saml (signed assertions, username as NameID, same groups) and shows entity ID, SSO/SLO URLs, metadata URL and certificate. The app's ACS path is served without the forward-auth check, because it receives a signed assertion by POST. SAML service provider settings your Authentik user
Username from nginx nginx forwards Remote-User, Remote-Email, Remote-Name and X-authentik-username/email/name from Authentik. When not enabled, nginx clears these headers so a visitor can never send them. The app must trust them only from the app network gateway (shown). reverse-proxy / trusted-header authentication your Authentik user
Login turned off Authentik in front is the only login. a setting that disables its own login one shared identity
HTTP Basic nginx sends a stored app account as Authorization: Basic … on every request. The credentials live only in the root-only nginx site file. HTTP Basic authentication one shared account
Auto-login After the Authentik login, Deployer signs in to the app on the server side with a stored account and hands the browser the app's session. Adapters: classic login forms (any app with an HTML form) and app-specific ones (Uptime Kuma). a login form, or an adapter one shared account
Keep the app's own login Not single sign-on: Authentik first, then the app asks for its own user. nothing the app's own users

How Deployer chooses

When an image is picked, ssodetect gathers evidence, best first:

  1. Tested: a catalog recipe (checked with a real login) or a recipe you saved from a working app.
  2. Documented: a curated list of popular apps (with the exact setting and a link), and the index of Authentik's official integration guides (about 245 apps: provider type and guide link). Methods only available in a paid edition are marked and never recommended.
  3. Found in its docs: the image's own environment variables (OIDC_*, OAUTH*, SAML*, REMOTE_USER, AUTH_PROXY, DISABLE_AUTH…), its Docker Hub description and its project README (sentences mentioning OpenID Connect, SAML, reverse-proxy authentication, disabling authentication, HTTP Basic, LDAP).

The Account in the app list then shows:

  • the tested recipe first (recommended);
  • every method with evidence, with its level badge and its sources (click "n sources");
  • auto-login with one shared account as the last resort, only when no single sign-on method is known;
  • the remaining methods behind "show all methods";
  • "Keep the app's own login" in a separate Not single sign-on section.

LDAP is reported as information only: same username and password, but typed in the app.

Tested recipes

A recipe describes, for one app: the method, the environment variables to add (with placeholders), variables to remove while SSO is on, steps to do once in the app, notes, and extras:

Field Purpose
env / remove added / removed variables of the main service; secrets go to secrets/app.env
steps what to do once in the app's admin page, rendered with the real values
redirect the app's OIDC callback (shown for setups done by hand)
adminClaim Deployer adds a scope mapping to the app's OIDC client: claim deployer_groups = ["admin"] for the admin account, ["user"] for everyone else (used by Mealie, BookStack, Pingvin Share)
init commands run once inside the container after it is healthy (e.g. Gitea creates the admin account)
ownDoor no forward auth in front: the app's own OIDC sign-in is the door (its client only admits the chosen groups). For apps whose service worker breaks behind forward auth (Actual).
login auto-login adapter (form with an optional path, or uptime-kuma)

Placeholders: {{URL}} {{FQDN}} {{OIDC_ISSUER}} {{OIDC_CONFIG_URL}} {{OIDC_LOGOUT_URL}} {{OIDC_CLIENT_ID}} {{OIDC_CLIENT_SECRET}} {{GATEWAY}} {{AUTHENTIK_URL}} {{ADMIN_USER}} {{ADMIN_EMAIL}}.

Recipes follow the image, including mirrors and forks: hkotel/mealie, someone/mealie or lscr.io/linuxserver/grafana use the same recipe (exact image, aliases, then an unambiguous name match).

Results of the real-login tests

Result Apps
One login, your Authentik user, admin checked Gitea, Grafana, Linkding, Navidrome, FreshRSS, Mealie, BookStack, Actual, Audiobookshelf (after its steps)
One login, your Authentik user Stirling PDF
No login after Authentik code-server, Dozzle, changedetection.io, ntfy, IT-Tools, Excalidraw…
Set up once in the app (values shown) Memos, Kavita, Wiki.js, Pingvin Share, Uptime Kuma ("Disable Auth")
Master password kept by design Vaultwarden (SSO login, then the vault's master password)
No single sign-on in the free edition n8n, NocoDB, Umami, PocketBase, WordPress (plugin needed)

The admin account inside the app

Recipes that need it ask for Admin in the app (default: the Authentik user whose email is yours). Deployer makes that account the app's admin by the means the app offers: a claim (deployer_groups), the app's admin user variable (Grafana, Linkding, FreshRSS), or a one-time command (Gitea). Deploy is refused until it is set.

Auto-login in detail

sequenceDiagram
    participant B as Browser
    participant N as nginx (app domain)
    participant A as Authentik
    participant D as Deployer
    participant X as App (127.0.0.1:port)
    B->>N: GET https://app.example.com/
    N->>A: forward auth
    A-->>B: login page (once)
    B->>N: GET /__deployer/autologin (after login)
    N->>A: forward auth: OK
    N->>D: /api/autologin/app + per-app token
    D->>X: GET login page, POST username/password (server side)
    X-->>D: session cookie
    D-->>B: Set-Cookie (app session), redirect to /
  • The password is sealed with the master key, never returned by the API, never written in a page.
  • The endpoint answers only to loopback requests carrying the app's token, which only the root-only nginx site holds; without an Authentik session nginx redirects to Authentik first.
  • The form adapter finds the login form (tries /login, /signin, /auth/login, … when no path is given), keeps hidden fields (CSRF tokens), posts it, and detects a refused login.
  • The Uptime Kuma adapter logs in over Kuma's socket.io API; the browser only receives Kuma's session token.
  • Everyone you let in uses that one app account. Use it for single-user tools or a group that shares one account.

Checking the sign-in

After every deploy and account change, the step Checking the sign-in verifies what can be verified and warns (with the fix) otherwise: forward auth asks for the login, the OIDC issuer is published, the SAML provider exists, the shared account is accepted (Basic), the auto-login really signs in.

Saving a recipe

When an app you set up by hand works (any method), Save as a recipe for this image on its page stores the method, the variables you tick (this app's own values, domain, client ID, issuer, gateway, admin, replaced by placeholders automatically), steps and notes. The next app made from that image gets it by itself, marked Tested · your saved recipe.

Running apps

The Account in the app card on a running app shows the method and, for methods done by hand, the values to copy (issuer, discovery URL, client ID, secret for editors, redirect URI; SAML entity ID, URLs, certificate; headers and the trusted address). Change switches the method (rewrite, restart, check, rollback on failure). An app created before a recipe existed shows Use it to switch to the tested setup.