Authentik¶
TL;DR / when to use this: Authentik is the self-hosted identity provider in front of my apps — SSO, MFA, Google as an external login source, and forward-auth to Nginx/Pangolin. Use it when you want one auth layer for everything; pair it with Pangolin for public access.
First-time setup¶
Follow the docker-compose install, then visit:
Housekeeping I always do:
Directory → Users → Createyour own user; expand the row to set a password.- Add yourself to a group, log in, and set up MFA.
- Deactivate the default admin user.
Forward auth from Nginx¶
Application → Providers → Create, type Forward auth (single application) (use the full-domain variant only if you want to protect a whole domain). The External host must match the proxy host. Copy the block Authentik generates into the proxy's advanced tab, and point the outpost path at your Authentik host:
Add the provider to the Outpost, then create the Application with the policy you just made. For zero-trust access, create an "access" group in Directory → Groups and bind policies to it.
Google as an external login source¶
Google sign-in requires a public domain routing to Authentik (e.g. a Cloudflare tunnel like authentik.example.com).
- In Google Cloud Console: new project →
APIs & Services→ OAuth consent screen +Create Credentials → OAuth client ID. - Redirect URL:
https://authentik.example.com/source/oauth/callback/google/. Scopes:openid,email,profile. - In Authentik:
Directory → Federation and Social Login → Create → Google OAuth Source, matching users by identical email, paste client ID/secret, scopesopenid email profile. Flows and Stages → Flows→ editdefault-authentication-flow→ Stage Bindings → edit theidentificationstage → select Google as the source.
Custom identification stage
Rather than editing the default stage, clone it (wilde-authentication-identification), duplicate the flow (wilde-authentication-flow), bind the password stage's failure result to Pass, swap in your cloned stage, and select the custom flow under the provider's Advanced flow settings. Blank out the Google source's Enrollment flow to disable enrollment.
Webhooks (event-driven automation)¶
Events → Notification Rules — create an Event Matcher Policy with action Login. A notification transport can hit an external API on every login. Example: auto-whitelisting a user's current IP as a Pangolin resource rule for Jellyfin clients that can't handle auth redirects.
Pangolin API quirk
Pangolin's integration API uses POST for updates and PUT for inserts, and Authentik webhooks only send POST — so pre-create a dummy rule per user, then have each user's login event update their rule via a per-user body mapping (priority must match the pre-created rule; rules can't share priorities). Per-user policies need an expression matching both event and user:
event = request.context.get("event")
return (
event is not None
and event.action == "login"
and event.user.get("pk") == 6
)
Header mapping carries Authorization: Bearer <token>; create scoped API keys (update-rules for Authentik, list-keys to find resource/rule IDs).
Authentik as Pangolin's identity provider¶
Pangolin treats every user/IdP combo as a distinct user, so Authentik is the cleaner IdP — you create users once and auto-provision them.
- Create an IdP in Pangolin named Authentik; note the redirect URL it shows.
- In Authentik, create an Application + OAuth2/OpenID provider (
pangolin), confidential client type, strict redirect URI = Pangolin's URL, authorization flowdefault-provider-authorization-explicit-consent. Paste client ID/secret into Pangolin. -
Enable Auto Provision Users, then add an Organization Policy. Role mapping can be hardcoded (
Member) or expression-based:contains(groups, 'authentik Admins') && 'Admin' || contains(groups, 'family') && 'Family' || 'Member'Organization mapping:
contains(groups, 'jellyfin')— users created in Authentik land in the right Pangolin organization automatically.
Google directly as a Pangolin IdP works too, but provisioning is awkward: the Identifier Path defaults to sub (an unknown UUID), so pre-provisioning users is hard; switching it to email works but usernames must stay unique across IdP combos.
See also¶
- Pangolin
- Blog posts: Setting up Authentik · Authentik Webhooks · Pangolin Identity Providers