Tech Digest

Head to head

Keycloak vs authentik

Both issue OIDC and SAML from a database-backed server. The difference is whether you need realms, token exchange and fine-grained authorization enough to run a JVM and read migration notes for every major.

Last reviewed 2 tools compared

Should you self-host Keycloak or authentik?

Choose authentik unless you need something Keycloak has and it does not: realms for genuinely separate tenants, token exchange, policy-based fine-grained authorization, or a name an auditor recognizes. authentik covers OIDC, SAML, an LDAP outpost and forward auth for apps with no login at all, which is the shape of a self-hosted stack. Keycloak is the more capable server and has the hardest upgrade path in this category, because its schema migration runs automatically on first start and does not run backwards.

These two overlap more than any other pair in this category. Both are full identity providers with a real database, both issue OIDC and SAML, both federate upward to an existing directory, both have a web admin UI, both are permissively licensed.

The decision is about shape, not capability. Keycloak was built for organizations with tenants, auditors and upgrade windows. authentik was built for a stack of self-hosted applications, half of which have no authentication at all. Each does the other's job worse.

Ask two questions. Do you need realms, token exchange or policy-based authorization? If yes, Keycloak, and nothing else here is close. Do you have applications with no login of their own that you need to protect? If yes, authentik, because Keycloak has no answer for that without a third product.

Read the container count and the RAM note#

The interesting rows are memory and container count. Keycloak is a JVM plus PostgreSQL; authentik is a Django server, a worker and PostgreSQL.

SpecificationKeycloakauthentik
LicenceApache-2.0 (Permissive)MIT (core); authentik/enterprise/ under a separate Authentik Security license (Permissive)
Written inJava (Quarkus)Python / Django, Go (outposts), TypeScript
First release20142020
MaturityMatureStable
DatastorePostgreSQL, MariaDB/MySQL, MSSQL or Oracle; a dev-file H2 database for development onlyPostgreSQL
Services to run23
Idle memory750 MB1000 MB
Memory in use1250 MB1600 MB
Operational load4 / 5, Heavy4 / 5, Heavy
IdentityNative OIDCNative OIDC
arm64 buildsYesYes
Default ports8080, 8443, 90009000, 9443
Backup shapePostgres dumpPostgres dump

Both land at ops load 4, and for the same underlying reason: a real database with a schema that migrates on upgrade. The difference is what a bad upgrade costs. authentik's breaking changes are configuration-shaped, so you fix a variable and restart. Keycloak's are schema-shaped, so you restore.

The Quarkus rewrite is finished, and most of the internet has not noticed#

Keycloak's distribution changed completely and it was not cosmetic. Quarkus became the default in 17.0.0, the WildFly distribution was removed in 20.0.0, and the keycloak-containers repository is archived. If a tutorial mentions standalone.xml, the JBoss CLI or the jboss/keycloak image, it is describing software that no longer exists.

What replaced it has its own shape you have to learn:

bash
# build-time options are baked into the image
kc.sh build --db=postgres --features=token-exchange

# run-time options are supplied at start
kc.sh start --optimized --hostname=https://id.example.com --proxy-headers=xforwarded

Database vendor, feature flags and some transaction settings are build-time options. Set them only as environment variables on an unoptimized image and Keycloak re-augments itself on every boot, adding tens of seconds to startup. Set them on an image started with --optimized and they are ignored or rejected. Knowing which image you are running is a prerequisite to debugging why a flag did nothing.

Two more Keycloak facts that copied-from-a-blog deployments get wrong:

  • start-dev is not a deployment. It enables HTTP, disables strict hostname resolution and stores everything in a dev-file H2 database inside the container. People run it for months and then lose the realm to a docker compose down -v. There is no supported H2 to PostgreSQL migration, so switching later means exporting realms and recreating credentials. Configure the database on day one.
  • Health and metrics moved off 8080. /health, /health/ready and /metrics are served on the management interface on port 9000, and they are off by default. Probes copied from older guides fail silently, so the orchestrator restarts a perfectly healthy Keycloak in a loop.

The upgrade path is the real cost of Keycloak#

This is the hardest upgrade story in this category, and it deserves a section rather than a footnote.

Every new version runs a Liquibase migration against the database on first start, automatically, with no prompt. It does not run backwards. A bad upgrade is not fixed by re-pulling the old tag, because the old jar now faces a newer schema. Your rollback is the PostgreSQL dump, which means taking one immediately before every upgrade, every time. Backing up a running database covers doing that safely on a running instance.

Then there are the per-major migration notes, which you must read in order. There is no supported way to jump three majors and hope. 26.0 alone:

  • removed the hostname v1 feature outright,
  • replaced the proxy option with proxy-headers plus proxy-trusted-addresses,
  • switched Infinispan marshalling from JBoss Marshalling to Protostream, which clears every cache on upgrade,
  • made persistent user sessions the default, so sessions and revoked tokens now write to PostgreSQL,
  • dropped the GELF log handler.

Hostname v2 also rejects dots in the path. Read the whole 26.0 section even coming from 25.

It is not all getting worse: 26.7 (July 2026) made zero-downtime patch upgrades the default within a major.minor stream. That helps with patches, not with majors.

authentik's equivalent cliffs are milder but real: 2025.10 removed Redis and moved caching, embedded outpost sessions and websockets into PostgreSQL, expecting roughly 50 percent more database connections, and 2026.8 made AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS mandatory before forwarded headers are honored. Both are fix-a-variable problems. Neither requires restoring a database. An update strategy that does not lose data covers building the habit that makes either survivable.

What Keycloak gives you that authentik does not#

