Skip to content

Single sign on

Pierre edited this page Oct 29, 2026 · 1 revision

Zukan implements standard OpenID Connect discovery, authorization code flow, PKCE S256 and asymmetric ID-token validation. Local accounts and SSO can coexist.

Provider-neutral configuration

For a provider named home:

TCG_PUBLIC_URL=https://cards.example.com
TCG_OIDC_PROVIDERS=["home"]
TCG_OIDC_HOME_DISPLAY_NAME=Home SSO
TCG_OIDC_HOME_ISSUER=https://identity.example.com/EXACT_ISSUER_PATH
TCG_OIDC_HOME_CLIENT_ID=zukan-web
TCG_OIDC_HOME_CLIENT_SECRET=REPLACE_WITH_PROVIDER_CLIENT_SECRET
TCG_OIDC_HOME_MOBILE_CLIENT_ID=zukan-android
TCG_OIDC_HOME_SCOPES=["openid","profile","email"]
TCG_OIDC_HOME_ACCOUNT_URL=https://identity.example.com/ACCOUNT_PAGE

The issuer and account page above are placeholders, not universal provider paths. Copy the issuer from the provider's discovery configuration. Lists must be JSON. Provider names use lowercase letters/digits, hyphens or underscores, begin with a letter/digit and are at most 64 characters. Their environment prefix is uppercase with hyphens replaced by underscores.

Recreate api after editing .env; recreate worker too when changing shared settings.

Two clients

Client Type Redirect URI
Web Confidential; authorization code + PKCE S256 https://cards.example.com/api/auth/oidc/home/callback
Android production Public; authorization code + PKCE S256 fr.zukan.app:/oauth2redirect
Android debug Public; same flow, additional allowed redirect fr.zukan.app.dev:/oauth2redirect

The mobile client ID must be supplied in Zukan configuration. Web and mobile must use the same issuer; matching email addresses do not merge accounts.

Account creation and authorization

By default, an accepted SSO login creates an account when no matching issuer/subject exists. Set AUTO_CREATE_USERS=false to permit only previously established SSO accounts for that provider.

ALLOWED_GROUPS restricts sign-in to members of the configured groups; empty means no additional group restriction. ADMIN_GROUPS maps group membership to administrator role on each login; other accepted users become normal users. Empty admin groups leaves roles managed in Zukan. Claim names default to preferred_username and groups.

Zukan never links a local account to SSO solely because the email is identical. Changing the issuer can therefore produce a different account with an empty collection. Preserve issuer and subject identity during provider migration or plan a separate data migration.

Keycloak

Use an issuer such as https://identity.example.com/realms/home. Create a confidential web client and a public mobile client with the redirect URIs above and PKCE S256. Configure a Group Membership mapper with token claim groups, normally without full group paths, if group authorization is used. Ensure the strings in Zukan match the actual claim values.

The account URL is guessed as <issuer>/account, or can be explicitly overridden.

Authentik

Create web and mobile OAuth2/OpenID providers/applications. Use a signing certificate/key that produces an asymmetric algorithm; without a suitable key, HS256 tokens are refused by Zukan. The repository recommends a shared issuer mode so both clients identify the same issuer. Copy the exact OpenID Configuration Issuer value and verify the mobile discovery document agrees.

Configure strict redirect URIs. Group information is supplied through the configured scopes/claims. An issuer containing /application/o/ allows the default account-page guess /if/user/#/settings; use TCG_OIDC_HOME_ACCOUNT_URL to link a custom profile-management flow or another account portal.

Custom password/email editing flows are owned by Authentik. Zukan only opens the configured URL. The application's generic documentation does not require any particular custom Authentik flow.

Authelia and other providers

Authelia commonly needs groups added to requested scopes and an explicit account URL such as the provider's settings page. Zukan can obtain missing profile/groups data from userinfo when an access token is supplied. For other providers, verify discovery, issuer, JWKS, supported scopes and redirect handling rather than assuming identical administration labels.

ID tokens signed with RS*, PS*, ES* or EdDSA are allowed by the reviewed validator. Symmetric HS* tokens are rejected.

Disable local login only after testing

  1. Confirm a web SSO user can sign in.
  2. Confirm at least one SSO user has administrator role.
  3. Confirm Android if mobile access is needed.
  4. Set TCG_LOCAL_LOGIN_ENABLED=false and recreate the API.

With one provider, web login normally redirects immediately to it. With local login disabled, administrators cannot create local users through the Users page.

For recovery, enable local login again, recreate the API and run docker compose exec api zukan create-admin recovery-admin. This creates or resets a local administrator through an interactive password prompt.

See Troubleshooting for issuer, signature and redirect failures.

Implementation references

Clone this wiki locally