Repository / Identity and Access /Deployment Guide /Authentik on Kubernetes: SSO for Self-Hosted Infrastructure

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

  1. User requests https://grafana.yourdomain.com
  2. Traefik intercepts the request and forwards it to Authentik's outpost
  3. Authentik checks: does this user have a valid session?
  4. If yes: Traefik proxies the request to Grafana with identity headers (X-authentik-username, X-authentik-groups, etc.)
  5. 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:

  1. Create a Provider (type: Proxy Provider, forward auth mode)
  2. Set the external host to https://grafana.yourdomain.com
  3. Create an Application and link it to the provider
  4. 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:

  1. Create an OAuth2/OpenID Provider
  2. Set redirect URIs to https://app.yourdomain.com/callback
  3. Note the client ID and client secret
  4. 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.