Authentik single sign-on protects all SpaceMusic services.
Overview¶
Authentik is the identity provider running at auth.spacemusic.tv. It handles authentication for every service in the SpaceMusic stack using two mechanisms:
- Forward auth -- Traefik intercepts requests and checks with Authentik before forwarding to the backend. Used by most services.
- OIDC -- Services with native OAuth support (Grafana, MinIO) authenticate directly with Authentik as an OpenID Connect provider.
Version: 2026.2 (ghcr.io/goauthentik/server:2026.2)
Components: Authentik server + worker, PostgreSQL 16, Redis 7
How Forward Auth Works¶
Browser → Traefik → authentik@file middleware → Authentik server
↓
authenticated?
↓ ↓
yes no
↓ ↓
forward to redirect to
backend auth.spacemusic.tv
↓ login page
(with X-authentik-*
response headers)
When a user is authenticated, Traefik passes these response headers to the backend service:
| Header | Content |
|---|---|
X-authentik-username |
Username |
X-authentik-email |
Email address |
X-authentik-name |
Display name |
X-authentik-groups |
Comma-separated group list |
X-authentik-uid |
Unique user ID |
User Groups¶
Access levels are controlled by Authentik groups:
| Group | Access |
|---|---|
spacemusic-admins |
Full access to all services, Authentik admin panel, Grafana Admin role, MinIO admin |
spacemusic-studio |
Grafana Editor role, MinIO read/write, stream dashboard, docs, Node-RED |
spacemusic-viewers |
Grafana Viewer role, stream dashboard (read-only), docs |
OIDC Providers¶
These services authenticate directly via OpenID Connect:
| Service | Authentik Slug | Redirect URI |
|---|---|---|
| Grafana | grafana |
https://dashboard.spacemusic.tv/login/generic_oauth |
| MinIO | minio |
https://storage.spacemusic.tv/oauth_callback |
Grafana maps Authentik groups to roles using a JMESPath expression:
contains(groups[*], 'spacemusic-admins') && 'Admin' || contains(groups[*], 'spacemusic-studio') && 'Editor' || 'Viewer'
MinIO uses claim_name=groups and maps Authentik group names directly to IAM policy names (the names must match exactly).
MinIO OIDC requirement
MinIO requires the Authentik provider to use an RS256 signing key, not the default self-signed certificate. Create a dedicated RSA signing key in Authentik and assign it to the MinIO provider.
Forward Auth Proxy Providers¶
These services use Traefik forward auth via the authentik@file middleware:
| Service | Authentik Slug | Domain |
|---|---|---|
| Stream Dashboard | stream |
stream.spacemusic.tv |
| Documentation | docs |
docs.spacemusic.tv |
| Uptime Monitoring | uptime-kuma |
uptime.spacemusic.tv |
| SpaceMusic Editor | uwd-spacemusic |
edit.spacemusic.com |
| Origin Infinite Editor | uwd-origininfinite |
edit.origin-infinite.com |
| Dashboard Preset | dashboard-preset |
preset-dashboard.spacemusic.tv |
| Node-RED | node-red |
connect.spacemusic.tv |
Each Proxy Provider must be manually added to the embedded outpost in Authentik for forward auth to work.
SvelteKit Auth Bridge¶
SvelteKit services (Stream, API) bridge Authentik headers into their own auth system via hooks.server.js:
// hooks.server.js - reads Traefik-forwarded Authentik headers
const username = event.request.headers.get('x-authentik-username');
if (username) {
event.locals.user = { username, email, name };
// Persist to cookies for client-side SvelteKit navigations
event.cookies.set('ak_username', username, cookieOpts);
}
This pattern is used because Traefik only forwards Authentik headers on the initial server-side request. Client-side SvelteKit navigations don't go through Traefik, so cookies bridge the identity.
devpush Auth Patching¶
devpush generates its own Traefik config files for each project, overwriting them on every deploy. To persist the authentik@file middleware, a systemd watcher automatically patches these files:
- Script:
/usr/local/bin/devpush-auth-patch.sh - Trigger:
devpush-auth-patch.pathwatches for file changes in/var/lib/devpush/traefik/ - Action:
devpush-auth-patch.serviceruns the script, which injects the middleware into the relevant Traefik config files
Logout¶
Use the invalidation flow URL for logout:
https://auth.spacemusic.tv/if/flow/default-invalidation-flow/
Warning: Do not use the outpost sign_out endpoint
Using /outpost.goauthentik.io/sign_out only clears the proxy session but leaves the core Authentik session alive. This causes an infinite redirect loop where the user is immediately re-authenticated. Always use the invalidation flow URL instead.
For Grafana, set the signout redirect:
GF_AUTH_SIGNOUT_REDIRECT_URL=https://auth.spacemusic.tv/application/o/grafana/end-session/
Gotchas¶
- The authorize endpoint is shared across all applications:
https://auth.spacemusic.tv/application/o/authorize/(not per-slug) - The
redirect_urisfield in the Authentik API requires a list of dicts:[{"url": "...", "matching_mode": "strict"}] - Forward auth Proxy Providers must be manually added to the embedded outpost -- creating the provider alone is not enough
- The outpost router in the Traefik config must explicitly list every non-
*.spacemusic.tvdomain (e.g.,edit.spacemusic.com)