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¶
- Applications → Applications → Create with provider
- Application
- Name:
Komodo - Slug:
komodo(note this — it appears in the provider URL) - Launch URL:
https://komodo.infra.realemail.app - Next
- Provider type: OAuth2/OpenID Connect (not Proxy Provider)
- Configure provider
- Name:
komodo(orkomodo-oidc) - Authorization flow:
default-provider-authorization-implicit-consent(or match Saltbox apps) -
Redirect URIs: add Strict → Authorization:
-
Signing Key: select one (e.g.
authentik Self-signed Certificate) - Encryption Key: leave empty (Komodo does not support JWE tokens)
- Advanced protocol settings → Scopes: default is fine; add entitlements mapping if you use Komodo group bindings later
- 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.
- Applications → Providers → open your Komodo OIDC provider
- Note Client ID and Client Secret
- On Applications → Applications → Komodo, note the Slug (e.g.
komodo) - Provider URL (trailing slash required):
- 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:
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.
- Commit and push repo changes to
main - 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.
- Incognito →
https://komodo.infra.realemail.app - Should redirect to Authentik (via
KOMODO_OIDC_AUTO_REDIRECT) - Log in at Authentik → redirected back → User Not Enabled (expected)
- Open Komodo login with bypass:
https://komodo.infra.realemail.app/login?disableAutoLogin - Log in with local admin (
KOMODO_INIT_ADMIN_*fromcompose.env) - Settings → Users → click your Authentik username (User type: OIDC)
- Enable User → assign Admin (or desired role)
- Log out → incognito → Komodo should land in the dashboard with one Authentik login
Step 5 — Disable local login (recommended)¶
Repo default and production host setting:
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 |
Related¶
- Authentik infra admin setup — domain forward-auth for other infra apps
- services/komodo/README.md — stack reference
- ADR-002 — native OIDC is an accepted enforcement pattern