DOCS

Single sign-on.

Bákn speaks OpenID Connect, so any standards-compliant identity provider works — Entra ID, Keycloak, Google Workspace, Okta, Authentik. Your directory decides who has an account.

How the flow runs

The server mediates the exchange rather than the client doing it: the app opens the system browser, the browser talks to your identity provider, and the provider redirects back to the server, which hands the app a Bákn session.

  1. The client opens /api/v1/auth/oidc/start in the system browser.
  2. The server redirects to your provider with PKCE.
  3. The user authenticates there — password, MFA, conditional access, whatever you enforce.
  4. The provider redirects to /api/v1/auth/oidc/callback.
  5. The server links the identity, then reactivates the app at bakn://sso-callback.

The system browser, not an embedded webview — that is RFC 8252, and it is why existing sessions and hardware keys work. It also means Bákn never sees the password.

1. Register the application

Create a confidential client (a "web" or "server-side" app — not SPA, not native) in your provider, and give it this redirect URI:

https://chat.example.com/api/v1/auth/oidc/callback

This is the single most common thing to get wrong. It must be the server's public address, not the client's, and it must match byte for byte — trailing slash included. Providers reject mismatches with a generic error that does not say which part disagreed.

Ask for the scopes openid profile email, and keep the client secret.

2. Configure the server

In .env, or as environment variables on the container:

Bakn__Oidc__Authority=https://login.example.com/realms/main
Bakn__Oidc__ClientId=bakn
Bakn__Oidc__ClientSecret=<secret>
Bakn__Oidc__ProviderDisplayName=Example SSO
Bakn__Oidc__PublicBaseUrl=https://chat.example.com

Authority is the issuer; discovery is resolved from it, so you do not configure endpoints individually. SSO turns on as soon as Authority and ClientId are both present — restart the server and the client's sign-in screen grows a Sign in with Example SSO button.

Set PublicBaseUrl. Without it the server builds the redirect URI from the incoming request's host, which is correct only when it is directly exposed — behind a reverse proxy it produces an internal address, and the provider rejects a redirect URI that does not match what you registered.

3. Close password registration

SSO does not replace self-registration on its own — it sits beside it. If the directory is meant to be the only way in, say so:

BAKN_ALLOW_REGISTRATION=false

SSO still creates accounts on first sign-in; only password registration closes. Existing password accounts keep working, so this is safe to turn on for a server already in use.

4. Optional: let the directory grant admin

Point Bákn at a claim and a value, and the provider becomes authoritative for the admin role on every sign-in:

Bakn__Oidc__AdminRoleClaim=groups
Bakn__Oidc__AdminRoleValue=bakn-admins

Authoritative means both directions: a user who loses the group loses admin at their next sign-in, and roles set inside Bákn are overwritten. Leave these unset to manage roles in the app instead — you cannot meaningfully do both.

Provider specifics

Microsoft Entra ID

Authority is https://login.microsoftonline.com/<tenant-id>/v2.0. Register under App registrations with a Web platform. Group claims are not emitted by default — enable them under Token configuration, and note they arrive as object ids, so AdminRoleValue is a GUID unless you configure group names. App roles are usually the tidier choice: AdminRoleClaim=roles.

Keycloak

Authority is https://keycloak.example.com/realms/<realm>. Create a client with Client authentication on and the standard flow enabled. For roles, add a mapper of type User Realm Role with token claim name roles.

Google Workspace

Authority is https://accounts.google.com. Create an OAuth client of type Web application in Google Cloud console. Google does not emit group membership in the ID token, so leave the admin-role settings unset and manage roles in Bákn.

Authentik / Okta / others

Anything with OIDC discovery works. Point Authority at the issuer — the value of iss in its tokens, which is not always the same as the URL you log in at — and the rest follows.

When it does not work

SymptomUsually
No SSO button in the client Authority or ClientId is missing, or the server was not restarted. Check GET /api/v1/auth/config — it reports what the client sees.
Provider says the redirect URI is invalid What you registered differs from what the server sent. Set PublicBaseUrl and compare character by character, including the scheme and any trailing slash.
Browser completes, app never returns The bakn:// scheme is not registered — a desktop build run from a folder rather than installed, or an Android build that skipped the callback activity.
Signs in, but as a brand-new empty account The provider's sub changed, or the user previously registered with a password under a different identity. Identities link on (issuer, subject), not on email.
Admin role not applied The claim is absent from the ID token. Most providers omit group/role claims until you explicitly add a mapper.

GET /api/v1/auth/config is anonymous and safe to curl from anywhere — it reports whether SSO is enabled and what the button will say, which separates "the server is not configured" from "the client is not asking".

Burn the dead zones.

Free on every platform. Your first message sends in under a minute — and keeps sending when nothing else does.

An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.