Authentik SSO
Audience
PLANA staff. This describes our staff SSO. Customer-facing tenant login flows are in Tenant auth.
PLANA runs its own identity provider — Authentik Community Edition — at https://auth.planapulse.com. Every backbone tool (Forgejo, Grafana, Matomo admin, Penpot, Matrix, Vaultwarden) authenticates PLANA staff against it via OIDC or proxy.
This is PLANA staff only. Customers do not log into Authentik; customers log into their own tenant Odoo via plana_auth, which itself talks to Authentik as a separate OIDC provider.
What runs where
| Component | Location |
|---|---|
| Authentik server + worker | authentik namespace, K8s Deployment |
| Database | authentik DB on pg01 |
| Public URL | https://auth.planapulse.com |
| Admin URL | https://auth.planapulse.com/if/admin/ |
| Bootstrap token | SOPS authentik.bootstrap_token |
| Embedded outpost | PK 10e469fe-81ff-48d1-ac11-0ef2b808855a, type proxy |
Helm chart from Authentik upstream. Never use helm upgrade --reuse-values=false — the upstream chart's values are not complete in our overlay, and a --reuse-values=false flag will reset secrets and crash the pods with "Secret key missing".
Protected applications
| App | Mode | Provider PK |
|---|---|---|
Matomo admin (analytics.planapulse.com) | Proxy (embedded outpost) | 13 |
| Matomo OIDC login button | OAuth2 / OIDC | 14 |
| Forgejo | OIDC | — |
| Grafana | OIDC | — |
| Penpot | OIDC | — |
| Matrix Synapse | OIDC | — |
| Nextcloud | OIDC | — |
| Vaultwarden | OIDC (SSO-only enforced) | — |
Each provider belongs to one application. The redirect URIs are tightly scoped per app to prevent cross-app token leakage.
Two authentication patterns
Pattern A — OIDC
For apps that natively support OIDC. The app redirects to Authentik for login, receives an id_token + access_token, and uses the user's groups claim for in-app authorisation.
Apps using OIDC:
- Forgejo (
OAuth2/OIDCprovider, scopeopenid profile email groups) - Grafana
- Penpot
- Matrix Synapse (
m.login.ssoredirected to Authentik) - Nextcloud
- Vaultwarden (configured for SSO-only — passwordless login)
- Matomo (the SSO button on the login page, via LoginOIDC plugin)
Authentik handles 2FA, password policy, account lockout, and audit logging. The app trusts the id_token.
Pattern B — Proxy
For apps that do not have native OIDC integration, Authentik's embedded outpost acts as a forward-auth proxy. The app's namespace runs an ExternalName Service that points at authentik-proxy, which internally points at authentik-server in the authentik namespace.
Apps using Proxy:
- Matomo admin path (
/and anything not in the public tracking endpoint list)
The Matomo case is informative because it shows the gotcha: the outpost handles /outpost.goauthentik.io/ paths only when the Host header matches the APP domain (analytics.planapulse.com), NOT the auth domain. Diagnostic: if the outpost callback redirects to auth.planapulse.com/outpost.goauthentik.io/..., it will 404 — the outpost only knows how to handle its callback at the app's hostname.
Users
PLANA staff users today (PKs may shift on user-edit):
| User | PK | 2FA | |
|---|---|---|---|
| Chudomir Monevski | chudomir.monevski@plana.solutions | 6 | TOTP required |
| Boyan Rabchev | boyan.rabchev@plana.solutions | (varies) | TOTP required |
| Julian Lubenov | julian.lubenov@plana.solutions | (varies) | TOTP required |
| Martin Kotrulev | martin.kotrulev@plana.solutions | (varies) | TOTP required |
| Ramona Gospodinova | ramona.gospodinova@plana.solutions | (varies) | TOTP required |
| Elena Encheva-Blagoeva | elena.encheva-blagoeva@plana.solutions | 24 | TOTP required |
TOTP is mandatory for every staff user. Enrolment is enforced by a group policy on the default flow — a user who has not enrolled is redirected to the enrolment screen on their first login. New staff members follow the procedure in Two-factor (TOTP).
Groups and roles
| Group | Members | Access |
|---|---|---|
plana-staff | All employees | Default access to all internal tools |
plana-admins | CTO + senior devs | Authentik admin + cluster RBAC |
plana-finance | CEO + accounting | Matomo write, Stripe admin, billing reports |
tenant-impersonators | CTO + designated senior devs | Allowed to log into customer tenants (audit logged) |
Group claims are emitted in the groups scope of the OIDC token. Apps that need fine-grained authorization read groups from the claim, not from their own internal user database.
How tenants authenticate (briefly)
Customer tenants run their own Odoo. The plana_auth module is installed on every tenant by the provisioning Composition. It connects to Authentik as an OIDC client with the same client_id for all tenants:
client_id: pNQrL29SXWXiLgNHdPWvFiRR85cmyxrGdTwoXgasThe Authentik provider for tenant auth (PK 10, name "PLANA Odoo Platform") uses a regex redirect_uri covering *.planapulse.app, *.planapulse.online, and erp.planapulse.ai so a single client serves every tenant. Per-tenant client isolation was considered (each tenant gets its own client_id) and deferred — the benefit is small and the operational cost is non-trivial.
See Tenant auth for the customer-side flow.
Google federation
PLANA also federates with Google for staff who prefer to log in with their Google account. Configured 2026-05-28. See Google federation.
Common operational tasks
Add a new staff user
- Authentik admin → Identity & Cryptography → Users → Create user
- Set email
firstname.lastname@plana.solutions - Add to
plana-staffgroup (auto-grants access to internal tools) - Send the password-reset link via the workspace's Matrix room
- First login: user is redirected to TOTP enrolment
Disable a user (offboarding)
- Authentik admin → Users → User → "Disable"
- Verify all OIDC sessions are killed:
Authentik admin → Events → Active sessions, terminate - Remove from
tenant-impersonatorsgroup if applicable - Audit log: confirm the user's recent activity is captured in
monitoring/lokifor retention
Rotate the bootstrap token
The bootstrap token (AK_ADMIN_BOOTSTRAP_TOKEN) is used during initial deploy to seed the first admin user. After bootstrap it should not be used for routine access. Rotation:
- Generate a new token in Authentik admin → Tokens
- Update SOPS
authentik.bootstrap_token - Reconcile the secret in the
authentiknamespace - Revoke the old token in Authentik admin
Reissue a forgotten provider client_secret
- Authentik admin → Applications → Providers → click the provider
- Click "Regenerate Client Secret"
- Copy the new secret
- Update the consuming app's config (commit to
infra/k8s/<app>/, merge, let Flux reconcile) - Restart the consuming app pods
Outpost details
The embedded outpost handles proxy authentication for Matomo. Configuration:
| Property | Value |
|---|---|
| Outpost PK | 10e469fe-81ff-48d1-ac11-0ef2b808855a |
| Type | proxy |
| Providers attached | [13] (Matomo proxy) |
The outpost is embedded (runs in the Authentik server pod), not external — we do not run a separate authentik-outpost-proxy Deployment. Embedded is sufficient for our scale; external is needed only for very high-traffic proxy use cases.
Where to read more
- Two-factor (TOTP) — mandatory enrolment, recovery
- Google federation — federated login with Google
- Tenant auth — customer-facing auth,
plana_authmodule - Shared infrastructure → Matomo — the proxy-mode example in detail