How to Use Kanidm: The Beginner's Guide (First Deploy, the Admin-Recovery Lesson, Your First User, and the Passkey Arc)

CodexFuse Team · 2026-11-01T14:03:33.795Z · 17 min read

Learn how to use Kanidm: deploy the Rust identity server with Docker, recover the admin, create users and groups, set up passkeys, and wire OIDC to Proxmox.

How to Use Kanidm: The Beginner's Guide (First Deploy, the Admin-Recovery Lesson, Your First User, and the Passkey Arc)

Learning how to use Kanidm is the moment your homelab or small team gets a single, serious identity source instead of a spreadsheet of passwords: one place that knows your people, their groups, and every app they are allowed to touch. Kanidm is an open-source identity management platform written in Rust, built secure-by-default, that runs your user directory, LDAP, RADIUS, and OAuth2/OIDC logins from one binary. There is no admin web UI to click through — the kanidm command line is the entire administration path, and that is a deliberate design choice, not a missing feature.

The current release line is 1.11.2, released September 2026, under the Mozilla Public License 2.0. This kanidm tutorial runs the complete beginner arc: a Docker deploy with TLS you cannot skip, the admin-recovery lesson every newcomer needs, your first person and group, the passkey credential flow, your first OAuth2 client, and a real Proxmox OIDC integration — then the honest moment where you decide whether Kanidm, Authentik, or Keycloak is the right fit for you. If the Docker commands feel new, read the Docker beginner guide first; this guide starts where that one ends.

How do you use Kanidm?

You use Kanidm by running the kanidm/server container with a TLS certificate and a domain name, recovering the break-glass admin account, installing the kanidm CLI, creating people and groups, issuing credential reset tokens so users enroll their own passkeys, and registering each app as an OAuth2 client. The whole beginner path is seven steps:

  1. Choose a domain name you will keep forever, and get a TLS certificate for it — Kanidm refuses to start without TLS.
  2. Write server.toml (domain, origin, bind address, TLS paths, database path) and start kanidm/server with a persistent /data volume.
  3. Install the kanidm CLI (distro package, cargo, or the kanidm/tools image) and point its profile at your server.
  4. Recover the admin and idm_admin break-glass accounts with kanidmd recover-account, then store those credentials offline.
  5. Create your first person and group, and add the person to the group.
  6. Issue a credential reset token so your first user enrolls a passkey (or password plus TOTP).
  7. Register your first OAuth2 client with kanidm system oauth2 create, set its redirect URL and scope map, and wire one real app to it.

What is Kanidm, exactly?

Kanidm is one Rust binary that holds your people, their groups, service accounts, OAuth2 clients, RADIUS credentials, and an LDAP gateway in a single database — say that sentence once and the rest of the guide falls into place. It is not a general single-sign-on platform with a marketing landing page builder; it is an identity manager in the old, serious sense: the system of record for who everyone is, with secure authentication flows (passkeys first, password plus TOTP second) built on WebAuthn.

Three things make it unlike the alternatives you will meet below. First, administrative functionality is primarily CLI-driven — a user-facing WebUI exists for logging in and self-service, but there is deliberately no admin web console. Second, the server will not run without TLS, because its stepped-challenge authentication relies on Secure-flag cookies that browsers only return over HTTPS. Third, the domain name you pick is load-bearing: WebAuthn credentials are bound to it, and changing it later is painful on purpose, so the project forces you to choose it carefully up front.

Is Kanidm right for you — or should you pick Authentik or Keycloak?

Kanidm is right for you if you want one self-hosted identity source, you are comfortable living in a terminal, and you want passkeys and secure defaults without configuring them. The honest beginner answer to "which identity server" is about the shape of the tool, not a ranking. Read the Authentik beginner guide if you want a click-through admin web interface: Authentik is Python-based, ships a full admin UI, and even proxies SSO onto apps that never learned it. Pick Keycloak if you live in the Java enterprise world and want the oldest, most battle-tested admin console. Pick Kanidm if you want the Rust option: CLI-first administration, passkeys as the default credential, and LDAP plus RADIUS plus OAuth2 from one deploy.

