Okta, Auth0 and Microsoft Entra ID run your company's login as a service, at a price per user. Keycloak and authentik do the same job on a server of your own: one login with two-factor for all your apps, over OpenID Connect or SAML, with no price per user. We gave both the same company setup on the same server. What Okta, Auth0 and Entra ID charge, and what you give up by leaving them, is near the end of this page, from their own pages.
The short answer
Pick Keycloak if you want the complete company login out of the box: password rules, lockout, password history and login pages and emails in Swedish are all built in and free, it used half the memory, and it is Apache 2.0 with nothing held back. Pick authentik if you want the friendlier admin interface, simple per-app access by group, and a login gate for apps that have no sign-in of their own, without an extra service, and you can live with English-only login pages and a few features behind its paid Enterprise licence.
What we tested
We installed both on the same fresh Melonslab VC-P Alloy (2 vCPU, 8 GB) with Debian 13, by following our guides Keycloak with rootless Podman and authentik with rootless Podman step by step, with the wiki from the Outline guide as the app to log in to. Each ran under a user of its own, behind the same Caddy. Every step in both guides worked as written.
Then we gave both the same company setup:
- a group, Staff, and three users: Anna and Erik in Staff, and Olle outside it;
- a one-time code from an authenticator app (TOTP) required from everyone, set up at the first login;
- passwords of at least 12 characters, and lockout after five failed logins;
- a password reset by email that still asks for the one-time code and keeps the authenticator app;
- Outline 1.11.0 connected over OpenID Connect, and only Staff allowed into it;
- one more app with no login of its own, put behind a login with Caddy's
forward_auth.
We logged in to Outline as all three users in both, tried wrong codes and wrong passwords, reset passwords by email, rebooted the server, measured the memory, and ran each guide's backup and restored it into an empty database. We tested the emails with a test mail server on the same machine, not through a real provider.
The numbers
| Keycloak 26.8.1 | authentik 2026.8.3 | |
|---|---|---|
| Containers | 2: Keycloak, PostgreSQL 18 | 3: server, worker, PostgreSQL 18 |
| Memory, idle after a reboot | about 480 MB (Keycloak 464, PostgreSQL 13) | about 990 MB (server 681, worker 275, PostgreSQL 33) |
| Images on disk | 0.79 GB | 1.68 GB |
| Database after the test | 72 MB | 91 MB |
From useradd to a working login page | about 3 minutes | about 7 minutes |
| Steps in our guide | 14 | 11 |
| Company setup in our guide | all of it except limiting an app to a group | users and one app; two-factor is optional, no email |
| Backup | 387 KB database dump, 101 KB realm export | 5.8 MB database dump, key and an empty upload folder |
| Login pages and emails in Swedish | yes | no |
| Login gate for apps without single sign-on | needs oauth2-proxy, a separate project | built in |
| Licence | Apache 2.0 | MIT, with Enterprise features under a paid licence |
Memory is the sum of each app's containers, measured with podman stats five minutes after a reboot. Keycloak's guide caps Keycloak at 1.5 GB; authentik has no cap. Keycloak became ready in under two minutes from the start of the image download; authentik took about five, mostly to download its 1.37 GB image and set up its database, and then waits for its admin account to be created in the browser.
Setup
Keycloak's guide does almost the whole company setup itself. The temporary admin is replaced from the command line before Keycloak is on the internet, the admin console is reached only through an SSH tunnel, and one kcadm command creates the company realm with the password policy, lockout, Swedish and password reset switched on. Two-factor for everyone and a reset that keeps the second factor take a copy of a login flow each, which the guide walks through in the console.
authentik's guide is shorter and older, and stops after users and one app. Its first-run page is on the public address until you fill it in, so do that at once. The rest of our setup we added ourselves, from authentik's documentation:
- Two-factor for everyone: in the stage
default-authentication-mfa-validation, set Not configured action to force setup, withdefault-authenticator-totp-setupas the setup stage. Users without an app then set one up at their next login. - Email: five
AUTHENTIK_EMAIL__settings inauthentik.env, with the password as a Podman secret. - Password reset: authentik ships an example blueprint, "Recovery with email and MFA verification", that you apply under Customization > Blueprints. You then pick that flow as the recovery flow in the login's identification stage, so Forgot username or password? appears, and in the brand. We also set its MFA stage to force setup, so that a new user who sets their password from an emailed link also has to add an authenticator app.
- Password policy: raise the length in
default-password-change-password-policyand add it to the reset flow's password prompt. - Lockout: a reputation policy and a deny stage, see below.
Neither has a quick path for everything: in Keycloak, the work is in flows; in authentik, in flows, stages and policies, wired together. Both have a full admin API; we did the company settings through Keycloak's kcadm and authentik's API, and checked the screens in both admin interfaces.
Two-factor, passwords and lockout
Both required a one-time code from every user and refused a wrong one. The differences were in the details.
| Keycloak | authentik | |
|---|---|---|
| Password length | length(12) | length in the password policy, plus a strength check (zxcvbn) |
| Not the username or email | built in | not as a rule; the strength check catches some |
| Not one of the last passwords | built in | Enterprise only: "Enterprise is required to create/update this object" |
| Temporary password, changed at first login | yes | no; you email the user a link to set their own |
| Lockout | built in, per account, from 1 up to 15 minutes | a reputation policy and a deny stage, which you add |
Keycloak's lockout worked as its guide says: after five failed logins the right password was refused, with the same "Invalid username or password" as a wrong one, and the lock ran out by itself. Wrong one-time codes counted too.
authentik cancels a login after five wrong passwords, but you can start a new one at once. To lock an account, we added a reputation policy that checks the username, with threshold −5, and bound it to a deny stage placed before the password stage in the login flow. After five failures, even the right password was refused with our message. Wrong one-time codes lower the score as well. The block lasts until the score expires, after 24 hours by default, unless an admin deletes the user's reputation score. Two catches: with the policy negated, as you might guess, it blocked everyone, since the policy passes when the score is bad; and the score is per username across all addresses, so like Keycloak, anyone can lock a person out.
Password reset by email
Both sent a reset link, asked for the one-time code, accepted a new password and kept the authenticator app.
- Keycloak's email arrived in Swedish, "Återställ lösenord", for a user who saw the login page in Swedish.
- authentik's email had the subject "authentik", in English, and its link opened a page asking the user to confirm with Continue before going on.
Connecting Outline
Both worked over OpenID Connect, and Outline linked the existing admin to the new login by email address.
Keycloak needed only the client from its guide.
authentik needed one thing its guide does not mention: its default email mapping sends email_verified: false, and Outline refused everyone with "Your email address has not been verified by authentik". We added a scope mapping for email that returns email_verified: true, and swapped it in on Outline's provider. After that, Outline's OIDC_LOGOUT_URI is https://auth.example.com/application/o/outline/end-session/.
Limiting an app to one group
This was the biggest difference in daily admin work.
authentik: on the application, add a binding to the group Staff. Olle got "Permission denied" after logging in, and still did after resetting his password by email.
Keycloak has no such switch for OpenID Connect apps. We gave Outline's client a role, access, gave that role to the Staff group, and built a login flow of its own for Outline, with a step that checks the role and a Deny access step, set as the client's browser flow. Olle then got "Access denied". But the password reset uses the realm's reset flow, not the client's, and when Olle reset his password from Outline's login page, he landed in Outline. We closed that by adding the same check to the reset flow, limited to Outline with a client scope that only Outline has. If you limit apps by group in Keycloak, test the reset path too.
Apps without single sign-on
Many internal tools have no login of their own. Both can put one in front of them with Caddy's forward_auth, and both worked with our test app, letting Erik in and keeping Olle out.
- authentik has it built in. A Proxy Provider in Forward auth (single application) mode, added to the embedded outpost that runs inside authentik's server, and a Caddy block that sends
/outpost.goauthentik.io/*to authentik and checks every other request withforward_auth. Group bindings work as for any app. Nothing extra runs. - Keycloak needs a separate program. We used oauth2-proxy 7.15.5, its own container with a Keycloak client, a cookie secret, and a Caddy block that sends
/oauth2/*to it and redirects to its login page on a 401. It used about 10 MB of memory and 46 MB of disk. Two settings were not obvious: its Keycloak provider asks for agroupsscope that Keycloak does not have, so set--scope="openid email profile", and limiting to a group needs a group mapper on the client and--allowed-group=/Staff.
Other protocols and passkeys
We did not test these; this is what each project's current documentation and admin interface list.
- SAML 2.0: both, for apps that log in with SAML.
- LDAP: Keycloak reads users from an existing LDAP server or Active Directory, but does not act as an LDAP server for apps. authentik can do both; an app that only speaks LDAP can log in against authentik, through an LDAP outpost, which runs as a separate container.
- SCIM: Keycloak 26.8 has a SCIM API, supported and on by default, so another system can create users and groups in Keycloak. authentik's SCIM provider does the opposite: it creates your users and groups in other apps.
- Also in authentik: RADIUS, and remote desktop and SSH in the browser.
- Passkeys: both. Keycloak's passkeys feature is on by default; authentik's users add a WebAuthn device under their own settings. Our two-factor setup used one-time codes in both.
Swedish
Keycloak comes translated into Swedish: the login pages, the account page and the emails. With Swedish on the realm's list, our browser set to Swedish got "Logga in till ditt konto", and the too-short password was refused with "Ogiltigt lösenord. minsta längd är 12."
authentik 2026.8.3 has no Swedish. Its language menu offers 19 languages, including Finnish and Norwegian Bokmål, and our Swedish browser got English. You can rename flows and set your own texts on some stages, but the buttons and messages stay in English.
Admin experience
Keycloak's console is complete and dense: realms, clients, flows, roles, groups and many settings for each. Our guide keeps it off the internet, behind an SSH tunnel, so you open a tunnel before you work. Failed logins are found in the log with journalctl.
authentik's admin interface is cleaner, with a wizard that creates an app and its provider in one go, a dashboard, and an events list with each visitor's address and country. It lives on the same public address as the login, protected by the admin's own login and, with our setup, a one-time code. Flows, stages and policies are powerful but take a while to understand; the setups above, apart from the group binding, each touched three or four objects.
Resources
Keycloak is a Java application and needs most of its memory from the start, about 465 MB here. authentik runs a server and a separate worker for background tasks, which together used about 960 MB. Both used far less than the 8 GB of the VC-P Alloy, and the two together, with Outline, used about 2.4 GB of the server's memory. authentik's image was about three times the size of Keycloak's.
Updates and backups
Keycloak's guide follows the 26.8 tag, so patch releases install by themselves; a new version, such as 26.9, comes every few months and you move by changing the tag after reading the upgrading guide. Each start takes a minute or so.
authentik's guide follows 2026.8 in the same way, and a new version comes about every three months, named after the year and month. You have to upgrade one version at a time and cannot go back.
Both backups are a database dump. Keycloak's guide adds a realm export you can import into another Keycloak; authentik's adds its secret key and its upload folder. We restored both into an empty database, and users, authenticator apps and apps came back; both also came back by themselves after a reboot. Two notes:
- Both guides load the dump right after starting the database, and starting the database starts the rest of the pod too. Keycloak takes long enough to start that the dump was in first. authentik's server started at once and created tables of its own, and the restore failed with "multiple primary keys". Stopping the server and worker before loading the dump fixed it:
systemctl --user stop authentik-server authentik-worker. - authentik's guide has no restore steps, and its backup files, the secret key included, are readable by other users of the server unless you run
umask 077first, as Keycloak's guide does. The home folder itself is closed to others on Debian 13.
Licence and cost
We read the licence texts, the pricing page and the documentation on 14 October 2026.
- Keycloak is open source under the Apache 2.0 licence, a project of the Cloud Native Computing Foundation. Everything is in the free version. Red Hat sells a supported build, Red Hat build of Keycloak, only as part of other subscriptions such as Red Hat Runtimes and OpenShift; it has no price of its own.
- authentik is made by Authentik Security Inc. in the United States. Its code is under the MIT licence, except the
authentik/enterprise/folder, whose licence allows production use only with an Enterprise subscription. Both are in the same image. Enterprise costs 5 US dollars per internal user a month, or 0.02 dollars per external user, billed yearly; Enterprise Plus starts at 20,000 dollars a year. Enterprise adds, among other things, password history, provisioning to Google Workspace and Microsoft Entra ID, certificate login, enhanced audit logging and scheduled offboarding, and support for subscriptions over 1,000 dollars. The free version has no support beyond the community.
For a company running its own staff login, both cost nothing. With Keycloak you will never reach a paid feature; with authentik you might, password history being the one we met.
Okta, Auth0 and Entra ID today
What follows is from Okta's, Auth0's and Microsoft's own pages, not from our tests: we did not sign up for any of them. The pages show prices in dollars.
| Service and plan | Price | Limits for a small company |
|---|---|---|
| Okta Workforce Identity, Starter | $6 per user a month, billed yearly | at least $1,500 a year, the price of about 21 users |
| Okta Workforce Identity, Essentials | $17 per user a month, billed yearly | the same minimum |
| Auth0, Free | $0 | up to 25,000 monthly active users, 1 enterprise connection, no Pro or Enterprise MFA, logs kept 1 day |
| Auth0 B2B, Essentials | from $150 a month for 500 monthly active users | Pro MFA, 3 enterprise connections, logs kept 5 days |
| Microsoft Entra ID Free | included with Microsoft 365 and Azure | two-factor through security defaults, no Conditional Access |
| Microsoft Entra ID P1 | $7 per user a month, paid yearly, annual commitment | Conditional Access; included in Microsoft 365 Business Premium |
| Microsoft Entra ID P2 | $10 per user a month, paid yearly, annual commitment | adds ID Protection, with risk-based sign-in rules |
Sources: Okta's pricing page, Auth0's pricing page, Microsoft Entra pricing and Microsoft Entra licensing, all checked 2026-10-14.
They are not the same kind of service. Okta Workforce Identity and Entra ID are logins for your staff, priced per user, like the setup we tested. Auth0 is mostly for the login to your own product, for your customers, priced per monthly active user; Keycloak and authentik can do that too, but we did not test it.
If your company already works in Microsoft 365, you already have Entra ID Free, and Microsoft 365 Business Premium includes P1, according to Microsoft's licensing page. Keycloak or authentik then makes most sense for the apps outside Microsoft. Moving the Microsoft 365 sign-in itself to them is something we did not test.
What you give up compared with Okta, Auth0 and Entra ID
On your own server, the login costs a fixed server price instead of a price per user, the user list stays in Sweden, and nobody can change your plan for you. But be honest about what you leave behind:
- Uptime and on-call. When the login is down, nobody gets into any app behind it. Okta's trust page showed a 12-month availability of 99.99 %, counted from incidents that hit at least 10 % of its customers (checked 2026-10-14). Our setup is one server: both apps came back by themselves after a reboot, but if the server stops at night, someone of yours has to notice and fix it. Keep a way into your most important apps that does not go through the login.
- Sign-in apps. We tested one-time codes from any authenticator app, in both. The services come with their own: Entra ID's security defaults prompt through Microsoft Authenticator, according to Microsoft's licensing page. Both projects list passkeys, which we did not test.
- Ready-made integrations. Okta lists "more than 8,000 ready-to-use, pre-built integrations" in its integration network (checked 2026-10-14). With Keycloak or authentik you connect each app yourself, as we did with Outline, and each app's quirks, like the
email_verifiedmapping above, are yours to find. Creating users automatically in Google Workspace or Entra ID is in authentik's Enterprise licence. - Compliance reports. Okta's security page lists SOC 2, ISO/IEC 27001:2022, FedRAMP High and more (checked 2026-10-14). Your own login server has no such report: when a customer or an auditor asks, you answer with your own routines for updates, backups, access and logs.
- Support. Keycloak has community help, or Red Hat's build as part of other Red Hat subscriptions. authentik includes support with Enterprise subscriptions over 1,000 dollars a year.
Which one to pick
Keycloak suits a company that wants one login with the security rules auditors ask about, in Swedish, at no cost. Its guide covers the whole setup we tested: two-factor for everyone, password rules with history, a lockout that lifts by itself, a reset that keeps the second factor and Swedish login pages and emails. It used about 480 MB. Its weak points are a dense console, flows that take care to change, no simple way to limit an app to a group, with the reset path to check as well, and a separate oauth2-proxy for apps without single sign-on. Follow the Keycloak guide, on a VC-P Alloy.
authentik suits a team that wants to connect many apps quickly, including tools with no login of their own, and to manage access per app with groups. Its admin interface is the easier one to find your way in, and apps that only speak LDAP or RADIUS can use it too. Its weak points are no Swedish, no built-in lockout or temporary passwords, password history only in Enterprise, a default that Outline rejects until you change the email mapping, twice the memory, and a guide of ours that covers less: plan for the extra steps above. Follow the authentik guide, on a VC-P Alloy.
Both together used under 1.5 GB, so a VC-P Alloy runs either one comfortably next to your other apps.