Authentik on Kubernetes: SSO for Self-Hosted Infrastructure
Authentik on Kubernetes: SSO for Self-Hosted Infrastructure
Every self-hosted platform starts the same way. You deploy a service. It has its own login page. You create an account. Then you deploy another service. Another login page. Another account. By the time you have ten services running, you have ten passwords, ten session cookies, and zero centralized visibility into who is accessing what.
Authentik solves this. It's an open-source identity provider that handles SSO (SAML, OIDC, OAuth2), user management, MFA, and access policies -- all from a single platform. This guide covers deploying it on Kubernetes with HA PostgreSQL and integrating it with Traefik for transparent authentication.
Why Authentik over Keycloak
Keycloak is the more established name in open-source identity. It's battle-tested, well-documented, and has a massive community. So why Authentik?
Flows, not configuration files. Authentik uses a visual flow designer to define authentication sequences. Login flow, enrollment flow, recovery flow -- they're all drag-and-drop stages. Keycloak buries equivalent functionality in nested admin menus and XML exports.
Forward auth built in. Authentik natively supports Traefik's ForwardAuth middleware and Nginx auth_request. You can protect any web application with SSO without modifying the application itself. Keycloak can do this with a Gatekeeper proxy, but it's an additional component.
Outpost model. Authentik deploys "outposts" -- lightweight proxy containers that handle authentication at the edge. They run as separate pods, scale independently, and can be placed close to the services they protect.
Modern stack. Authentik is Python (Django) with a Go-based outpost. The admin UI is clean and responsive. Keycloak is Java/Quarkus with a UI that feels dated.
The trade-off: Keycloak has deeper enterprise federation support (Kerberos, LDAP sync with advanced mapping). If you're integrating with an existing Active Directory forest with complex trust relationships, Keycloak may be the better fit. For everything else, Authentik is faster to deploy and easier to operate.
Deployment architecture
Components
A production Authentik deployment on Kubernetes consists of:
- Authentik Server -- The main application. Handles the web UI, API, and authentication flows.
- Authentik Worker -- Background task processor. Handles email delivery, LDAP sync, and scheduled tasks.
- PostgreSQL -- Primary data store. User accounts, application configs, flow definitions.
- Redis -- Session storage, caching, and message broker between server and worker.
- Outpost(s) -- Optional. Deployed for forward auth or LDAP proxy use cases.
High availability
Single-instance Authentik works for labs. For production -- where every service depends on identity -- you need HA.
PostgreSQL: Use CloudNativePG (or a similar operator) to run a 3-node PostgreSQL cluster. Primary with two streaming replicas. Automatic failover if the primary goes down. This is the most critical component -- if the database is lost without backup, every user account and application configuration goes with it.
Redis: A single Redis instance with persistence is usually sufficient. Authentik uses Redis for ephemeral data (sessions, cache). If Redis restarts, users get logged out but nothing is permanently lost.
Authentik Server: Run at least 2 replicas behind a load balancer (Traefik, Nginx, or a Kubernetes Service). Authentik server is stateless -- it reads everything from PostgreSQL and Redis.
Authentik Worker: A single worker replica handles background tasks. For larger deployments with heavy LDAP sync or email volume, scale to 2.
Helm deployment
Authentik provides an official Helm chart. Here's a values file for a production deployment:
authentik:
secret_key: "<generate-a-strong-random-string>"
error_reporting:
enabled: false
postgresql:
host: authentik-postgresql-rw # CloudNativePG service
name: authentik
user: authentik
password: "<database-password>"
redis:
host: authentik-redis-0.authentik-redis-headless
server:
replicas: 2
ingress:
enabled: true
ingressClassName: traefik
hosts:
- auth.yourdomain.com
tls:
- secretName: auth-tls
hosts:
- auth.yourdomain.com
worker:
replicas: 1
Deploy:
helm repo add authentik https://charts.goauthentik.io
helm install authentik authentik/authentik \
--namespace authentik \
--create-namespace \
-f values.yaml
Traefik forward auth integration
This is where Authentik becomes genuinely powerful. Forward auth lets you protect any web application with SSO -- without modifying the application.
How it works
- User requests
https://grafana.yourdomain.com - Traefik intercepts the request and forwards it to Authentik's outpost
- Authentik checks: does this user have a valid session?
- If yes: Traefik proxies the request to Grafana with identity headers (
X-authentik-username,X-authentik-groups, etc.) - If no: Authentik redirects the user to the login page
The application never sees unauthenticated traffic. It doesn't need to know about OIDC, SAML, or any identity protocol. It just reads HTTP headers.
Configuration
In Authentik's admin UI:
- Create a Provider (type: Proxy Provider, forward auth mode)
- Set the external host to
https://grafana.yourdomain.com - Create an Application and link it to the provider
- Create an Outpost (type: Proxy) and assign the application to it
In your Traefik IngressRoute:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: authentik-auth
namespace: grafana
spec:
forwardAuth:
address: http://authentik-outpost.authentik.svc.cluster.local:9000/outpost.goauthentik.io/auth/traefik
trustForwardHeader: true
authResponseHeaders:
- X-authentik-username
- X-authentik-groups
- X-authentik-email
- X-authentik-name
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: grafana
namespace: grafana
spec:
entryPoints:
- websecure
routes:
- match: Host(`grafana.yourdomain.com`)
kind: Rule
middlewares:
- name: authentik-auth
services:
- name: grafana
port: 3000
tls:
secretName: grafana-tls
That's it. Grafana is now behind SSO. No Grafana configuration changes required. The same pattern works for any web application: ArgoCD, Harbor, Uptime Kuma, N8N -- any service with a web UI.
OIDC for applications that support it
Some applications have native OIDC/OAuth2 support. For these, direct integration is cleaner than forward auth because the application manages its own session lifecycle.
In Authentik:
- Create an OAuth2/OpenID Provider
- Set redirect URIs to
https://app.yourdomain.com/callback - Note the client ID and client secret
- Create an Application and link it
In the target application, configure OIDC with:
- Issuer:
https://auth.yourdomain.com/application/o/<app-slug>/ - Client ID: from Authentik
- Client secret: from Authentik
- Scopes:
openid profile email
GitLab, Grafana, Harbor, and ArgoCD all support native OIDC. Use it when available -- it gives the application awareness of the user's identity for its own RBAC, not just "authenticated or not."
What to protect and what not to
Not everything should go behind SSO. A good rule of thumb:
Protect with SSO:
- Admin interfaces (Grafana, ArgoCD, GitLab, Harbor)
- Internal tools (N8N, wiki, project management)
- Monitoring dashboards
- Any application with write access to infrastructure
Don't protect with SSO:
- Public-facing websites (your portfolio, marketing pages)
- API endpoints consumed by automated systems (use API keys or service accounts)
- Health check endpoints (monitoring systems need unauthenticated access)
Backup strategy
Authentik's entire state lives in PostgreSQL. Back up the database and you can rebuild everything:
- User accounts and credentials
- Application and provider configurations
- Flow definitions
- Policy bindings and group memberships
If you're running CloudNativePG, scheduled backups to object storage (MinIO, S3) give you point-in-time recovery. Test the restore. An untested backup is not a backup.
The identity layer matters
Identity is the one service that everything else depends on. If your monitoring goes down, you lose visibility. If your CI/CD goes down, you can't deploy. If your identity provider goes down, nobody can log into anything.
That's why Authentik runs with HA PostgreSQL, redundant server replicas, and automated backups. It's the foundation. Build it like one.