There is also a tool this guide deliberately does not rival. Logto is an Auth0-style developer auth platform for apps you build; Kanidm is the identity server for the people and devices in your own organization. Pomerium, meanwhile, is an identity-aware proxy that consumes an identity provider — and Kanidm can be that provider. They are neighbors, not competitors.

What do you need before you start?

You need four things, and the order matters. First, a server you control: a small VPS is the normal home for Kanidm, and if you have never rented one, the what is VPS hosting guide explains the shape of the thing. Second, Docker on that server. Third, a real domain name pointed at the server — not an IP address, not localhost — because WebAuthn credentials bind to the origin. Fourth, a TLS certificate for that domain, which a reverse proxy like Caddy can fetch for you automatically; Kanidm itself just needs the chain and key files to exist.

Pick the domain once, with care. Changing the domain name later means reconfiguring every LDAP and OAuth client and breaks every registered WebAuthn credential for every user, because those credentials are bound to the origin — the project's own domain-name guide says this plainly. The escape hatch is kanidmd domain rename, but the intended behavior is that you get it right the first time.

How do you install Kanidm with Docker?

A kanidm install is a kanidm docker deploy: you write a server.toml config file, mount it with your TLS files and a persistent data directory into the kanidm/server container, and publish port 8443. The current server.toml schema is versioned — here is a minimal v2 file for a Docker deploy, verified against the current docs:

version = "2"
bindaddress = "[::]:8443"
db_path = "/data/kanidm.db"
domain = "idm.example.com"
origin = "https://idm.example.com:8443"
tls_chain = "/data/cert.pem"
tls_key = "/data/key.pem"
ldapbindaddress = "127.0.0.1:3636"

The three values a beginner most often gets wrong: origin must exactly match what users will type in their browsers (scheme, host, and port), domain is the identity domain and cannot change later, and the TLS chain and key must be real, valid files — Kanidm does not generate them for you. Start the server with the data directory persisted:

docker run -d --name kanidmd -v kanidm_data:/data -p 8443:8443 docker.io/kanidm/server:1.5.0 /sbin/kanidmd server -c /data/server.toml

Pin a version tag rather than floating on latest: the guides that are known-good reference explicit tags such as kanidm/server:1.5.0, and the project publishes version-tagged releases. Then install the CLI on your workstation — the kanidm command is the only admin path, so installing it is installing your control panel. Verified options: openSUSE ships kanidm-unixd-clients via zypper, Fedora via dnf from the openSUSE network:idm repos, FreeBSD via pkg install kanidm-client, anywhere via cargo install kanidm_tools, or pull the statically linked binary straight out of the kanidm/tools image. Configure its profile in ~/.config/kanidm with your server's URI and CA, and confirm with kanidm login --name idm_admin once you have recovered that account — which is the next section.

Say the TLS lesson once, loudly: TLS for all connections is mandatory. It is not an optional feature you add later, and the server will not start without a certificate configured. The stepped-challenge authentication design uses Secure-flag cookies that clients only return over HTTPS, and WebAuthn plus the QR-code credential flows only work over TLS. If you are tempted to run it plaintext "just for testing," the answer is no — get a real certificate first.

How do you recover the Kanidm admin account?

You recover the admin account with kanidmd recover-account, and this is the lesson every beginner guide must teach before anything else: Kanidm ships two break-glass accounts, admin and idm_admin, which exist with no password by default and cannot be accessed at all until you recover them. Run this on the host running kanidmd:

docker exec -i -t kanidmd kanidmd recover-account admin
docker exec -i -t kanidmd kanidmd recover-account idm_admin

Each command prints an auto-generated password to stdout. The two accounts are not interchangeable:

adminidm_admin
ScopeWhole-system configuration (domains, server settings)People, groups, credentials, service accounts
Daily useAlmost never — initial setup and disaster recovery onlyDaily administration, always via --name idm_admin
First taskRecover it, store the password offline, forget it existsRecover it, delegate real privileges to named user accounts

The recover-account lesson is really a delegation lesson: break-glass accounts are for initial setup and disaster recovery, never for daily use. The moment the server is up, create named administrator users, give them the privileges they need, and put the break-glass passwords somewhere offline.

How do you create your first user and group?

You create people and groups with the kanidm CLI, authenticating every command as idm_admin through the --name flag. The commands are exactly what they look like:

