Skip to main content

Authentik vs Keycloak vs Authelia SSO 2026

·OSSAlt Team
authentikkeycloakautheliassoself-hostedidentity-provider
Share:

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

FeatureAutheliaAuthentikKeycloak
GitHub Stars~22K~15K~25K
LicenseApache-2.0MITApache-2.0
LanguageGoPython (Django) + GoJava (Quarkus)
RAM (idle)~20–30MB~500MB–1GB~400MB–2GB
RAM (recommended)256MB2GB4GB+
Is a full IdP?No (proxy auth only)YesYes
OIDC/OAuth 2.0Limited (proxy only)YesYes
SAML 2.0NoYesYes (most complete)
LDAPNoYes (LDAP outpost)Yes (federation + outbound)
Active DirectoryNoYesYes (best support)
KerberosNoNoYes
Social loginNoYesYes
MFA/2FAYes (TOTP, WebAuthn, Duo)Yes (TOTP, WebAuthn, FIDO2)Yes (TOTP, WebAuthn, SMS)
Passkeys/WebAuthnYesYesYes
Self-registrationNoYesYes
User management UIBasicExcellentGood (complex)
Flow customizationNoYes (visual builder)Yes (complex)
Branding/themesNoYesYes
Multi-tenancyNoYesYes (realms)
FederationNoNoYes (IdP chaining)
Config formatYAML filesWeb UI + APIWeb UI + CLI
GitOps-friendlyYesPartialPartial
Setup complexityLowMediumHigh
Reverse proxy integrationNative (Traefik/Nginx/Caddy)Via outpost/proxyVia 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

Comments

Get the free Self-Hosting Migration Guide

Complete guide to migrating from SaaS to self-hosted open-source — infrastructure, data migration, backups, and security. Plus weekly OSS picks.

No spam. Unsubscribe anytime.