Skip to content

Authentik

Authentik on Bifrost is the single sign-on for everything public: users log in with GitHub, Grafana and NetBird use it over OIDC, and Traefik gates other public routes with ForwardAuth. Authentik docs.

URLhttps://auth.madhan.app (always public)
Runs onBifrost, started by just core hetzner up
Configured byPulumi stack authentik, authentik.go, just core authentik up
SecretsAUTHENTIK_TOKEN, AUTHENTIK_GITHUB_SECRET, GRAFANA_OAUTH_CLIENT_SECRET, NETBIRD_CLIENT_SECRET (SOPS)

The container comes up on the Hetzner stack; the authentik stack then configures it through its API with AUTHENTIK_TOKEN, which is also the bootstrap token Authentik creates for akadmin on first boot.

SettingValueWhy
Client IDOv23liUPVh4nPuUJzGFpGitHub OAuth app
PKCES256
User matchingidentifieremail_link loops when the admin’s email matches a GitHub account that is not logged in
Login pageBound to default-authentication-identificationShows the Login with GitHub button
AppClient IDRedirect URIsExtra scopes
Grafanagrafana-homelabhttps://grafana.madhan.app/login/generic_oauthgroups
NetBirdaumenijDycfG1cQURqH9BNJpV3KVUCoMHGPUVUlThttps://netbird.madhan.app/oauth2/callback, http://localhost:53000—

Both are confidential clients signed with the default self-signed key; access tokens last 1 hour, authorization codes 10 minutes. Every provider gets openid, email, profile, offline_access and a custom empty api scope that NetBird requests.

The groups scope returns the user’s group names. Grafana’s org_mapping makes members of grafana-admins Admin of the main org; everyone else is a Viewer.

The NetBird app is the upstream for NetBird’s embedded Dex, not NetBird itself; the connector is added by hand in the NetBird UI (setup). Pulumi also creates service account sa-netbird (in authentik Admins) with a non-expiring token, exported as NetbirdServiceToken.

The Homelab ForwardAuth proxy provider runs in forward_domain mode with cookie domain .madhan.app, so one login covers every subdomain. Traefik’s authentik-forwardauth middleware calls authentik-server:9000/outpost.goauthentik.io/auth/nginx. Every route generated from publicServices uses it unless the entry sets SkipAuth: true; see Exposure.

Terminal window
just core authentik up # idempotent; re-run after drift or a failed run
cd core && pulumi stack select authentik && pulumi stack output NetbirdServiceToken --show-secrets

Grant Grafana admin: Directory → Groups → grafana-admins → Add user.

Grafana login works but the user has no admin rights

Section titled “Grafana login works but the user has no admin rights”

The user is not in grafana-admins. Add them, then log in again.

Check Authentik is healthy with ssh root@178.156.199.250 'docker exec authentik-server ak healthcheck', then confirm the outpost in Applications → Outposts.