Authentik vs Authelia: Self-Hosted SSO Compared
Quick Verdict
Authelia is the better choice for most self-hosters. It does one thing well — adding authentication and MFA in front of your reverse proxy — and it does it with minimal resource usage and a straightforward YAML config. If all you need is to protect your web apps behind a login portal with two-factor auth, Authelia gets you there in minutes with under 30 MB of RAM.
Pick Authentik when you need a real identity provider: SAML support, user provisioning, an admin GUI for managing dozens of users, or SCIM directory sync. It is a full IAM platform, not an auth proxy. That power costs 800+ MB of RAM and a more involved setup.
The Core Difference
This is not an apples-to-apples comparison. These tools solve different problems that happen to overlap:
Authelia is an authentication proxy. It sits between your reverse proxy (Traefik, Nginx, Caddy) and your applications. When a user tries to access a protected app, the reverse proxy asks Authelia whether the request is authenticated. If not, the user sees a login portal. Authelia itself does not manage application access at the protocol level — it gates HTTP requests.
Authentik is a full identity provider (IdP). It speaks OIDC, SAML 2.0, LDAP, SCIM, and RADIUS. Applications connect to Authentik directly using standard identity protocols. It has a web-based admin console, user self-service portal, enrollment flows, and a policy engine. It is closer to Keycloak or Okta than it is to Authelia.
The overlap is that both can protect self-hosted apps with SSO and MFA. The question is how much identity infrastructure you actually need.
Feature Comparison
| Feature | Authentik | Authelia |
|---|---|---|
| Architecture | Full identity provider | Auth proxy / portal |
| OpenID Connect (OIDC) | Full provider | Certified provider (since v4.38) |
| SAML 2.0 | Full provider | Not supported |
| LDAP | Built-in LDAP outpost | Consumer only (can auth against LDAP) |
| Forward Auth (Traefik/Nginx) | Via embedded outpost | Native — this is the primary mode |
| Multi-Factor Auth | TOTP, WebAuthn/FIDO2, SMS, email, Duo | TOTP, WebAuthn/FIDO2, Duo |
| Admin UI | Full web-based admin console | None — YAML configuration only |
| User Self-Service | Portal with profile, app links, enrollment | Password reset, MFA registration |
| User Directory | Built-in with groups, attributes, SCIM sync | File-based (users.yml) or LDAP backend |
| Policy Engine | Visual flow designer with conditions and stages | Access control rules in YAML |
| Branding/Theming | Per-tenant branding, custom CSS, logo | Basic theming via CSS overrides |
| Idle RAM Usage | ~800 MB - 1.2 GB (server + worker + PostgreSQL) | ~20-30 MB (Authelia only) |
| Language | Python (Django) + Go (outposts) | Go |
| License | MIT (Enterprise features available) | Apache 2.0 |
| GitHub Stars | ~20k | ~24k |
| Docker Support | Official Compose with server + worker + PostgreSQL | Single container + optional DB |
Docker Compose: Authentik
Authentik requires three services: PostgreSQL, the server, and a background worker. As of 2025.10+, Redis is no longer required — PostgreSQL handles caching and task queuing.
Create a .env file first:
# Generate required secrets
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env
Your .env file should look like this:
# PostgreSQL password -- used by both the database and Authentik
PG_PASS=your-generated-password-here
# Authentik secret key -- used for signing tokens and cookies
AUTHENTIK_SECRET_KEY=your-generated-secret-here
# Optional: customize exposed ports (defaults: 9000/9443)
# COMPOSE_PORT_HTTP=9000
# COMPOSE_PORT_HTTPS=9443
docker-compose.yml:
services:
postgresql:
image: postgres:16-alpine
container_name: authentik-db
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- database:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS}
POSTGRES_USER: authentik
POSTGRES_DB: authentik
networks:
- authentik
server:
image: ghcr.io/goauthentik/server:2025.12.4
container_name: authentik-server
restart: unless-stopped
command: server
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
volumes:
- ./media:/media
- ./custom-templates:/templates
ports:
- "${COMPOSE_PORT_HTTP:-9000}:9000"
- "${COMPOSE_PORT_HTTPS:-9443}:9443"
depends_on:
postgresql:
condition: service_healthy
networks:
- authentik
worker:
image: ghcr.io/goauthentik/server:2025.12.4
container_name: authentik-worker
restart: unless-stopped
command: worker
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./media:/media
- ./certs:/certs
- ./custom-templates:/templates
depends_on:
postgresql:
condition: service_healthy
networks:
- authentik
volumes:
database:
networks:
authentik:
Start it:
docker compose up -d
Navigate to http://your-server:9000/if/flow/initial-setup/ to create the admin account. Authentik exposes a full admin dashboard at /if/admin/.
Docker Compose: Authelia
Authelia is a single Go binary. For a basic setup with a local SQLite database and file-based users, you need one container and two config files.
Create the directory structure:
mkdir -p ./authelia/config ./authelia/secrets
Generate secrets:
openssl rand -base64 32 > ./authelia/secrets/JWT_SECRET
openssl rand -base64 32 > ./authelia/secrets/SESSION_SECRET
openssl rand -base64 32 > ./authelia/secrets/STORAGE_ENCRYPTION_KEY
docker-compose.yml:
services:
authelia:
image: authelia/authelia:4.39.15
container_name: authelia
restart: unless-stopped
volumes:
- ./authelia/config:/config
- ./authelia/secrets:/secrets
environment:
TZ: "UTC"
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE: "/secrets/JWT_SECRET"
AUTHELIA_SESSION_SECRET_FILE: "/secrets/SESSION_SECRET"
AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE: "/secrets/STORAGE_ENCRYPTION_KEY"
ports:
- "9091:9091"
networks:
- authelia
networks:
authelia:
Create ./authelia/config/configuration.yml:
# Authelia configuration
# Docs: https://www.authelia.com/configuration/
server:
address: "tcp://0.0.0.0:9091"
log:
level: info
totp:
issuer: selfhosting.sh
authentication_backend:
file:
path: /config/users.yml
password:
algorithm: argon2id
iterations: 3
memory: 65536
parallelism: 4
salt_length: 16
access_control:
default_policy: deny
rules:
# Allow public access to specific subdomains
- domain: "public.example.com"
policy: bypass
# Require two-factor for sensitive apps
- domain: "*.example.com"
policy: two_factor
session:
cookies:
- name: authelia_session
domain: "example.com" # CHANGE THIS to your root domain
authelia_url: "https://auth.example.com" # CHANGE THIS
expiration: 1h
inactivity: 5m
storage:
local:
path: /config/db.sqlite3
notifier:
filesystem:
filename: /config/notification.txt
# For production, use SMTP instead:
# smtp:
# address: "smtp://mail.example.com:587"
# sender: "[email protected]"
# username: "[email protected]"
# password: "your-smtp-password"
Create ./authelia/config/users.yml:
# User accounts
# Generate password hashes: docker run --rm authelia/authelia:4.39.15 crypto hash generate argon2
users:
admin:
displayname: "Admin"
# Password: changeme (CHANGE THIS - generate a proper hash)
password: "$argon2id$v=19$m=65536,t=3,p=4$your-generated-hash-here"
email: [email protected]
groups:
- admins
- users
Start it:
docker compose up -d
Authelia is now listening on port 9091. You still need to configure your reverse proxy (Traefik, Nginx Proxy Manager, or Caddy) to use Authelia as a forward authentication provider. That is where the actual protection happens.
Performance and Resource Usage
This is where the difference is stark.
| Metric | Authentik | Authelia |
|---|---|---|
| Container count | 3 (server + worker + PostgreSQL) | 1 (Authelia only) |
| Idle RAM | 800 MB - 1.2 GB total | 20-30 MB |
| RAM under load | 1.5 - 2 GB+ | 50-100 MB |
| CPU (idle) | Moderate — Python + background worker | Negligible — compiled Go binary |
| Minimum specs | 2 CPU cores, 2 GB RAM | Runs on a Raspberry Pi Zero |
| Disk (application) | ~500 MB (images + database) | ~20 MB (binary + SQLite) |
| Startup time | 15-30 seconds (migrations, worker init) | 1-2 seconds |
Authentik is a Django application with a background worker process, a PostgreSQL database, and (prior to 2025.10) a Redis cache. That stack adds up. On a 4 GB homelab server running other services, Authentik takes a noticeable chunk.
Authelia is a single statically-compiled Go binary. It starts instantly, barely touches the CPU, and can run alongside dozens of other containers without anyone noticing. If your server has 2 GB of RAM or less, Authelia is the practical choice.
Setup Complexity
Authelia requires editing YAML config files by hand. There is no admin UI. You define users in a file (or point to an LDAP backend), write access control rules in YAML, and configure your reverse proxy to forward auth requests. The configuration surface is small and well-documented. Most setups take 15-30 minutes.
Authentik gives you a web-based admin console with a visual flow designer for authentication flows. You can configure OIDC providers, SAML applications, user enrollment, and access policies through a GUI. The trade-off is that the initial setup is more involved — understanding flows, stages, providers, and outposts takes time. Expect 1-2 hours for a first deployment with application integrations.
The irony: Authelia’s lack of a GUI makes simple setups faster. Authentik’s GUI makes complex setups manageable but adds overhead for simple ones.
Use Cases
Choose Authelia If…
- You want to add login + MFA in front of apps that do not support SSO natively (dashboards, admin panels, monitoring tools)
- You run Traefik, Nginx, or Caddy and want forward auth middleware
- Your server has limited resources (Raspberry Pi, 2 GB VPS)
- You have fewer than 20 users
- You prefer declarative YAML configuration over GUIs
- You do not need SAML, LDAP server, or SCIM
- You want the fastest path to “all my apps are behind a login page”
Choose Authentik If…
- You need a proper identity provider that speaks OIDC and SAML to applications
- You manage users across multiple apps and want centralized provisioning
- You want a web-based admin console for managing users, groups, and policies
- You need LDAP server functionality (Authentik can expose an LDAP interface)
- You run applications that require SAML 2.0 (many enterprise apps do)
- You want customizable authentication flows (enrollment, password reset, conditional MFA)
- You have the hardware headroom — at least 2 GB of RAM available for auth infrastructure
What About OIDC?
Both support OpenID Connect, but differently.
Authelia earned OpenID Certified status with v4.38. It can act as an OIDC provider for applications that support it. This is a significant addition — apps like Portainer, Grafana, and Gitea can authenticate directly against Authelia via OIDC without relying on forward auth. The OIDC support is newer and covers the common cases well.
Authentik has had OIDC support since its early days. Its implementation is more mature, with support for more grant types, token customization, and advanced claim mapping. If your applications rely heavily on OIDC features like dynamic client registration or complex scope configurations, Authentik has the edge.
For most self-hosted apps that just need “login with OIDC,” both work fine.
Final Verdict
For a typical self-hoster running 5-20 apps on a single server or small cluster, Authelia is the right tool. It protects everything behind a clean login portal with MFA, it barely uses any resources, and you can have it running in under 30 minutes. The addition of OIDC support means it now covers the vast majority of authentication needs without the overhead of a full IdP.
Authentik is the right tool when Authelia is not enough. If you are building a multi-user environment, need SAML for specific applications, want a GUI for user management, or are running infrastructure that resembles an organization more than a homelab, Authentik delivers enterprise-grade identity management without the enterprise price tag.
Neither is objectively better. They solve different problems at different scales. But for the question most people are actually asking — “how do I put a login page in front of my self-hosted apps?” — the answer is Authelia.
Related
Get self-hosting tips in your inbox
New guides, comparisons, and setup tutorials — delivered weekly. No spam.