- Add full header doc block explaining purpose, patterns, and scheduling - Inline comments on all functions and both processing passes - Fix folder format: YYYY/YYYY-MM/ → YYYY/MM/ (year was redundant in subfolder) - Add pass 2: migrate existing YYYY/YYYY-MM/ folders to YYYY/MM/ - Pass 1 now also handles Android-app pre-sorted YYYY/MM/ videos correctly Also commit pending doc updates: - README.md: remove Kopia stack, add ntfy entry, fix infrastructure.caddy note - authentik/SETUP-GUIDE.md: add Mealie OIDC setup notes - homelab-overview.md: remove Kopia refs, add Vaultwarden, fix TrueNAS/PBS wording
12 KiB
Authentik SSO — Setup Guide
Authentik is your central identity provider. Once set up, you log in once at auth.jgitta.com and all your services recognize you automatically.
Phase 1: Deploy the Stack
Step 1 — Copy files to siklos
SSH into siklos and create the directory:
ssh jgitta@192.168.88.27
sudo mkdir -p /srv/docker/authentik
Copy the files from this folder to siklos:
# Run these from your local machine (not from siklos)
scp docker-compose.yml jgitta@192.168.88.27:/srv/docker/authentik/
scp .env jgitta@192.168.88.27:/srv/docker/authentik/
Step 2 — Deploy via Portainer
- Open Portainer at
https://portainer.jgitta.com - Click Stacks → Add stack
- Name it
authentik - Choose Upload and upload the
docker-compose.ymlfrom this folder - Scroll down to Environment variables → click Load variables from .env file → upload
.env - Click Deploy the stack
Authentik takes about 60–90 seconds to start on first run (it runs database migrations).
Step 3 — Add auth.jgitta.com to Caddy
SSH into the Caddy VM and add the auth block:
ssh caddy # (root@192.168.88.110)
nano /etc/caddy/sites/infrastructure.caddy
Add this at the bottom of the file:
auth.jgitta.com {
import web_secure
reverse_proxy 192.168.88.27:9011
}
Then reload Caddy:
systemctl reload caddy
Step 4 — Add DNS record
Add auth.jgitta.com to:
- MikroTik DNS:
auth.jgitta.com→192.168.88.110(same as all other subdomains) - Cloudflare: A record
auth→ your WAN IP, grey cloud (DNS only)
Phase 2: First-Time Setup
- Open
https://auth.jgitta.com/if/flow/initial-setup/ - Create your admin account (email + password)
- You'll land on the Authentik admin dashboard
Tip: The admin interface is at
https://auth.jgitta.com/if/admin/— bookmark it.
Phase 3: Service Integrations
What each type means
- Native OIDC: The service has a built-in "Login with SSO" button. Best experience.
- Forward Auth: Caddy intercepts the request and checks Authentik before letting you in. Works on services with no login support at all.
3A — Native OIDC Services
For each service below, you create an OAuth2/OIDC Provider in Authentik, then configure the service to use it.
How to create an OIDC Provider in Authentik (do this for each service)
- Go to
https://auth.jgitta.com/if/admin/→ Applications → Providers → Create - Choose OAuth2/OpenID Provider
- Fill in:
- Name: e.g.
Gitea - Authorization flow:
default-provider-authorization-explicit-consent - Client type:
Confidential - Redirect URIs: (see per-service table below)
- Name: e.g.
- Click Finish — copy the Client ID and Client Secret
- Go to Applications → Create:
- Name: same as provider
- Slug: lowercase, e.g.
gitea - Provider: select the one you just created
Gitea (gitea.jgitta.com)
Redirect URI: https://gitea.jgitta.com/user/oauth2/authentik/callback
In Gitea → Site Administration → Authentication Sources → Add:
| Field | Value |
|---|---|
| Authentication type | OAuth2 |
| Name | authentik |
| OAuth2 provider | OpenID Connect |
| Client ID | (from Authentik) |
| Client Secret | (from Authentik) |
| OpenID Connect Auto Discovery URL | https://auth.jgitta.com/application/o/gitea/.well-known/openid-configuration |
Portainer (portainer.jgitta.com)
Redirect URI: https://portainer.jgitta.com/
In Portainer → Settings → Authentication → OAuth:
| Field | Value |
|---|---|
| Provider | Custom |
| Client ID | (from Authentik) |
| Client Secret | (from Authentik) |
| Authorization URL | https://auth.jgitta.com/application/o/authorize/ |
| Access token URL | https://auth.jgitta.com/application/o/token/ |
| Resource URL | https://auth.jgitta.com/application/o/userinfo/ |
| Redirect URL | https://portainer.jgitta.com/ |
| Logout URL | https://auth.jgitta.com/application/o/portainer/end-session/ |
| User identifier | preferred_username |
| Scopes | openid email profile |
Linkwarden (links.jgitta.com)
Redirect URI: https://links.jgitta.com/api/v1/auth/callback/authentik
Add to the Linkwarden stack's environment variables in Portainer:
NEXTAUTH_URL=https://links.jgitta.com
AUTHENTIK_CUSTOM_NAME=Authentik
AUTHENTIK_ISSUER=https://auth.jgitta.com/application/o/linkwarden/
AUTHENTIK_CLIENT_ID=<client id>
AUTHENTIK_CLIENT_SECRET=<client secret>
Redeploy the stack after adding these.
Immich (VM113 — 192.168.88.32)
Redirect URI: https://immich.jgitta.com/auth/login (if you have this subdomain) — or app.immich.cloud:// for mobile app
In Immich → Administration → Authentication Settings:
| Field | Value |
|---|---|
| Enable OAuth | ✓ |
| Issuer URL | https://auth.jgitta.com/application/o/immich/ |
| Client ID | (from Authentik) |
| Client Secret | (from Authentik) |
| Scope | openid email profile |
| Button text | Login with Authentik |
| Auto register | ✓ (optional — creates Immich user on first SSO login) |
OCIS / ownCloud (cloud.jgitta.com, VM114)
OCIS already uses OIDC. Update its config to point to Authentik instead of its built-in IDP.
Redirect URI: https://cloud.jgitta.com/
SSH into VM114 and edit the OCIS systemd environment or config file to set:
OCIS_OIDC_ISSUER=https://auth.jgitta.com/application/o/ocis/
PROXY_OIDC_ISSUER=https://auth.jgitta.com/application/o/ocis/
WEB_OIDC_CLIENT_ID=<client id>
Note: OCIS with external OIDC is more involved — reach out if you want a dedicated guide for this one.
Mealie (recipes.jgitta.com)
Redirect URIs: https://recipes.jgitta.com/login and https://recipes.jgitta.com/login?direct=1
Set in the Mealie stack (Portainer stack 59, siklos/mealie/docker-compose.yml in Gitea):
OIDC_AUTH_ENABLED=true
OIDC_SIGNUP_ENABLED=true
OIDC_CONFIGURATION_URL=https://auth.jgitta.com/application/o/mealie/.well-known/openid-configuration
OIDC_CLIENT_ID=<client id>
OIDC_CLIENT_SECRET=<client secret>
OIDC_PROVIDER_NAME=Authentik
OIDC_AUTO_REDIRECT=false
OIDC_REMEMBER_ME=true
Client ID/secret and the Authentik API token used to create this provider are in API Codes.md.
Mealie links accounts by email, so the existing Mealie admin account (jgitta) had its email changed to admin@jgitta.com to match the Authentik akadmin account — otherwise the first OIDC login would have created a brand-new, empty Mealie account instead of linking to the one with all the recipes. Password login (ALLOW_PASSWORD_LOGIN, default true) was left enabled as a fallback.
Home Assistant (ha.jgitta.com, VM106)
Redirect URI: https://ha.jgitta.com/auth/oidc/callback
In Home Assistant → configuration.yaml, add:
homeassistant_cloud: # remove this if present
# In configuration.yaml:
http:
use_x_forwarded_for: true
trusted_proxies:
- 192.168.88.110 # Caddy VM
# Via HACS or built-in: install "OpenID Connect" (HACS → Integrations → search OIDC)
# Or use the built-in auth provider:
homeassistant:
auth_providers:
- type: homeassistant
- type: trusted_networks
trusted_networks:
- 192.168.88.0/24
Then add the authentik integration via Settings → Integrations → Add → search "OpenID Connect":
| Field | Value |
|---|---|
| Client ID | (from Authentik) |
| Client Secret | (from Authentik) |
| Metadata URL | https://auth.jgitta.com/application/o/homeassistant/.well-known/openid-configuration |
Open WebUI (ai.jgitta.com)
Redirect URI: https://ai.jgitta.com/oauth/oidc/callback
Add to the Open WebUI stack environment variables:
ENABLE_OAUTH_SIGNUP=true
OAUTH_MERGE_ACCOUNTS_BY_EMAIL=true
OAUTH_PROVIDER_NAME=Authentik
OPENID_PROVIDER_URL=https://auth.jgitta.com/application/o/openwebui/.well-known/openid-configuration
OAUTH_CLIENT_ID=<client id>
OAUTH_CLIENT_SECRET=<client secret>
OAUTH_SCOPES=openid email profile
Homarr (homarr.jgitta.com)
Redirect URI: https://homarr.jgitta.com/api/auth/callback/oidc
Add to Homarr stack environment:
AUTH_PROVIDER=oidc
AUTH_OIDC_CLIENT_ID=<client id>
AUTH_OIDC_CLIENT_SECRET=<client secret>
AUTH_OIDC_URI=https://auth.jgitta.com/application/o/homarr/
AUTH_OIDC_CLIENT_NAME=Authentik
Nextcloud (next.jgitta.com, VM103)
Install the user_oidc app in Nextcloud (Apps → Search "OpenID Connect user backend").
In Nextcloud → Administration → OpenID Connect:
| Field | Value |
|---|---|
| Identifier | authentik |
| Client ID | (from Authentik) |
| Client Secret | (from Authentik) |
| Discovery endpoint | https://auth.jgitta.com/application/o/nextcloud/.well-known/openid-configuration |
Redirect URI to enter in Authentik: https://next.jgitta.com/apps/user_oidc/code
3B — Forward Auth (Caddy Middleware)
These services have no native SSO. Caddy checks Authentik before granting access.
Step 1 — Create a Proxy Provider in Authentik
- Authentik Admin → Applications → Providers → Create
- Choose Proxy Provider
- Set:
- Name:
Forward Auth - Authorization flow:
default-provider-authorization-implicit-consent - Forward auth (single application) → OR Forward auth (domain level)
- For domain-level (covers all subdomains): external host =
https://auth.jgitta.com
- Name:
- Create an Application called
Forward Authlinked to this provider
Step 2 — Deploy the Outpost
- Authentik Admin → Applications → Outposts → Create
- Type: Proxy
- Applications: select
Forward Auth - Integration: Docker (Authentik will auto-deploy the outpost container on siklos)
Step 3 — Add forward auth to Caddy
Edit /etc/caddy/snippets.caddy on the Caddy VM and add:
(authentik_forward_auth) {
forward_auth http://192.168.88.27:9000 {
uri /outpost.goauthentik.io/auth/caddy
copy_headers X-authentik-username X-authentik-groups X-authentik-email X-authentik-name X-authentik-uid
trusted_proxies private_ranges
}
}
Then add import authentik_forward_auth to any site block you want protected:
dashy.jgitta.com {
import web_secure
import authentik_forward_auth
reverse_proxy http://192.168.88.27:8081
}
Services to protect with forward auth:
| Service | Subdomain | Current Port |
|---|---|---|
| Dashy | dashy.jgitta.com | :8081 |
| SearXNG | search.jgitta.com | :8092 |
| Beszel | beszel.jgitta.com | :8085 |
| Uptime Kuma | status.jgitta.com | :3001 |
| Glances | glances.jgitta.com | :61208 |
| Actual Budget | budget.jgitta.com | :5006 |
| Guacamole | apache.jgitta.com | :8080 |
Recommended Order
- Deploy Authentik stack (Phase 1)
- Complete initial setup (Phase 2)
- Start with Gitea (simplest native OIDC, easy to test)
- Add Portainer and Homarr
- Set up Forward Auth outpost to protect Dashy, SearXNG, Beszel, etc.
- Tackle Nextcloud, OCIS, Immich, Home Assistant individually
Troubleshooting Tips
- Can't reach auth.jgitta.com: Check that Caddy reloaded (
systemctl reload caddy) and MikroTik DNS has the record - Redirect URI mismatch error: The redirect URI in Authentik must exactly match what the service sends — check for trailing slashes
- "Invalid client": Client ID or Secret was copy-pasted with extra whitespace — re-enter manually
- Forward auth loops: Make sure the Authentik app URL itself (
auth.jgitta.com) does NOT haveimport authentik_forward_auth— it would loop forever