Be specific, because "more enterprise" is not a reason:

  • Realms. Genuinely separate user populations, each with their own clients, branding, policies and signing keys. authentik has one user space with groups and tenancy-flavored branding, which is not the same thing. If you host services for two organizations that must not see each other, this is decisive.
  • Token exchange. Swapping one token for another, for service-to-service delegation. There is no equivalent.
  • Fine-grained authorization services. Keycloak can evaluate resource and scope permissions for your application, so authorization decisions live in the IdP rather than in each app.
  • User federation with write-back. LDAP and Kerberos federation where Keycloak is a front end to the existing directory, optionally writing changes back, rather than importing a copy. Point it at LLDAP and you have one password store with realms on top.
  • Institutional weight. CNCF incubating, with a Red Hat product built on the same code. That is worth nothing at home and quite a lot in a procurement review.

What authentik gives you that Keycloak does not#

  • A proxy provider with an embedded outpost. Forward auth for applications with no login, built in. Keycloak needs oauth2-proxy alongside it for the same job.
  • An LDAP outpost. authentik can serve LDAP to applications that speak nothing else. Keycloak consumes LDAP; it does not serve it.
  • A searchable event log covering every login, flow execution and API call, in the same UI you administer from.
  • Ergonomics for the actual job. Adding a self-hosted app to authentik is a provider and an application object. In Keycloak it is a client, then hostname and proxy settings you will get wrong at least once.

The licensing asymmetry is worth stating too. Keycloak is Apache-2.0 with nothing gated. authentik is MIT except authentik/enterprise/, which needs a paid subscription: Google Workspace and Entra ID provisioning, RADIUS with EAP-TLS, client certificate authentication, detailed audit logging and CSV export. None of that matters for a household, and outbound provisioning is the one people assume is free.

Which one for your situation#

SituationUseWhy
Ten self-hosted apps, some with no login at allauthentikProxy provider and LDAP outpost cover the gaps
Two client organizations on one serverKeycloakRealms are real isolation, not branding
You need token exchange or authorization servicesKeycloakauthentik has no equivalent
An auditor or customer has to recognize the nameKeycloakCNCF incubating, Red Hat product lineage
You already run Java and PostgreSQL with upgrade windowsKeycloakThe operational model matches what you have
One host, five apps, no upgrade windowauthentikOr drop a tier entirely to Authelia
Existing OpenLDAP or Active Directory to frontKeycloakFederation with configurable write-back
You want OIDC device enrollment for Headscale and little elseNeitherPocket ID does that in 30 MB
Under 2 GB RAM freeNeitherKeycloak wants 2 GB alone; authentik documents 2 GB

What to do next#

Write down the protocols your applications actually speak before you install either. If the list is OIDC and nothing else, both of these are oversized and Pocket ID vs Authelia is a more useful page. If SAML or an LDAP consumer appears on the list, you are choosing between these two, and the tiebreaker is usually whether you also need forward auth. Single sign-on for self-hosters has the process, The single sign-on gap has the numbers on how few self-hosted apps support anything at all, and if you pick Keycloak, set up the pre-upgrade pg_dump before you set up anything else. The rest of the category is at Identity.

Questions#

Is Keycloak still based on WildFly?

No, and anything you read about standalone.xml, the JBoss CLI or the jboss/keycloak image is dead information. Quarkus became the default distribution in 17.0.0 and the WildFly distribution was removed outright in 20.0.0; the old keycloak-containers repository is archived. Configuration is now CLI flags and environment variables, split into build-time options resolved by kc.sh build and run-time options. Search results from before 2022 will send you badly wrong.

Can I roll back a bad Keycloak upgrade by changing the image tag?

No. Liquibase migrates the database on first start of a new version, automatically and with no prompt, and there is no reverse migration. Recovering means restoring the PostgreSQL dump you took beforehand, so take one immediately before every upgrade. On a large realm the migration can also exceed the default timeout, and the upgrading guide documents both a timeout setting and a manual SQL export path for that case.

Does Keycloak do forward auth for apps with no login?

Not on its own. Keycloak issues tokens to applications that know how to consume them; it has no proxy outpost. Protecting an app with no authentication means putting oauth2-proxy or a similar gateway in front and pointing it at Keycloak. authentik ships that as a built-in proxy provider with an embedded outpost, which is one of the two reasons a homelab usually ends up on authentik.

How much RAM do these actually need?

Keycloak's container guide says give it at least 750 MB and suggests 2 GB for production, and the sizing guide budgets 1250 MB for a pod holding realm caches and 10,000 sessions, of which about 300 MB is non-heap. That is before PostgreSQL. authentik documents 2 CPU cores and 2 GB, and a real install sits near 1 GB idle across server, worker and Postgres. Neither belongs on a 2 GB machine.

What can Keycloak do that authentik cannot?

Realms, which give genuinely separate user populations with their own branding, policy and signing keys. Token exchange. Fine-grained authorization services, meaning policy-based permissions Keycloak evaluates for your application rather than just an identity assertion. LDAP and Kerberos user federation with configurable write-back, so it can be a front end to an existing directory rather than a copy of one. Plus a CNCF incubating badge and a Red Hat product built on it, which matters in a procurement conversation.

Which one is easier to keep in version control?

Neither is good, and both have an escape hatch. Keycloak has realm export from kc.sh export, which is useful for moving configuration between environments but is not a backup: it is not consistent with a live server and omits credentials unless you ask. authentik has blueprints, YAML documents it reconciles into the database, which is a second system to learn on top of the UI. If reviewable configuration is a hard requirement, Authelia's single YAML file is the tool that actually delivers it.

Sources#

Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.