# 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: ```bash ssh jgitta@192.168.88.27 sudo mkdir -p /srv/docker/authentik ``` Copy the files from this folder to siklos: ```bash # 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 1. Open Portainer at `https://portainer.jgitta.com` 2. Click **Stacks** → **Add stack** 3. Name it `authentik` 4. Choose **Upload** and upload the `docker-compose.yml` from this folder 5. Scroll down to **Environment variables** → click **Load variables from .env file** → upload `.env` 6. 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: ```bash 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: ```bash 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 1. Open `https://auth.jgitta.com/if/flow/initial-setup/` 2. Create your admin account (email + password) 3. 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) 1. Go to `https://auth.jgitta.com/if/admin/` → **Applications** → **Providers** → **Create** 2. Choose **OAuth2/OpenID Provider** 3. Fill in: - **Name**: e.g. `Gitea` - **Authorization flow**: `default-provider-authorization-explicit-consent` - **Client type**: `Confidential` - **Redirect URIs**: (see per-service table below) 4. Click **Finish** — copy the **Client ID** and **Client Secret** 5. 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= AUTHENTIK_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= ``` > 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= OIDC_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: ```yaml 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= OAUTH_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= AUTH_OIDC_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 1. Authentik Admin → **Applications** → **Providers** → **Create** 2. Choose **Proxy Provider** 3. 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` 4. Create an Application called `Forward Auth` linked to this provider #### Step 2 — Deploy the Outpost 1. Authentik Admin → **Applications** → **Outposts** → **Create** 2. Type: **Proxy** 3. Applications: select `Forward Auth` 4. 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 1. Deploy Authentik stack (Phase 1) 2. Complete initial setup (Phase 2) 3. Start with **Gitea** (simplest native OIDC, easy to test) 4. Add **Portainer** and **Homarr** 5. Set up **Forward Auth outpost** to protect Dashy, SearXNG, Beszel, etc. 6. 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 have `import authentik_forward_auth` — it would loop forever