kanidm person create alice "Alice Example" --name idm_admin
kanidm group create staff --name idm_admin
kanidm group add-members staff alice --name idm_admin

The --name idm_admin on each line is not decoration: it is the admin identity the command runs as, matching the account profile you configured in ~/.config/kanidm with the server URI and your CA. A person's login name is the first argument (alice), and the display name follows in quotes. Groups are the unit of access control everywhere in Kanidm — OAuth2 scope maps, RADIUS access, PAM login rights all hang off group membership, so building a sensible group structure early is the habit that pays off for months.

How do credentials work in Kanidm?

Credentials in Kanidm are per-device and per-purpose, not one password per person — and the credential-reset-token flow is how a new user gets theirs. As an admin you never set someone's password directly; you issue them a token, they open the link, and they enroll their own credentials:

kanidm person credential create-reset-token alice --name idm_admin

The command generates a QR code and a URL. The user opens it in a browser and chooses: register a passkey (a YubiKey, a phone, Face ID — the modern path) or set a password. Say the passkey-first line once: Kanidm treats passkeys as the primary credential and everything else as the fallback, because passkeys cannot be phished and need no shared secret on the server. If the user picks a password, Kanidm requires them to also set up TOTP — traditional passwords without a second factor are not an option, full stop.

The project's account-policy page ranks credential strength on a ladder you should know:

Policy levelWhat it requiresWhen to use it
anyAnything the user enrolledNever for real users — the weak default
mfaMulti-factor (password plus TOTP counts)Minimum sane setting for a homelab
passkeyA WebAuthn passkeyThe Kanidm default recommendation
attested_passkeyPasskey from a trusted hardware authenticatorRegulated teams, via the fido-mds-tool allowlist

The token redemption command — kanidm person credential use-reset-token — exists for automation and scripting, but humans should use the QR link: it is the flow the project designed and tested.

How do you create your first OAuth2 client?

You create an OAuth2 client with kanidm system oauth2 create, and this is the moment Kanidm stops being a user directory and starts being the login button for your apps. The command takes a name, a display name, and the app's origin:

kanidm system oauth2 create gitea Gitea https://gitea.example.com --name idm_admin
kanidm system oauth2 add-redirect-url gitea https://gitea.example.com/user/oauth2/kanidm/callback --name idm_admin
kanidm system oauth2 update-scope-map gitea staff email openid profile groups --name idm_admin

The three commands do three different jobs: create registers the client (use create-public for PKCE clients with no secret), add-redirect-url whitelists exactly where tokens may be sent — redirect URIs are matched exactly, so copy them from the app's docs letter by letter — and update-scope-map decides which Kanidm groups receive which claims, which is how "only the staff group can log in to this app" is expressed. (Note: the docs use update-scope-map — a create-or-update verb — there is no create-scope-map command despite what some older write-ups say.)

Most apps only need the discovery URL: https://<your-domain>/oauth2/openid/<client-id>/.well-known/openid-configuration. And here is where the proxy lane connects: an identity-aware proxy like Pomerium consumes an identity provider, and Kanidm can be that provider — the Pomerium beginner guide walks the proxy side, while this guide covers the Kanidm side that feeds it.

How do you connect Proxmox to Kanidm with OIDC?

You connect Proxmox by registering it as an OAuth2 client in Kanidm and adding an OpenID Connect realm in Proxmox's Datacenter Permissions panel — the kanidm proxmox integration needs no plugin on either side — and the gyptazy guide's full-setup arc is still the reference walkthrough. On the Kanidm side, create the client with Proxmox's origin:

kanidm system oauth2 create proxmox "Proxmox Lab" https://proxmox.example.com:8006 --name idm_admin
kanidm system oauth2 add-redirect-url proxmox https://proxmox.example.com:8006 --name idm_admin
kanidm system oauth2 update-scope-map proxmox pve-users email openid profile groups --name idm_admin

Then in Proxmox, go to Datacenter, Permissions, Realms, and add an OpenID Connect realm with these fields: the Issuer URL is https://<kanidm-domain>/oauth2/openid/proxmox, the Client ID is the Kanidm client id, the Client Key is the client secret, the Realm is your Kanidm domain, and Autocreate Users is yes. The lesson beginners trip on: the client id in the Issuer URL path must match the actual client id you created in Kanidm — the gyptazy guide created the client named Proxmox but used lowercase proxmox in the issuer, which only works if the client id is actually the lowercase one. Keep the name, the id, and the issuer path identical and the whole flow just works.

