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.
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.
| Secret | Minimum Length | Purpose |
|---|---|---|
jwtSecret |
64 chars | Signs identity tokens for password resets. |
sessionSecret |
64 chars | Encrypts session cookies. |
storageEncryptionKey |
20 chars | Encrypts 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: PrefixConfiguration Reference
Image
| Parameter | Type | Default | Description |
|---|---|---|---|
image.repository |
string | docker.io/authelia/authelia |
Authelia image. |
image.tag |
string | "4.39.22" |
Image tag. |
Secrets
| Parameter | Type | Default | Description |
|---|---|---|---|
secrets.jwtSecret |
string | "" |
JWT signing secret (64+ chars). Required. |
secrets.sessionSecret |
string | "" |
Session cookie encryption secret (64+ chars). Required. |
secrets.storageEncryptionKey |
string | "" |
MFA data encryption key (20+ chars). Required. Never rotate. |
secrets.oidcHmacSecret |
string | "" |
OIDC HMAC secret. Required only when using OIDC. |
secrets.existingSecret |
string | "" |
Existing secret containing all secret keys. |
secrets.existingSecretJwtKey |
string | jwt-secret |
Key for JWT secret. |
secrets.existingSecretSessionKey |
string | session-secret |
Key for session secret. |
secrets.existingSecretStorageEncryptionKey |
string | storage-encryption-key |
Key for storage encryption key. |
secrets.existingSecretOidcHmacKey |
string | oidc-hmac-secret |
Key for OIDC HMAC secret. |
Configuration
The config block is rendered as Authelia’s configuration.yml. Key sub-sections:
| Section | Description |
|---|---|
config.session.cookies |
Domain and Authelia URL for cookie scope (must match ingress). |
config.access_control.rules |
Access control policies per domain, group, user, and network. |
config.access_control.default_policy |
Default policy: bypass, one_factor, two_factor, deny. |
config.notifier.filesystem |
Log notifications to file (no email). Default. |
config.notifier.smtp |
SMTP notifier for email delivery (password resets, device enroll). |
config.totp |
TOTP algorithm, period, digits. |
config.webauthn |
WebAuthn/FIDO2 display name and timeout. |
config.regulation |
Brute force: max_retries, find_time, ban_time. |
config.identity_providers.oidc |
OIDC client registrations. |
Users Database
| Parameter | Type | Default | Description |
|---|---|---|---|
usersDatabase.enabled |
boolean | true |
Enable file-based user database at /config/users_database.yml. |
usersDatabase.existingSecret |
string | "" |
Existing secret with the users_database.yml content. |
usersDatabase.users |
object | {} |
Inline user definitions. Passwords must be Argon2 hashes. |
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
| Parameter | Type | Default | Description |
|---|---|---|---|
database.type |
string | sqlite |
Storage backend: sqlite, postgres, mysql. |
database.external.host |
string | "" |
External database hostname. |
database.external.existingSecret |
string | "" |
Existing secret with database password. |
database.external.existingSecretPasswordKey |
string | password |
Key for the database password. |
Subcharts
| Parameter | Type | Default | Description |
|---|---|---|---|
postgresql.enabled |
boolean | false |
Deploy the bundled PostgreSQL subchart. |
postgresql.auth.password |
string | "" |
Password. Required when using the subchart. |
mysql.enabled |
boolean | false |
Deploy the bundled MySQL subchart. |
redis.enabled |
boolean | false |
Deploy the bundled Redis subchart (required for HA). |
redis.auth.password |
string | "" |
Password. Required when using the subchart. |
Persistence, Service, Metrics
| Parameter | Type | Default | Description |
|---|---|---|---|
persistence.enabled |
boolean | true |
Enable PVC for /data (SQLite DB, filesystem notifier). |
persistence.size |
string | 1Gi |
PVC size. |
service.port |
integer | 80 |
Service port (Authelia listens on 9091). |
metrics.enabled |
boolean | false |
Enable separate metrics service on port 9959. |
metrics.serviceMonitor.enabled |
boolean | false |
Enable Prometheus ServiceMonitor. |
Backup
| Parameter | Type | Default | Description |
|---|---|---|---|
backup.enabled |
boolean | false |
Enable scheduled S3 backup CronJob. |
backup.schedule |
string | "0 2 * * *" |
Cron schedule. |
backup.s3.endpoint |
string | "" |
S3-compatible endpoint URL. |
backup.s3.bucket |
string | "" |
Target bucket name. |
backup.s3.existingSecret |
string | "" |
Existing secret with S3 credentials. |
extraManifests |
array | [] |
Extra Kubernetes manifests. |
Upgrading to 4.39.22
Authelia 4.39.21 changes storage encryption to use HKDF and authenticated additional data; 4.39.22 fixes the access-token JWT session migration. Back up the database and retain the storage encryption key before upgrading. Allow startup migrations to complete before serving traffic. A rollback may require restoring the matching database backup and key.
Generated credentials are retained through Helm cluster lookup. Use an existing
Secret for GitOps or offline rendering, where lookup cannot retrieve the installed
key. Do not rotate the storage key during this update. After rollout, run
authelia storage encryption check --config /config/configuration.yml inside the
Authelia container and verify application health and MFA enrollment.
See the 4.39.21 release notes and 4.39.22 migration fix.