Authentik vs Keycloak vs Authelia SSO 2026
Authentik vs Keycloak vs Authelia: Self-Hosted SSO and Auth 2026
TL;DR
Self-hosted SSO in 2026 has three serious options. Authelia is a lightweight reverse proxy authentication layer — under 30MB RAM, configured in YAML, purpose-built for adding 2FA to homelab services. Authentik is a full identity provider with a modern UI, flow-based customization, and OIDC/SAML support — the default recommendation for teams who want proper SSO without Keycloak's complexity. Keycloak is the enterprise standard — Java-based, Red Hat-backed, supports every protocol including Kerberos and Active Directory federation, but requires 400MB–2GB RAM and significant configuration investment. Start with Authelia for homelab, move to Authentik for team use, consider Keycloak only if enterprise AD integration is non-negotiable.
Key Takeaways
- Authelia: ~22K stars, Apache-2.0, Go — lightweight proxy auth, ~20MB container, YAML config, 2FA, not a full IdP
- Authentik: ~15K stars, MIT, Python/Go — full IdP, OIDC/SAML/LDAP, visual flow builder, 2GB RAM minimum
- Keycloak: ~25K stars, Apache-2.0, Java (Quarkus) — enterprise IdP, every protocol including Kerberos, 400MB–2GB+ RAM
- Critical distinction: Authelia is proxy authentication middleware, not an identity provider — it cannot issue OIDC tokens for apps that need proper OAuth flows
- Recommendation by use case: Homelab → Authelia; SMB/Team → Authentik; Enterprise with AD → Keycloak
- Authelia + Authentik: Many setups combine both — Authelia for simple reverse proxy protection, Authentik as the OIDC backend
Understanding the Difference: Proxy Auth vs Identity Provider
Before comparing these three tools, a critical distinction: Authelia is not an identity provider. This is the most common point of confusion.
Proxy authentication (Authelia): Sits in front of your services in your reverse proxy (Traefik, Nginx, Caddy). When you visit service.yourdomain.com, Authelia checks if you're authenticated. If not, it shows a login page. It stores your credentials and issues a session cookie. It's excellent for protecting services that don't have built-in authentication.
Identity provider (Authentik, Keycloak): Issues OIDC tokens and SAML assertions that applications use to authenticate users via standard protocols. Apps like Gitea, Outline, Nextcloud, and Grafana have built-in SSO support that requires an OIDC/SAML provider. Only Authentik and Keycloak can fill this role.
In practice, many homelabs run both:
- Authelia handles basic HTTP authentication for simple apps (simple dashboards, internal tools)
- Authentik (or Keycloak) handles OIDC SSO for apps with proper OAuth support
Comparison Table
| Feature | Authelia | Authentik | Keycloak |
|---|---|---|---|
| GitHub Stars | ~22K | ~15K | ~25K |
| License | Apache-2.0 | MIT | Apache-2.0 |
| Language | Go | Python (Django) + Go | Java (Quarkus) |
| RAM (idle) | ~20–30MB | ~500MB–1GB | ~400MB–2GB |
| RAM (recommended) | 256MB | 2GB | 4GB+ |
| Is a full IdP? | No (proxy auth only) | Yes | Yes |
| OIDC/OAuth 2.0 | Limited (proxy only) | Yes | Yes |
| SAML 2.0 | No | Yes | Yes (most complete) |
| LDAP | No | Yes (LDAP outpost) | Yes (federation + outbound) |
| Active Directory | No | Yes | Yes (best support) |
| Kerberos | No | No | Yes |
| Social login | No | Yes | Yes |
| MFA/2FA | Yes (TOTP, WebAuthn, Duo) | Yes (TOTP, WebAuthn, FIDO2) | Yes (TOTP, WebAuthn, SMS) |
| Passkeys/WebAuthn | Yes | Yes | Yes |
| Self-registration | No | Yes | Yes |
| User management UI | Basic | Excellent | Good (complex) |
| Flow customization | No | Yes (visual builder) | Yes (complex) |
| Branding/themes | No | Yes | Yes |
| Multi-tenancy | No | Yes | Yes (realms) |
| Federation | No | No | Yes (IdP chaining) |
| Config format | YAML files | Web UI + API | Web UI + CLI |
| GitOps-friendly | Yes | Partial | Partial |
| Setup complexity | Low | Medium | High |
| Reverse proxy integration | Native (Traefik/Nginx/Caddy) | Via outpost/proxy | Via reverse proxy headers |
Resource Usage in Detail
Resource usage is often the deciding factor for homelab users.
Authelia
Authelia's Go binary is remarkably lean. The Docker container is under 20MB in size. At runtime:
- Idle RAM: 15–30MB
- Peak (during auth flow): ~50–100MB
- Storage: Minimal (SQLite by default, a few MB for session data)
You can run Authelia on a Raspberry Pi alongside dozens of other services without noticing it. This is its killer advantage for resource-constrained homelabs.
Authentik
Authentik requires PostgreSQL and Redis alongside the main server container. Total stack:
- Authentik server: ~300–500MB RAM
- Authentik worker: ~200–400MB RAM
- PostgreSQL: ~100–300MB RAM
- Redis: ~30–50MB RAM
- Total: ~700MB–1.2GB RAM for a lightly-used instance
For a team setup, 2GB RAM dedicated to the Authentik stack is comfortable. The official documentation recommends 2 vCPU and 2GB RAM minimum.
Keycloak
Keycloak runs on Java (Quarkus), which means JVM overhead. However, Quarkus has significantly reduced Keycloak's startup time and memory footprint compared to the older WildFly-based versions.
- Idle RAM: ~400MB–800MB (Quarkus, depends on configuration)
- Under load: 1–4GB+ depending on concurrent sessions and realm complexity
- Database: External PostgreSQL required (add 100–300MB)
- Total: ~600MB–2.5GB RAM for a typical installation
For enterprise deployments, plan for 4–8GB RAM per Keycloak node, with clustering for high availability.
Setup and Configuration
Authelia
Authelia is configured entirely through YAML files. This is one of its strongest features for GitOps and infrastructure-as-code workflows.
# configuration.yml
server:
host: 0.0.0.0
port: 9091
log:
level: info
jwt_secret: a-very-long-secret-key
authentication_backend:
file:
path: /config/users_database.yml
access_control:
default_policy: deny
rules:
- domain: "*.yourdomain.com"
policy: two_factor
- domain: "public.yourdomain.com"
policy: bypass
session:
name: authelia_session
secret: another-long-secret
expiration: 1h
inactivity: 5m
domain: yourdomain.com
storage:
local:
path: /config/db.sqlite3
notifier:
smtp:
username: you@gmail.com
password: your-app-password
host: smtp.gmail.com
port: 587
sender: auth@yourdomain.com
Traefik integration:
# In your Traefik-managed service's Docker labels:
labels:
- "traefik.http.routers.myservice.middlewares=authelia@docker"
# Authelia middleware definition:
labels:
- "traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.yourdomain.com"
- "traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true"
- "traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email"
Authentik Docker Compose
version: "3.4"
services:
postgresql:
image: docker.io/library/postgres:16-alpine
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
redis:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- redis:/data
server:
image: ghcr.io/goauthentik/server:2024.12
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
volumes:
- ./media:/media
- ./custom-templates:/templates
ports:
- "0.0.0.0:9000:9000"
- "0.0.0.0:9443:9443"
depends_on:
- postgresql
- redis
worker:
image: ghcr.io/goauthentik/server:2024.12
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: redis
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: authentik
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./media:/media
- ./certs:/certs
- ./custom-templates:/templates
depends_on:
- postgresql
- redis
volumes:
database:
redis:
Keycloak Docker Compose
version: "3"
services:
keycloak:
image: quay.io/keycloak/keycloak:latest
command: start-dev # Use 'start' for production
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: ${KC_DB_PASSWORD}
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD}
KC_HOSTNAME: auth.yourdomain.com
KC_PROXY: edge # Behind reverse proxy
ports:
- "8080:8080"
depends_on:
- postgres
restart: unless-stopped
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: ${KC_DB_PASSWORD}
volumes:
- pg_data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
pg_data:
Note: For production, use start instead of start-dev and configure KC_HOSTNAME_STRICT=false, TLS certificates, and a proper database with backups.
Use Case Matrix
Homelab (1–5 users, personal services)
Recommended: Authelia with optional Authentik for apps that need proper OIDC.
Most homelab services (Portainer, Grafana, dashboards) don't have built-in auth. Authelia protects them with minimal resources. Add Authentik only for apps that have native OIDC support (Gitea, Outline, Nextcloud) and benefit from real SSO.
Small Team (5–50 users, business applications)
Recommended: Authentik
Authentik handles the full SSO flow for modern business apps, has a user-friendly admin UI, and supports SAML for legacy enterprise apps. The flow-based customization lets you add registration approval, MFA enrollment, and custom login pages without writing code. Resource usage is manageable on a 2–4GB RAM VPS.
Mid-size Business (50–500 users, mixed legacy/modern apps)
Recommended: Authentik or Keycloak depending on Active Directory requirements.
If your organization has Windows Active Directory and needs to federate users from AD into your self-hosted apps, Keycloak's AD integration is more mature. If you're building green-field with modern protocols, Authentik handles this tier well.
Enterprise (500+ users, Kerberos, AD federation, complex compliance)
Recommended: Keycloak
Keycloak is the only option in this space with full Kerberos support, deep Active Directory federation, and the battle-tested scalability for high-concurrency enterprise auth. Red Hat's backing means long-term security patching. The configuration complexity is real, but enterprise IT teams are accustomed to it.
Common Combinations
Authelia + Authentik: Run Authelia for simple proxy auth on services without OIDC support, and point Authelia to Authentik as its LDAP/OIDC backend for user management. This gives you single user management with both proxy auth and full IdP capabilities.
Authentik + Authelia: The reverse — use Authentik as the primary IdP, and deploy Authelia only for protecting legacy services that can't be updated with OIDC.
Keycloak + Vault: For enterprise secrets management, Keycloak integrates with HashiCorp Vault (or Infisical) for federated identity in CI/CD pipelines.
For hands-on setup guides, see our how to self-host Authentik guide, our Authelia authentication middleware guide, and our Keycloak self-hosting guide. If you're building a full self-hosted stack and need to understand where SSO fits, the best open source authentication solutions overview covers the broader landscape.
Troubleshooting Common Issues
Authelia: "missing redirects" on first login
The most common Authelia configuration error: the session.domain in configuration.yml must match the top-level domain of all your services. If your services are on *.home.yourdomain.com, set session.domain: home.yourdomain.com. A mismatch causes session cookies to not be shared across subdomains, resulting in infinite login loops.
Authentik: Worker not starting
If the Authentik worker container keeps restarting, check for PostgreSQL connection errors (docker logs authentik-worker-1). The most common cause is a missing AUTHENTIK_SECRET_KEY environment variable or a mismatch between the server and worker environment files. Generate a secret key with openssl rand -base64 36.
Keycloak: "Invalid redirect URI" on login
In Keycloak's admin console, every OIDC client must have its redirect URIs explicitly allowlisted. Navigate to Clients → [your client] → Settings → Valid redirect URIs and add https://yourapp.yourdomain.com/*. The wildcard at the end is intentional. A missing or incorrectly scoped redirect URI is the most common Keycloak integration error.
All three: Clock skew
OIDC tokens have short expiry windows (typically 5 minutes). If your server's clock is more than a few minutes off, token validation will fail with cryptic errors. Run timedatectl to check clock sync status and enable systemd-timesyncd or ntpd if needed.
Backup and Disaster Recovery
For SSO infrastructure, backup and recovery planning is critical — if your auth system goes down, users can't access any protected services.
Authelia backup is simple: back up configuration.yml, the users database file, and the SQLite file (if using local storage). Everything else is stateless. Recovery is fast — restore those files and restart the container.
Authentik requires backing up the PostgreSQL database and the /media volume (certificates, custom themes). Use pg_dump for the database on a schedule. Authentik can export flows, applications, and providers as blueprints — storing these in git gives you configuration-as-code for rapid recovery.
Keycloak state lives in PostgreSQL. Back up the database with pg_dump and test restores regularly. Keycloak's realm export feature (docker exec keycloak /opt/keycloak/bin/kc.sh export --dir /tmp/export) creates a JSON export of all realm configuration including clients, users (without passwords), and flows. This is invaluable for disaster recovery.
Migrating from Auth0 or Clerk to Self-Hosted
Many teams are moving from Auth0 (Okta) or Clerk to self-hosted identity solutions to control costs and data. Both Authentik and Keycloak can replace these services for most use cases.
From Auth0: Export users via Auth0's Management API (passwords are hashed and can be imported). In Authentik, configure OIDC applications with the same client IDs and secrets as your Auth0 apps — some apps can be migrated with a configuration change, no code changes required. In Keycloak, the migration tooling is similar.
From Clerk: Clerk's OIDC compatibility is limited; it's primarily an SDK-based product. Migration to Authentik or Keycloak typically requires updating application code to use standard OIDC libraries (e.g., next-auth with an OIDC provider instead of Clerk's proprietary SDK).
For detailed migration steps, see our guide to migrating from Auth0 to Keycloak and our best open source Auth0 alternatives overview.
Methodology
- Sources consulted: 8
- GitHub star data from GitHub.com, March 2026
- RAM benchmarks from official documentation and community measurements
- Protocol support from official documentation for each project
- Date: March 2026