Zudoku
Supported Providers

OpenID Connect (OIDC)

Zudoku supports any identity provider that implements the OpenID Connect protocol via the generic openid provider type. This includes Okta, Keycloak, Authentik, Ory, ZITADEL, AWS Cognito, Google Identity, and most enterprise IdPs.

Configuration

Add the authentication property to your Zudoku configuration:

TypeScriptCode
{ // ... authentication: { type: "openid", clientId: "<your-client-id>", issuer: "<the-issuer-url>", scopes: ["openid", "profile", "email"], // Optional }, // ... }
OptionRequiredDescription
clientIdYesThe OAuth client ID issued by your provider.
issuerYesThe issuer URL. Zudoku discovers endpoints from <issuer>/.well-known/openid-configuration.
scopesNoScopes to request. Defaults to ["openid", "profile", "email"].

Provider Setup

Register Zudoku as a public SPA / single page application client in your identity provider and set:

  • Callback / Redirect URI to https://your-site.com/oauth/callback
  • For local development, add http://localhost:3000/oauth/callback
  • If your provider supports wildcards, add https://*.your-domain.com/oauth/callback for preview environments
  • Add your site origin to the list of allowed CORS origins
  • Enable the Authorization Code grant with PKCE and the Refresh Token grant

Okta

  1. In the Okta admin console go to ApplicationsApplicationsCreate App Integration.
  2. Select OIDC - OpenID Connect and Single Page Application.
  3. Set Sign-in redirect URIs to https://your-site.com/oauth/callback (add http://localhost:3000/oauth/callback for local development).
  4. Under Assignments, assign the users or groups that should have access.
  5. After creating the app, copy the Client ID. Your issuer is your Okta domain, for example https://your-tenant.okta.com or a custom authorization server like https://your-tenant.okta.com/oauth2/default.
  6. Under SecurityAPITrusted Origins, add your site origin for both CORS and Redirect.
TypeScriptCode
{ authentication: { type: "openid", clientId: "<your-okta-client-id>", issuer: "https://your-tenant.okta.com/oauth2/default", scopes: ["openid", "profile", "email"], }, }

Keycloak

Use the realm issuer URL:

TypeScriptCode
{ authentication: { type: "openid", clientId: "zudoku", issuer: "https://keycloak.example.com/realms/<your-realm>", }, }

In the realm, create a client with Client type OpenID Connect, Access type public, and enable Standard Flow (Authorization Code).

Verifying the Issuer

You can confirm your issuer URL is correct by opening <issuer>/.well-known/openid-configuration in a browser. It should return a JSON document listing authorization_endpoint, token_endpoint, userinfo_endpoint, and jwks_uri.

Customizing Sign-up

By default Register and Sign in both call the OIDC authorize endpoint, so users land on the same login page. Two options change that:

TypeScriptCode
{ authentication: { type: "openid", clientId: "<your-client-id>", issuer: "<the-issuer-url>", // Send Register to a separate URL (absolute → external redirect, relative → in-app navigate) signUp: { url: "/register" }, // Or pass extra params to the authorize URL on sign-up only (e.g. Keycloak) signUp: { authorizationParams: { kc_action: "register" } }, // Hide Register UI entirely. Visual only — still configure your IdP to block sign-ups. disableSignUp: true, }, }

When disableSignUp is true, the Register button on the protected-route login dialog is hidden and /signup shows an "Invitation required" page.

User Profile

After sign-in Zudoku calls the provider's UserInfo endpoint and reads name, email, picture, and email_verified from the response. Map these claims in your provider if they are not emitted by default.

Troubleshooting

  • Discovery fails: verify <issuer>/.well-known/openid-configuration resolves and matches the issuer value in the document.
  • CORS errors on token / userinfo: add your site origin to the provider's allowed origins.
  • Redirect URI mismatch: the URI registered with the provider must match the Zudoku origin exactly, including protocol and port.
  • Missing profile fields: ensure profile and email scopes are granted and that the provider includes name, email, and picture claims in the UserInfo response.
Last modified on