Skip to content

Authentication

Pro-Tweaker edited this page Aug 2, 2026 · 1 revision

Authentication

Note

Source: roles/authelia/ in the SEEDbox repo. The middleware assignments below come from the Traefik labels each role sets on its own container.

Table of Contents

Overview

Authelia is the single sign-on portal for the stack. It runs as a forward-auth provider behind Traefik: Traefik asks Authelia whether a request is allowed before it ever reaches the application.

It is published on login.yourdomain.com by default (authelia.subdomain in settings.yml).

Important

Authelia does not sit in front of every application. Eight services are published with no Authelia middleware and are protected only by their own login page. Know which group each of your services is in before you expose anything.

The three groups

Behind authelia@docker

The router carries the forward-auth middleware. An unauthenticated request is redirected to the Authelia portal, and the application is never reached until login succeeds.

ArchiveBox Bazarr Flood Librespeed
Lidarr Netdata NZBGet Prowlarr
qBittorrent Radarr Readarr ruTorrent
SABnzbd Scrutiny Sonarr Speedtest Tracker
Syncthing Traefik whoami

Behind authelia-basic@docker

Same check, but Authelia answers with an HTTP basic auth challenge rather than a redirect to the portal. Used by Homer only, because the dashboard is fetched as a static page and a redirect would break it.

Built-in authentication only

No Authelia middleware. These applications are reachable directly and their own login page is the only thing protecting them.

Application Why
Portainer Has its own user database and API tokens
qui Has its own login
Seerr Uses Jellyfin or a local account, and needs its API reachable
Jellyfin Client apps cannot complete a forward-auth redirect
Navidrome Subsonic clients cannot complete a forward-auth redirect
Kavita Reader apps and OPDS feeds cannot complete a forward-auth redirect
Yamtrack Has its own Django account system
File Browser Has its own user database

Warning

Several of these applications create their admin account on first visit, meaning whoever reaches the URL first claims it. The Kavita and Yamtrack roles close that window by registering the admin over the API during the play. For the rest, log in and set your password immediately after the first deploy.

How Authelia is wired into Traefik

The authelia role defines both middlewares as labels on its own container:

Middleware Address Behaviour
authelia@docker http://authelia:9091/api/verify?rd=https://login.yourdomain.com/ Redirects to the portal
authelia-basic@docker http://authelia:9091/api/verify?auth=basic HTTP basic auth challenge

Both set trustForwardHeader: true. A role opts in by setting one label on its own router:

traefik.http.routers.<service>.middlewares: "authelia@docker"

That single line is the whole difference between the first group and the third. To put an app from the Built-in group behind Authelia, add the label to that role and redeploy.

Users

Users live in a flat file, {{ authelia.folder }}/users_database.yml, generated from settings.yml:

Setting Purpose
authelia.username Login name
authelia.password Plaintext in settings.yml, hashed into the file with sha512crypt at 50000 rounds
authelia.displayname Shown in the portal
authelia.email Used for password reset and notifications

The generated user belongs to the admins and dev groups.

Warning

The role writes this file with force: true, so it is overwritten on every playbook run. Any user you add by hand is lost the next time you deploy. Add users to the template, not to the file on disk.

The hash is also re-salted on every run, so the file shows as changed on each deploy even when nothing in your settings did.

Access control policy

access_control:
  default_policy: deny
  rules:
    - domain: yourdomain.com
      policy: one_factor
    - domain: "*.yourdomain.com"
      policy: one_factor

The default is deny, and the two rules bring the apex domain and every subdomain up to one_factor. In practice: one factor, username and password, everywhere. Anything outside your domain is denied.

To require 2FA on a specific service, add a rule above the wildcard:

    - domain: qbittorrent.yourdomain.com
      policy: two_factor

Rules are evaluated in order, so a more specific rule must come first.

Sessions and brute force protection

Setting Value Meaning
session.expiration 3600 Session is valid for 1 hour
session.inactivity 300 Idle for 5 minutes and you re-authenticate
session.domain your domain The session cookie is shared across every subdomain, so one login covers the whole stack
regulation.max_retries 3 Failed logins before a ban
regulation.find_time 120 Window in seconds those 3 failures must fall within
regulation.ban_time 300 Ban length in seconds

Sessions are stored in the authelia-redis container, so a restart of Authelia does not log everyone out.

Tip

A 5 minute inactivity window is aggressive for a media stack. Raise inactivity in roles/authelia/templates/configuration.yml.j2 if you are tired of re-authenticating.

Two factor authentication

TOTP is configured with your domain as the issuer, so you can enrol an authenticator app from the Authelia portal. But because the access control policy is one_factor everywhere, enrolling does not by itself cause 2FA to be requested. You must also raise the policy to two_factor for the domains you want protected.

Duo push is present in the template but commented out.

Password reset and notifications

Password reset is enabled and delivers over SMTP through the postfix container:

Setting Source
notifier.smtp.host authelia.notification_email_server, default postfix
notifier.smtp.port authelia.notification_email_server_port, default 587
notifier.smtp.sender authelia.notification_email_from

disable_startup_check: true and disable_require_tls: true are set, the latter because the hop to the local postfix container is on the internal Docker network.

Storage and secrets

Authelia keeps its own database at /config/db.sqlite3 inside the container, encrypted with authelia.storage_encryption_key.

Important

Three values in settings.yml must be changed from their defaults before you expose anything:

Setting Requirement
authelia.jwt_secret Long random string, signs the identity tokens
authelia.unsecure_session_secret Long random string, signs the session cookie
authelia.storage_encryption_key At least 64 characters, Authelia refuses to start otherwise

Generate them with something like openssl rand -hex 32 (use -hex 64 for the storage key).

Things worth knowing

  • The config file is world readable. configuration.yml is written with mode 0775 and holds all three secrets in plaintext. Anyone with a shell on the host can read them.
  • Log level is debug. Useful while setting up, noisy in normal operation. Change log.level in the template to info once the stack is running.
  • One login covers everything. Because the session cookie is scoped to the whole domain, authenticating at any one service authenticates you at all of them in the first group.
  • Authelia protects Traefik's own dashboard, so losing Authelia means losing the dashboard too.

Clone this wiki locally