Skip to content

Komodo — Authentik OIDC (single login)

Komodo uses native OIDC to Authentik instead of Traefik forward-auth. Forward-auth and Komodo OIDC conflict — do not apply authentik@file on the Komodo router when OIDC is enabled (authentik#17927).

Admin URL: https://auth.realemail.app/if/admin/ Komodo URL: https://komodo.infra.realemail.app Official reference: Authentik Komodo integration


What changes

Layer Before After
Traefik authentik@file forward-auth No auth middleware (Komodo handles login)
Komodo Local username/password Authentik OIDC with auto-redirect
Authentik Domain proxy provider only Additional OAuth2/OIDC provider for Komodo

The domain-level proxy provider (infra-realemail-app-domain) stays as-is for Grafana, Homepage, etc. Komodo gets its own OIDC application.


Step 1 — Create OIDC provider in Authentik

  1. Applications → Applications → Create with provider
  2. Application
  3. Name: Komodo
  4. Slug: komodo (note this — it appears in the provider URL)
  5. Launch URL: https://komodo.infra.realemail.app
  6. Next
  7. Provider type: OAuth2/OpenID Connect (not Proxy Provider)
  8. Configure provider
  9. Name: komodo (or komodo-oidc)
  10. Authorization flow: default-provider-authorization-implicit-consent (or match Saltbox apps)
  11. Redirect URIs: add Strict → Authorization:

    https://komodo.infra.realemail.app/auth/oidc/callback
    
  12. Signing Key: select one (e.g. authentik Self-signed Certificate)

  13. Encryption Key: leave empty (Komodo does not support JWE tokens)
  14. Advanced protocol settings → Scopes: default is fine; add entitlements mapping if you use Komodo group bindings later
  15. Submit

Copy credentials and confirm slug

The application slug in Authentik becomes part of the provider URL. It does not have to be komodo — use whatever slug you chose (e.g. infra-services-komodo), but every copy-paste below must use your slug.

  1. Applications → Providers → open your Komodo OIDC provider
  2. Note Client ID and Client Secret
  3. On Applications → Applications → Komodo, note the Slug (e.g. komodo)
  4. Provider URL (trailing slash required):
https://auth.realemail.app/application/o/<slug>/
  1. Verify before restarting Komodo (must return JSON, not HTML 404):
curl -sL "https://auth.realemail.app/application/o/<slug>/.well-known/openid-configuration" | head -c 120

Example for slug komodo:

{"issuer":"https://auth.realemail.app/application/o/komodo/",...

Do not assign this application to any outpost — OIDC talks to Authentik server directly.


Step 2 — Update config (template + SOPS)

Non-secret OIDC flags go in services/komodo/compose.env.template (in git):

KOMODO_OIDC_ENABLED=true
KOMODO_OIDC_PROVIDER=https://auth.realemail.app/application/o/<slug>/
KOMODO_OIDC_AUTO_REDIRECT=true
KOMODO_LOCAL_AUTH=false
KOMODO_DISABLE_LOCAL_USER_REGISTRATION=true

Client ID and secret go in services/komodo/secrets.sops.yaml (encrypted in git):

set -euo pipefail
cd services/komodo || exit 1
sops secrets.sops.yaml   # set KOMODO_OIDC_CLIENT_ID and KOMODO_OIDC_CLIENT_SECRET

On infra-services, after git pull, use the authorized identity for the key. Bootstrap's default /etc/homelab/age-key.txt is root:root 0400; do not weaken it. The existing Komodo renderer already uses atomic replacement and preserves its destination on decryption failure. It defaults to that host key, and on root runs assigns compose.env mode 0600 to someone:someone (overrides: KOMODO_COMPOSE_ENV_OWNER / KOMODO_COMPOSE_ENV_GROUP). Confirm that consumer identity before rendering; ownership failure must also stop deployment.

Atomic replacement is not dotenv escaping proof. The helper now rejects ambiguous secret characters with the shared restricted validator, uses private ignored .decrypted~render-* staging, and sets output ownership before promotion. It remains a template renderer, not the shared .env CLI. The non-secret template permits comments, blanks and unique simple assignments (restricted value characters plus internal spaces); duplicate, quoted or interpolated assignments fail closed. Changes to its syntax need synthetic Compose tests. Read the serialization boundary. Local source tests do not certify target Compose, runtime key access or consumer permissions. Unsupported values are a hard stop, not permission to guess escaping.

Default-key invocation (noninteractive sudo must already be authorized):

set -euo pipefail
cd /opt/homelab/services/komodo || exit 1
sudo -n bash /opt/homelab/scripts/render-komodo-compose-env.sh || exit 1

Alternatively, an authorized operator with a separately provisioned readable key can invoke without sudo using SOPS_AGE_KEY_FILE=/absolute/operator/key and the reviewed REPO_ROOT; the output is then owned by that operator. Do not copy the host key or change its mode to make this work. Failure is a hard stop for Step 3.

Leave other keys in SOPS (KOMODO_DATABASE_PASSWORD, JWT, webhook) unchanged unless rotating.

Commit the encrypted secrets.sops.yaml after editing — never commit plaintext compose.env.


Step 3 — Deploy (remove forward-auth)

Repo change: services/komodo/compose.yml must not set authentik@file on the Komodo router.

  1. Commit and push repo changes to main
  2. On infra-services:
set -euo pipefail
cd /opt/homelab || exit 1
git pull --ff-only origin main || exit 1
cd services/komodo || exit 1
# Re-render after this exact pull, not just before it; stop on any failure.
sudo -n bash /opt/homelab/scripts/render-komodo-compose-env.sh || exit 1
docker compose --env-file compose.env up -d --no-deps core

Use --no-deps core only — avoids recreating Mongo/periphery.

Verify Traefik router has no authentik@file middleware:

docker inspect komodo-core --format '{{index .Config.Labels "traefik.http.routers.komodo.middlewares"}}'
# (empty output = correct)

Step 4 — Enable your OIDC user (one-time)

Komodo does not auto-provision OIDC users.

  1. Incognito → https://komodo.infra.realemail.app
  2. Should redirect to Authentik (via KOMODO_OIDC_AUTO_REDIRECT)
  3. Log in at Authentik → redirected back → User Not Enabled (expected)
  4. Open Komodo login with bypass: https://komodo.infra.realemail.app/login?disableAutoLogin
  5. Log in with local admin (KOMODO_INIT_ADMIN_* from compose.env)
  6. Settings → Users → click your Authentik username (User type: OIDC)
  7. Enable User → assign Admin (or desired role)
  8. Log out → incognito → Komodo should land in the dashboard with one Authentik login

Repo default and production host setting:

KOMODO_LOCAL_AUTH=false
set -euo pipefail
cd /opt/homelab/services/komodo || exit 1
sudo -n bash /opt/homelab/scripts/render-komodo-compose-env.sh || exit 1
docker compose --env-file compose.env up -d --no-deps core

Emergency break-glass: temporarily set KOMODO_LOCAL_AUTH=true and use ?disableAutoLogin on the login URL.


Troubleshooting

Symptom Fix
Login URL has client_id=9eX5… and redirect_uri=…homepage…/outpost.goauthentik.io Forward-auth still on Komodo router — remove authentik@file from compose.yml, recreate core
Blank page or redirect to komodo.../application/o/authorize Wrong KOMODO_OIDC_PROVIDER — must be auth.realemail.app, trailing /
OIDC init panic / issuer mismatch Provider URL missing trailing slash
Invalid JSON web token: found 5 parts Remove Encryption Key on Authentik provider
Still prompted for Komodo password after Authentik Forward-auth still on router — remove authentik@file, recreate core
Authentik login then 502 Core container crash — docker logs komodo-core; check OIDC env vars
User Not Enabled forever Complete Step 4 with local admin
Core cannot reach Authentik From infra-services: curl -sI https://auth.realemail.app — DNS/firewall
Komodo Go stuck on Authentik, or reports a login page The app uses an API key, not the OIDC redirect. See mobile-apps-authentik.md