What about LDAP and RADIUS in Kanidm?

LDAP is Kanidm's read-only gateway for legacy apps, and it lives on the port you already saw in server.toml: enable ldapbindaddress (port 3636, LDAP over TLS) and old software can bind against your Kanidm directory with a base DN derived from your domain, like dc=idm,dc=example,dc=com. Two rules matter: LDAP binds use the POSIX password and get anonymous-level permissions — least privilege by design — while service accounts can bind with API tokens for elevated reads.

RADIUS is the Wi-Fi and VPN lane, and it runs as a separate kanidm/radius container with its config mounted at /data/radius.toml. The pattern is: create a service account, add it to idm_radius_servers, generate an API token for it, and define radius_required_groups plus group-to-VLAN mappings in the radius config. Each account holds exactly one RADIUS password credential — a deliberate limitation, because the protocol can only attest a single password — and accounts generate it themselves. The kanidm webauthn story and the kanidm ldap story are the same philosophy: modern credentials for people, least-privilege bridges for everything legacy.

Kanidm vs Authentik vs Keycloak: the honest draw-the-line

Three comparisons close the loop on the decision you started in section four. The kanidm vs keycloak question, like the Authentik one, is really a question about your operating model — none of these is "the winner," each is the right default for a different kind of operator:

KanidmAuthentikKeycloak
LanguageRustPython (Django) plus React frontendJava (Quarkus)
Admin experienceCLI-first — no admin web UI by designFull web admin interface on first visitFull admin console, the enterprise standard
Credential philosophyPasskeys first, password-plus-TOTP secondFlows and stages you compose yourselfAuthentication flows with broad enterprise options
Protocols in one deployOAuth2/OIDC, LDAP, RADIUS, PAM, SSH keysOIDC, SAML, LDAP, RADIUS, plus a proxy provider for apps with no SSOOIDC, SAML, LDAP as the usual trio
Best forTerminal-comfortable homelabs and teams that want secure defaultsHomelabs wanting a click-through SSO admin panelTeams that already live in the Java enterprise world

Say the graduation line once: if your team needs a web admin console, delegated helpdesk administration, or enterprise SSO brokers out of the box, start with Authentik or Keycloak instead of bending Kanidm into a shape it refuses to be. Kanidm's refusal is the feature — every default you skipped configuring was a default the Rust binary already chose correctly.

Seven beginner mistakes to avoid

MistakeWhat actually happens
Choosing a throwaway domain for testingWebAuthn credentials bind to the origin — you cannot move later without breaking every passkey.
Starting the server without TLS "just to test"Kanidmd will not start. TLS is mandatory, not optional — this is documented, not a bug.
Using the break-glass admin dailyYou are one leaked terminal history away from a full-compromise account — delegate to named users.
Setting passwords for users by handThat is not the flow — issue a reset token and let users enroll passkeys themselves.
Typing redirect URLs from memoryExact-match redirect URIs reject anything you misremember — copy from the app's docs.
Creating the OAuth2 client with one name and the issuer URL with anotherProxmox-style integrations fail silently — keep name, id, and issuer path identical.
Treating Kanidm like AuthentikThere is no admin web UI and never will be — if you need one, that is the signal to pick Authentik.

