Skip to content

Authelia

Deploy Authelia on Kubernetes — a full-featured authentication and authorization server with single sign-on (SSO), multi-factor authentication (TOTP, WebAuthn/FIDO2), OpenID Connect identity provider, and forward-auth middleware support for Traefik, nginx, Caddy, and Envoy.

storageEncryptionKey protects MFA registrations — losing it permanently destroys all TOTP and WebAuthn data

Authelia requires three secrets before it can start. The most critical is storageEncryptionKey (20+ chars), which encrypts all MFA secrets stored in the database — TOTP keys and WebAuthn credentials. If this key is lost or rotated, all MFA device registrations become permanently unreadable and users must re-enroll. Always persist all three secrets via secrets.existingSecret before the first deployment.

Three secrets are required — Authelia will not start if any is missing
SecretMinimum LengthPurpose
jwtSecret64 charsSigns identity tokens for password resets.
sessionSecret64 charsEncrypts session cookies.
storageEncryptionKey20 charsEncrypts MFA secrets (TOTP, WebAuthn) in the DB.

Generate with: openssl rand -base64 64 | head -c 64

Key Features

  • Forward auth middleware — native Traefik, nginx, Caddy, and Envoy integration
  • MFA — TOTP, WebAuthn/FIDO2, and Duo Push
  • OpenID Connect IdP — certified OIDC provider for app SSO
  • File or LDAP auth backends — local YAML user database or LDAP/AD directory
  • Access control rules — domain, user, group, network, and method policies
  • Brute force protection — configurable regulation (max_retries, ban_time)
  • Prometheus metrics with optional ServiceMonitor

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install authelia helmforge/authelia -f values.yaml

OCI registry:

helm install authelia oci://ghcr.io/helmforgedev/helm/authelia -f values.yaml

Deployment Examples

# values.yaml — Authelia with SQLite and file-based user database
secrets:
  existingSecret: authelia-master-secrets
  existingSecretJwtKey: jwt-secret # 64+ chars
  existingSecretSessionKey: session-secret # 64+ chars
  existingSecretStorageEncryptionKey: storage-encryption-key # 20+ chars

config:
  session:
    cookies:
      - domain: example.com
        authelia_url: 'https://auth.example.com'
        default_redirection_url: 'https://www.example.com'
  access_control:
    default_policy: one_factor
    rules:
      - domain: 'public.example.com'
        policy: bypass
      - domain: '*.example.com'
        policy: two_factor
  notifier:
    # filesystem notifier logs to /data/notification.txt — email not sent
    # Switch to smtp notifier for production email delivery
    filesystem:
      filename: /data/notification.txt

usersDatabase:
  enabled: true
  users:
    admin:
      displayname: 'Administrator'
      email: 'admin@example.com'
      # Generate password hash: authelia crypto hash generate argon2 --password 'mypassword'
      password: '$argon2id$v=19$m=65536,t=3,p=4$...'
      groups:
        - admins

persistence:
  enabled: true
  size: 1Gi

ingress:
  enabled: true
  ingressClassName: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: auth.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: authelia-tls
      hosts:
        - auth.example.com
# values.yaml — Authelia HA: PostgreSQL + Redis (required for multi-replica)
replicaCount: 2 # requires Redis for session coordination

secrets:
  existingSecret: authelia-master-secrets

config:
  session:
    cookies:
      - domain: example.com
        authelia_url: 'https://auth.example.com'
  access_control:
    default_policy: two_factor
  notifier:
    smtp:
      address: 'submissions://smtp.example.com:465'
      sender: 'Authelia <authelia@example.com>'
      username: 'authelia@example.com'
      password: 'smtp-password' # use extraEnv with secretKeyRef in production

postgresql:
  enabled: true
  auth:
    database: authelia
    username: authelia
    password: 'strong-db-password'

redis:
  enabled: true
  auth:
    password: 'strong-redis-password'

database:
  type: postgres

persistence:
  enabled: true
  size: 1Gi

backup:
  enabled: true
  schedule: '0 2 * * *'
  s3:
    endpoint: https://s3.amazonaws.com
    bucket: authelia-backups
    existingSecret: authelia-s3-credentials

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: auth.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Authelia configured for Traefik forwardAuth middleware
# After deploying, create a Traefik Middleware resource in the same namespace:
#
# apiVersion: traefik.io/v1alpha1
# kind: Middleware
# metadata:
#   name: authelia
# spec:
#   forwardAuth:
#     address: http://authelia.authelia.svc.cluster.local/api/authz/forward-auth
#     trustForwardHeader: true
#     authResponseHeaders:
#       - Remote-User
#       - Remote-Groups
#       - Remote-Name
#       - Remote-Email
#
# Then add annotation to protected services:
#   traefik.ingress.kubernetes.io/router.middlewares: <namespace>-authelia@kubernetescrd

secrets:
  existingSecret: authelia-master-secrets

config:
  session:
    cookies:
      - domain: example.com
        authelia_url: 'https://auth.example.com'
  access_control:
    default_policy: one_factor
    rules:
      - domain: 'auth.example.com'
        policy: bypass
      - domain: '*.example.com'
        policy: one_factor

