Selfhosted SSO med Authentik
Dokumentation for at centralisere login til mine selfhostede services (Forgejo, Jellyfin, n8n, Kanboard, Shaarli, WebDAV) bag én identity provider, i stedet for separat auth pr. app.
- Ét login-flow og én 2FA-politik i stedet for app-for-app opsætning.
- Tilføjer 2FA til services der i dag ikke har det (fx WebDAV, som kun er beskyttet af et langt password).
- Centraliseret brugerstyring og adgangslog.
| Komponent | Rolle |
|---|---|
server |
Web-UI, API, OIDC/SAML-endpoints |
worker |
Baggrundsjobs (flows, outpost-sync) |
| PostgreSQL | Database |
| Redis | Cache/session store |
Officielt minimum er 2 CPU-tråde + 2 GB RAM. I et lille setup som dette kører det typisk fint med ~1 CPU / 1.5-2 GB RAM i idle. Det er klart tungere end Authelia (ingen database, enkelt Go-binary, <50 MB RAM), men til gengæld får man en fuld UI, bruger-admin og indbyggede outposts.
Native OIDC-apps taler direkte med Authentik. Apps uden SSO-support (Shaarli, Kanboard, WebDAV) sidder bag en Proxy Outpost, som agerer selvstændig reverse proxy — det er den vej, der passer bedst til Synology DSM’s reverse proxy, da DSM’s GUI ikke understøtter custom nginx-direktiver som auth_request.
graph LR Internet -->|HTTPS 443| DSM[Synology Reverse Proxy] DSM -->|forgejo.4nton.dk| Forgejo[Forgejo] DSM -->|jellyfin.4nton.dk| Jellyfin[Jellyfin] DSM -->|shaarli.4nton.dk| Outpost[Authentik Proxy Outpost] DSM -->|kanboard.4nton.dk| Outpost DSM -->|n8n.4nton.dk| Outpost DSM -->|dav.4nton.dk| WebDAV[WebDAV - uden for SSO-planen] Outpost -->|header-auth, ægte SSO| Kanboard Outpost -->|dobbelt login| Shaarli Outpost -->|dobbelt login| N8N[n8n] Forgejo -.OIDC.-> Authentik[(Authentik Server)] Jellyfin -.OIDC.-> Authentik Outpost -.auth check.-> Authentik Authentik --- DB[(PostgreSQL)] Authentik --- Cache[(Redis)]
sequenceDiagram participant Bruger participant Forgejo participant Authentik Bruger->>Forgejo: Ã…bner forgejo.4nton.dk Forgejo->>Bruger: Redirect til Authentik (authorize) Bruger->>Authentik: Login + 2FA Authentik->>Bruger: Redirect med authorization code Bruger->>Forgejo: Code Forgejo->>Authentik: Exchange code for token Authentik->>Forgejo: ID token + access token Forgejo->>Bruger: Logget ind
sequenceDiagram
participant Bruger
participant DSM as DSM Reverse Proxy
participant Outpost as Authentik Outpost
participant Shaarli
participant Authentik
Bruger->>DSM: GET shaarli.4nton.dk
DSM->>Outpost: Forward request
Outpost->>Outpost: Gyldig session?
alt Ingen session
Outpost->>Bruger: Redirect til Authentik login
Bruger->>Authentik: Login + 2FA
Authentik->>Outpost: Session cookie sat
end
Outpost->>Shaarli: Forward original request
Shaarli->>Bruger: Side vises
services:
postgresql:
image: docker.io/library/postgres:16-alpine
restart: unless-stopped
volumes:
- database:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS}
POSTGRES_USER: authentik
POSTGRES_DB: authentik
redis:
image: docker.io/library/redis:7-alpine
restart: unless-stopped
volumes:
- redis:/data
server:
image: ghcr.io/goauthentik/server:2024.10.1 # opdater til nyeste stabile tag fra GitHub releases
restart: unless-stopped
command: server
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_REDIS__HOST: redis
volumes:
- media:/media
- templates:/templates
ports:
- "9000:9000"
- "9443:9443"
depends_on:
- postgresql
- redis
worker:
image: ghcr.io/goauthentik/server:2024.10.1 # samme tag som server
restart: unless-stopped
command: worker
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_REDIS__HOST: redis
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- media:/media
- templates:/templates
depends_on:
- postgresql
- redis
volumes:
database:
redis:
media:
templates:
.env skal indeholde:
PG_PASS=<random, lang streng>
AUTHENTIK_SECRET_KEY=<openssl rand -base64 36>
docker compose up -d- Ã…bn
https://<intern-ip>:9443/if/flow/initial-setup/og sæt admin-password. - Log ind pÃ¥ admin-UI’et.
Pr. app i Authentik:
- Applications → Create — giv den et navn og slug.
- Providers → Create → OAuth2/OpenID Provider — sæt redirect URI til appens callback-URL (fx
https://forgejo.4nton.dk/user/oauth2/authentik/callback). - Kobl provideren til applikationen.
- Indsæt Client ID/Secret i appens egen OIDC/OAuth2-konfiguration (Forgejo:
app.inieller admin-UI under Authentication Sources; Jellyfin: SSO-plugin).
n8n er udeladt her: SSO (SAML/OIDC) er en Enterprise-feature i n8n og er ikke med i min licens. n8n kan derfor ikke være en native OIDC-app — den er i stedet lagt i gruppen nedenfor, bag outposten.
- Providers → Create → Proxy Provider — vælg Forward auth (single application) eller Proxy mode.
- Outposts → Create — tilknyt provideren, lad Authentik generere en outpost-container.
- Kør outpost-containeren i Docker (Authentik giver et docker-compose-snippet med token).
- Peg DSM’s reverse proxy for
shaarli.4nton.dk/kanboard.4nton.dk/n8n.4nton.dkpå outpost-containerens interne port, ikke direkte på appen længere. - Tilføj en 2FA-stage (TOTP/WebAuthn) til login-flowet.
| App | Resultat | Hvorfor |
|---|---|---|
| Kanboard | Ægte SSO, ét login | Understøtter REVERSE_PROXY_AUTH — den stoler på en header fra outposten i stedet for at vise sin egen login-side |
| Shaarli | Dobbelt login | Ingen dokumenteret mulighed for header-baseret auth-bypass — har kun sin egen formular-login |
| n8n | Dobbelt login | Community-edition har ingen SSO/header-support (Enterprise-feature) |
For Kanboard, sæt i dens config (eller env-variabler):
REVERSE_PROXY_AUTH=true
REVERSE_PROXY_USER_HEADER=HTTP_X_AUTHENTIK_USERNAME
REVERSE_PROXY_EMAIL_HEADER=HTTP_X_AUTHENTIK_EMAIL
TRUSTED_PROXY_NETWORKS=<outpost-containerens interne IP/CIDR>
Verificer det eksakte header-navn Authentiks proxy-outpost sender i din version (typisk X-authentik-username/X-authentik-email), før du låser TRUSTED_PROXY_NETWORKS til kun outpostens IP — ellers kan en klient der går uden om outposten forfalske headeren og udgive sig for en anden bruger.
Shaarli og n8n beholder deres eget login bag outposten — det er en accepteret UX-trade-off, da begge allerede har deres egen 2FA.
Authentiks forward-auth virker ved at omdirigere en browser til en interaktiv login-side med 2FA. WebDAV-klienter (kalender-/kontakt-sync, Finder/Explorer-netværksdrev) er ikke browsere — de sender HTTP Basic/Digest-credentials direkte og kan ikke følge en redirect eller indtaste en 2FA-kode. At lægge outposten foran WebDAV vil sandsynligvis ødelægge disse klienter, ikke bare give dobbelt login.
WebDAV fortsætter derfor som i dag: eget, random genereret password på 35+ tegn, ingen SSO/outpost.
-
.envmed unikke secrets, ikke committed til git - Pin Authentik-versionen (ikke
:latest) — tjek GitHub releases for nyeste stabile tag - 2FA-stage tilføjet til default login-flow
- Native OIDC konfigureret for Forgejo, Jellyfin
- Proxy outpost kørende for Shaarli, Kanboard, WebDAV, n8n (n8n får dobbelt login — accepteret trade-off)
- DSM reverse proxy opdateret til at pege på outpost i stedet for direkte på apps
- Gammelt direkte login (uden SSO) deaktiveret pr. app, så Authentik bliver den eneste vej ind