Sources

  • Kanidm frequently asked questions (TLS mandatory, secure cookies, WebAuthn over HTTPS) — https://kanidm.github.io/kanidm/master/frequently_asked_questions.html
  • Kanidm: choosing a domain name (domain rename breaks WebAuthn credentials, kanidmd domain rename escape hatch) — https://kanidm.github.io/kanidm/master/choosing_a_domain_name.html
  • Kanidm accounts introduction (break-glass admin/idm_admin, recover-account, delegation guidance) — https://kanidm.github.io/kanidm/master/accounts/intro.html
  • Kanidm account policy (credential-strength ladder: any, mfa, passkey, attested_passkey; fido-mds-tool allowlist) — https://kanidm.github.io/kanidm/stable/accounts/account_policy.html
  • Kanidm OAuth2 integration docs (oauth2 create/create-public, add-redirect-url, update-scope-map, discovery URL) — https://kanidm.github.io/kanidm/master/integrations/oauth2/examples.html
  • Kanidm CLI OAuth2 options reference (create-public enum) — https://docs.rs/kanidm_tools/latest/kanidm_cli/enum.Oauth2Opt.html
  • Kanidm LDAP integration (ldapbindaddress, POSIX binds anonymous-level, service-account API tokens) — https://kanidm.github.io/kanidm/master/integrations/ldap.html
  • Kanidm RADIUS integration (kanidm/radius container, radius.toml, required groups, VLAN mapping) — https://kanidm.github.io/kanidm/stable/integrations/radius.html
  • Kanidm PAM and NSS integration (CLI install: zypper, dnf, pkg, cargo kanidm_tools) — https://kanidm.github.io/kanidm/master/integrations/pam_and_nsswitch
  • kanidm_tools on crates.io (release 1.11.2, September 2026; MPL-2.0) — https://lib.rs/crates/kanidm_tools
  • Muetsch: OpenID Connect login for Wakapi with Kanidm (Docker arc, kanidm/server + kanidm/tools images, TLS) — https://www.muetsch.io/openid-connect-login-for-wakapi-with-kanidm.html
  • Gyptazy: Kanidm with Proxmox and OIDC (Debian Docker arc, server.toml schema, Proxmox realm fields, domain rename warning) — https://gyptazy.com/blog/kanidm-with-proxmox-and-oidc-the-full-setup/
  • William Lam: vCenter Server identity federation with Kanidm (server.toml, recover-account, person/group commands, credential reset token, TOTP requirement) — https://williamlam.com/2025/04/vcenter-server-identity-federation-with-kanidm.html
  • Kammel: k8s home lab 2025, part 6 (kanidmd recover-account admin/idm_admin, OAuth2 client arc) — https://blog.kammel.dev/post/k8s_home_lab_2025_06/
  • Alec Divito: Kanidm, an open-source identity management platform (CLI-first administration, user-facing WebUI) — https://alecdivito.com/kanidm-an-open-source-identity-management-platform/
  • Authentik vs Keycloak comparison (Authentik Python/Django with web admin interface) — https://dev.to/selfhostingsh/authentik-vs-keycloak-which-identity-provider-1b99
  • Tech-Insider: Keycloak vs Ory vs Zitadel 2026 (Keycloak Java/Quarkus, CNCF incubating, enterprise deployments) — https://tech-insider.org/keycloak-vs-ory-vs-zitadel-2026/
  • Elest: Authentik quickstart (web admin interface on first visit) — https://elest.io/open-source/authentik/resources/quickstart

Frequently Asked Questions

Is Kanidm free to use?

Yes — Kanidm is open source under the Mozilla Public License 2.0, and there is no paid tier or hosted edition to graduate into. You run it on your own hardware or VPS; the only costs are the server and the domain name.

Does Kanidm have a web admin panel?

No. Administrative functionality is primarily CLI-driven: the kanidm command line is the admin interface, and there is deliberately no admin web UI. A user-facing WebUI exists for logging in and self-service, but server administration happens in the terminal.

Can Kanidm replace Active Directory?

Partially. Kanidm provides the identity-management core — users, groups, credentials, LDAP, RADIUS, and OAuth2 — but it is not a Windows domain controller: there is no Group Policy or SMB/NTLM stack. For Linux-first homelabs and small teams, plus apps that speak LDAP or OIDC, it covers the need.

Why does Kanidm force TLS even for local testing?

Because its authentication design depends on Secure-flag cookies that browsers only return over HTTPS, and WebAuthn plus the QR-code credential flows only work over TLS. The server refuses to start without a certificate configured — the project documents this as intentional, not a bug.

When should I choose Authentik or Keycloak over Kanidm?

Choose Authentik when you want a click-through web admin interface, or Keycloak when your organization already runs on Java enterprise infrastructure. Choose Kanidm when you are comfortable in a terminal and want Rust-built, passkey-first identity management with secure defaults you never have to configure.

Kanidm is not another tool on a shelf — it is the system of record for who your people are. Deploy it once, recover the admin, delegate to named users, and let passkeys do the rest.

Featured on Twelve Tools Launch Llama Tools Launch your MCP