One Login to Rule Your Entire Homelab
Running a homelab or self-hosted stack means managing a growing collection of web UIs, each with its own username and password. Jellyfin, Grafana, Portainer, Nextcloud – the list keeps expanding, and so does the credential sprawl. Single sign-on (SSO) solves this by centralizing authentication into one identity provider that every other service trusts. You log in once, and everything else just opens.
Authentik is an open-source identity provider built for exactly this scenario. It supports SAML, OAuth2, OpenID Connect (OIDC), and LDAP, which means it speaks the authentication language of virtually every modern self-hosted app. It ships with a polished admin interface, a user enrollment flow, MFA support, and a policy engine that can restrict access based on group membership, IP, or time of day. For a self-hosted tool, its feature depth is hard to match.
This guide walks through deploying Authentik with Docker Compose, configuring it as an OIDC provider, and connecting a downstream application – using Grafana as the example client.
Prerequisites and Environment Setup
You need a Linux host with Docker and Docker Compose installed. Authentik runs two main containers – a server and a worker – plus PostgreSQL and Redis as dependencies. Give the host at least 2GB of RAM; Authentik’s worker handles background tasks like certificate rotation and outpost management, and it appreciates having headroom. A domain name pointed at your server is strongly recommended, because OAuth2 redirect URIs require a consistent, resolvable hostname – localhost works for testing but breaks in multi-device scenarios.
Start by generating the required secrets. Authentik needs a secret key and a PostgreSQL password. Run openssl rand -base64 36 twice and save both outputs. Create a working directory called authentik and inside it create a .env file. Populate it with PG_PASS=your_postgres_password and AUTHENTIK_SECRET_KEY=your_secret_key. You can also set AUTHENTIK_ERROR_REPORTING__ENABLED=false if you prefer to keep telemetry off. These variables get injected into the Compose file at runtime, so keep the .env file in the same directory as your docker-compose.yml.
Next, pull the official Compose file directly from Authentik’s repository with curl -O https://goauthentik.io/docker-compose.yml. Review the file before running it – Authentik publishes versioned releases, and the Compose file pins to a specific image tag. Check that the PostgreSQL and Redis versions match what your host can support. Once satisfied, run docker compose up -d from the directory. The initial pull takes a few minutes. When all four containers report healthy status via docker compose ps, navigate to http://your-host:9000/if/flow/initial-setup/ to create the first admin account.
Configuring an OIDC Provider and Application
Authentik separates the concepts of providers and applications. A provider defines the authentication protocol and settings. An application is what users see when they log in – it holds the name, icon, and policy bindings. You create them in sequence: provider first, then application pointing to that provider.
In the Authentik admin panel at /if/admin/, navigate to Applications > Providers and click Create. Choose OAuth2/OpenID Provider. Give it a name like Grafana OIDC. Set the authorization flow to default-provider-authorization-explicit-consent – this prompts users to approve the login the first time, which is standard OIDC behavior. Under redirect URIs, enter https://grafana.yourdomain.com/login/generic_oauth. Authentik will generate a client ID and client secret once you save; copy both immediately. The signing key should default to the auto-generated certificate Authentik creates at startup – leave it unless you have a specific key management requirement. After saving the provider, go to Applications > Applications, create a new entry, name it Grafana, set the slug to grafana, and bind it to the provider you just created. Assign it to the All Users group under Policy/Group Bindings unless you want to restrict access to a subset of users.
Now configure Grafana’s side. In Grafana’s grafana.ini (or via environment variables in its Compose definition), add a [auth.generic_oauth] block. Set enabled = true, name = Authentik, client_id and client_secret to the values from Authentik, and set the following URLs based on your Authentik host: auth_url = https://authentik.yourdomain.com/application/o/grafana/authorize/, token_url = https://authentik.yourdomain.com/application/o/token/, and api_url = https://authentik.yourdomain.com/application/o/userinfo/. Set scopes = openid email profile and role_attribute_path = contains(groups, ‘Grafana Admins’) && ‘Admin’ || ‘Viewer’ to map Authentik groups to Grafana roles. Restart Grafana, and the login page will show an Sign in with Authentik button alongside the standard form.
Outposts, MFA, and What Comes Next
Authentik supports a forward authentication proxy model through its outpost system. An outpost is a lightweight container that sits in front of an application and enforces authentication at the reverse proxy layer – meaning the downstream app does not need to support OAuth2 natively at all. Traefik and Nginx Proxy Manager both have documented integration paths with Authentik outposts, which opens the door to protecting apps like Portainer or static dashboards that have no built-in auth. The outpost deployment is managed from the Authentik admin UI under System > Outposts, and it pulls configuration from the server automatically once the API token is configured.
MFA enrollment works through Authentik’s flow system. By default, users can add TOTP (Google Authenticator, Authy) or WebAuthn (hardware keys, passkeys) from their profile page at /if/user/. If you want to require MFA for specific applications, create a new authentication flow in the admin panel, add a stage of type Authenticator Validation, and bind that flow to the provider instead of the default one. The policy engine can also enforce MFA only when a login comes from outside a trusted IP range – useful for homelab setups where local network logins feel redundant but external access needs the extra friction. Authentik’s stage-based flow builder is genuinely flexible once you understand the model: stages are individual steps, flows chain those steps together, and bindings attach flows to providers or applications.
One area worth careful attention is token expiry and session management. Authentik issues refresh tokens with a default lifetime that may outlast what you want for sensitive applications. Under the provider settings, the Access Token Validity field accepts duration strings like minutes=5 or hours=1. Shorter access token lifetimes mean more frequent silent refreshes, which is the correct tradeoff when the application holds any kind of sensitive data. The refresh token lifetime is separate and can be set independently – a common pattern is short access tokens with multi-day refresh tokens, so users stay logged in across sessions without holding a long-lived credential that could be replayed if intercepted.
Once Authentik is running and at least one application is wired up, the practical pressure to add more grows fast – every new service you deploy with its own login becomes an obvious candidate for the same SSO flow, and the Authentik admin interface makes adding providers a ten-minute task rather than a project. The harder question is around user lifecycle: what happens when you want to revoke access for a specific account across every connected application simultaneously, and whether the Grafana role mapping you set up on day one still makes sense when the group structure in Authentik evolves. OIDC does not propagate revocation in real time by default – an evicted user’s existing session in Grafana stays valid until the access token expires, which is exactly why that token lifetime setting matters more than it first appears.
Frequently Asked Questions
What authentication protocols does Authentik support?
Authentik supports OAuth2, OpenID Connect (OIDC), SAML, and LDAP, making it compatible with most modern self-hosted applications.
Can Authentik protect apps that have no built-in authentication?
Yes. Authentik’s outpost system works with reverse proxies like Traefik to enforce authentication at the proxy layer, regardless of the app’s native auth support.
