Authelia Cheat Sheet
Overview
Authelia is an open-source authentication and authorization server that provides single sign-on (SSO) and two-factor authentication (2FA) for applications behind a reverse proxy. It acts as a companion to reverse proxies like Nginx, Traefik, HAProxy, and Caddy, intercepting requests and enforcing authentication policies before allowing access to protected services.
Authelia supports multiple second-factor methods including TOTP (time-based one-time passwords), WebAuthn/FIDO2 security keys, and Duo push notifications. It features password reset flows, access control rules based on domain, path, user, and group, and supports LDAP and file-based user backends with OpenID Connect identity provider capabilities.
Installation
# Docker (recommended)
docker pull authelia/authelia
# Docker Compose
mkdir authelia && cd authelia
curl -O https://raw.githubusercontent.com/authelia/authelia/master/examples/compose/lite/docker-compose.yml
curl -O https://raw.githubusercontent.com/authelia/authelia/master/examples/compose/lite/authelia/configuration.yml
# Linux binary
wget https://github.com/authelia/authelia/releases/latest/download/authelia-linux-amd64.tar.gz
tar xzf authelia-linux-amd64.tar.gz
sudo mv authelia /usr/local/bin/
# Kubernetes Helm
helm repo add authelia https://charts.authelia.com
helm install authelia authelia/authelia
# Verify
authelia --version
Core Configuration
# configuration.yml
server:
address: "tcp://0.0.0.0:9091/"
log:
level: info
theme: dark
default_redirection_url: "https://home.example.com"
totp:
issuer: example.com
period: 30
skew: 1
authentication_backend:
file:
path: /config/users_database.yml
password:
algorithm: argon2id
iterations: 3
memory: 65536
parallelism: 4
key_length: 32
salt_length: 16
access_control:
default_policy: deny
rules:
- domain: "public.example.com"
policy: bypass
- domain: "*.example.com"
policy: one_factor
- domain: "secure.example.com"
policy: two_factor
- domain: "admin.example.com"
policy: two_factor
subject:
- "group:admins"
session:
name: authelia_session
secret: insecure_session_secret
expiration: 1h
inactivity: 5m
remember_me: 1M
cookies:
- domain: example.com
authelia_url: https://auth.example.com
storage:
local:
path: /config/db.sqlite3
notifier:
filesystem:
filename: /config/notification.txt
User Database
# users_database.yml
users:
john:
displayname: "John Doe"
password: "$argon2id$v=19$m=65536,t=3,p=4$hash..."
email: john@example.com
groups:
- admins
- devops
jane:
displayname: "Jane Smith"
password: "$argon2id$v=19$m=65536,t=3,p=4$hash..."
email: jane@example.com
groups:
- developers
# Generate password hash
authelia crypto hash generate argon2 --password "YourSecurePassword"
# Generate random password and hash it
authelia crypto hash generate argon2 --random --random.length 72
LDAP Backend
authentication_backend:
ldap:
implementation: custom
address: "ldap://ldap.example.com:389"
timeout: 5s
start_tls: false
base_dn: "dc=example,dc=com"
additional_users_dn: "ou=users"
users_filter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=inetOrgPerson))"
additional_groups_dn: "ou=groups"
groups_filter: "(member={dn})"
user: "cn=admin,dc=example,dc=com"
password: "ldap-admin-password"
attributes:
username: uid
display_name: displayName
mail: mail
group_name: cn
Access Control Rules
access_control:
default_policy: deny
rules:
# Public endpoints (no auth)
- domain: "public.example.com"
policy: bypass
- domain: "*.example.com"
resources:
- "^/api/health$"
policy: bypass
# Single factor for general access
- domain:
- "app.example.com"
- "wiki.example.com"
policy: one_factor
# Two factor for sensitive services
- domain: "vault.example.com"
policy: two_factor
# Group-based access
- domain: "admin.example.com"
policy: two_factor
subject:
- "group:admins"
# Network-based rules
- domain: "internal.example.com"
policy: bypass
networks:
- "10.0.0.0/8"
- "172.16.0.0/12"
# Method-based rules
- domain: "api.example.com"
policy: one_factor
methods:
- GET
- HEAD
- domain: "api.example.com"
policy: two_factor
methods:
- POST
- PUT
- DELETE
Reverse Proxy Integration
Nginx
server {
listen 443 ssl;
server_name app.example.com;
location /authelia {
internal;
proxy_pass http://authelia:9091/api/authz/auth-request;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-Method $request_method;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-URI $request_uri;
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}
location / {
auth_request /authelia;
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
auth_request_set $email $upstream_http_remote_email;
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
proxy_set_header Remote-Email $email;
proxy_pass http://backend:8080;
}
}
Traefik
# docker-compose.yml with Traefik
services:
traefik:
image: traefik:v3
command:
- "--providers.docker=true"
- "--entrypoints.websecure.address=:443"
labels:
- "traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth"
- "traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true"
- "traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Email"
my-app:
image: my-app:latest
labels:
- "traefik.http.routers.my-app.rule=Host(`app.example.com`)"
- "traefik.http.routers.my-app.middlewares=authelia@docker"
OpenID Connect Provider
identity_providers:
oidc:
hmac_secret: "your-hmac-secret"
jwks:
- key_id: "main"
algorithm: RS256
use: sig
key: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
clients:
- client_id: grafana
client_name: Grafana
client_secret: "$pbkdf2-sha512$310000$hash..."
public: false
authorization_policy: two_factor
redirect_uris:
- "https://grafana.example.com/login/generic_oauth"
scopes:
- openid
- profile
- groups
- email
- client_id: portainer
client_name: Portainer
client_secret: "$pbkdf2-sha512$310000$hash..."
redirect_uris:
- "https://portainer.example.com"
scopes:
- openid
- profile
- email
Advanced Usage
Production Storage (PostgreSQL)
storage:
postgres:
address: "tcp://postgres:5432"
database: authelia
schema: public
username: authelia
password: "database-password"
tls:
skip_verify: false
Email Notifications
notifier:
smtp:
address: "submissions://smtp.gmail.com:465"
username: "noreply@example.com"
password: "app-password"
sender: "Authelia <noreply@example.com>"
subject: "[Authelia] {title}"
tls:
skip_verify: false
Redis Session Storage
session:
redis:
host: redis
port: 6379
password: "redis-password"
database_index: 0
maximum_active_connections: 8
Configuration
# Generate secrets
authelia crypto hash generate pbkdf2 --password "client-secret"
authelia crypto rand --length 64 --charset alphanumeric
# Validate configuration
authelia validate-configuration --config /config/configuration.yml
# Environment variable overrides
AUTHELIA_SESSION_SECRET=your-secret
AUTHELIA_STORAGE_POSTGRES_PASSWORD=db-password
AUTHELIA_NOTIFIER_SMTP_PASSWORD=smtp-password
AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET=hmac-secret
Troubleshooting
| Issue | Solution |
|---|---|
| Redirect loop | Check default_redirection_url and cookie domain settings |
| 401 on all requests | Verify reverse proxy forwards correct headers to Authelia |
| 2FA not working | Check TOTP time sync; verify totp.period and totp.skew |
| LDAP bind fails | Test LDAP credentials directly; check base DN and filters |
| Session not persisting | Ensure cookie domain matches; check Redis connection |
| OIDC client unauthorized | Verify client secret hash; check authorization_policy |
| Emails not sending | Test SMTP settings; check spam filters and app passwords |
| Access denied despite rules | Rules are evaluated top-to-bottom; first match wins |