usersDatabase:
  enabled: true
  users:
    admin:
      displayname: 'Admin'
      email: 'admin@example.com'
      password: '$argon2id$v=19$m=65536,t=3,p=4$...'
      groups:
        - admins

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: auth.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — Authelia as OIDC identity provider
secrets:
  existingSecret: authelia-master-secrets
  existingSecretOidcHmacKey: oidc-hmac-secret # required for OIDC

config:
  session:
    cookies:
      - domain: example.com
        authelia_url: 'https://auth.example.com'
  access_control:
    default_policy: two_factor
  identity_providers:
    oidc:
      clients:
        - client_id: grafana
          client_name: Grafana
          client_secret: '$pbkdf2-sha512$310000$...' # hashed client secret
          public: false
          authorization_policy: two_factor
          redirect_uris:
            - 'https://grafana.example.com/login/generic_oauth'
          scopes:
            - openid
            - profile
            - email
            - groups
          userinfo_signed_response_alg: none

postgresql:
  enabled: true
  auth:
    password: 'strong-db-password'

redis:
  enabled: true
  auth:
    password: 'strong-redis-password'

database:
  type: postgres

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: auth.example.com
      paths:
        - path: /
          pathType: Prefix

Configuration Reference

Image

ParameterTypeDefaultDescription
image.repositorystringdocker.io/authelia/autheliaAuthelia image.
image.tagstring"4.39.16"Image tag.

Secrets

ParameterTypeDefaultDescription
secrets.jwtSecretstring""JWT signing secret (64+ chars). Required.
secrets.sessionSecretstring""Session cookie encryption secret (64+ chars). Required.
secrets.storageEncryptionKeystring""MFA data encryption key (20+ chars). Required. Never rotate.
secrets.oidcHmacSecretstring""OIDC HMAC secret. Required only when using OIDC.
secrets.existingSecretstring""Existing secret containing all secret keys.
secrets.existingSecretJwtKeystringjwt-secretKey for JWT secret.
secrets.existingSecretSessionKeystringsession-secretKey for session secret.
secrets.existingSecretStorageEncryptionKeystringstorage-encryption-keyKey for storage encryption key.
secrets.existingSecretOidcHmacKeystringoidc-hmac-secretKey for OIDC HMAC secret.

Configuration

The config block is rendered as Authelia’s configuration.yml. Key sub-sections:

SectionDescription
config.session.cookiesDomain and Authelia URL for cookie scope (must match ingress).
config.access_control.rulesAccess control policies per domain, group, user, and network.
config.access_control.default_policyDefault policy: bypass, one_factor, two_factor, deny.
config.notifier.filesystemLog notifications to file (no email). Default.
config.notifier.smtpSMTP notifier for email delivery (password resets, device enroll).
config.totpTOTP algorithm, period, digits.
config.webauthnWebAuthn/FIDO2 display name and timeout.
config.regulationBrute force: max_retries, find_time, ban_time.
config.identity_providers.oidcOIDC client registrations.

Users Database

ParameterTypeDefaultDescription
usersDatabase.enabledbooleantrueEnable file-based user database at /config/users_database.yml.
usersDatabase.existingSecretstring""Existing secret with the users_database.yml content.
usersDatabase.usersobject{}Inline user definitions. Passwords must be Argon2 hashes.
Generate Argon2 password hashes with the Authelia CLI

Authelia enforces Argon2id hashes for user passwords. Generate a hash using the CLI:

docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'mypassword'

The output hash goes in usersDatabase.users.<user>.password.

Database

ParameterTypeDefaultDescription
database.typestringsqliteStorage backend: sqlite, postgres, mysql.
database.external.hoststring""External database hostname.
database.external.existingSecretstring""Existing secret with database password.
database.external.existingSecretPasswordKeystringpasswordKey for the database password.

Subcharts

ParameterTypeDefaultDescription
postgresql.enabledbooleanfalseDeploy the bundled PostgreSQL subchart.
postgresql.auth.passwordstring""Password. Required when using the subchart.
mysql.enabledbooleanfalseDeploy the bundled MySQL subchart.
redis.enabledbooleanfalseDeploy the bundled Redis subchart (required for HA).
redis.auth.passwordstring""Password. Required when using the subchart.

Persistence, Service, Metrics

ParameterTypeDefaultDescription
persistence.enabledbooleantrueEnable PVC for /data (SQLite DB, filesystem notifier).
persistence.sizestring1GiPVC size.
service.portinteger80Service port (Authelia listens on 9091).
metrics.enabledbooleanfalseEnable separate metrics service on port 9959.
metrics.serviceMonitor.enabledbooleanfalseEnable Prometheus ServiceMonitor.

Backup

ParameterTypeDefaultDescription
backup.enabledbooleanfalseEnable scheduled S3 backup CronJob.
backup.schedulestring"0 2 * * *"Cron schedule.
backup.s3.endpointstring""S3-compatible endpoint URL.
backup.s3.bucketstring""Target bucket name.
backup.s3.existingSecretstring""Existing secret with S3 credentials.
extraManifestsarray[]Extra Kubernetes manifests.

More Information