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.path watches for file changes in /var/lib/devpush/traefik/
  • Action: devpush-auth-patch.service runs 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_uris field 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.tv domain (e.g., edit.spacemusic.com)