Single sign-on with Entra ID, Okta, or Google
For an internal ERP or line-of-business app, identity usually already lives in a corporate directory — Microsoft Entra ID, Okta, or Google Workspace — with central accounts, groups, MFA, and conditional access. You want Kozou to use that, not a separate consumer login.
It does. Kozou delegates identity: you point it at your existing OpenID Connect (OIDC) provider, and Kozou verifies the tokens that provider issues. The model is the same one used for any provider; for enterprise you simply aim it at your corporate directory.
This guide covers Entra ID first, with the Okta and Google equivalents noted alongside. For the command reference behind it, see kozou dev; for the conceptual picture, see Authentication and authorization.
How it fits
Section titled “How it fits”Three parties, each with one job:
- Your identity provider signs the user in (password, MFA, conditional access) and issues a signed OIDC JWT that names who they are and what role they hold.
- Kozou verifies that token against the provider’s published keys, then runs the request inside a transaction under
SET LOCAL ROLE <role-from-claim>. - PostgreSQL RLS — your own row-level-security policies — decides what that role can read and write.
Kozou is the resource server and enforcement layer: it verifies the token and switches role, but it does not sign users in and it never writes the policies. That keeps identity in the system built to guard it, and access control in the database where it applies to every client.
Before you start
Section titled “Before you start”- An OIDC identity provider with an app registration — Entra ID, Okta, or Google Workspace.
- PostgreSQL roles and RLS policies already defined for the roles your app needs (for example
app_admin,app_editor,app_author,app_viewer). Kozou switches into these roles; your policies enforce. The login role indatabase.urlmust beGRANTed membership in each. - A way to deliver the token to requests. Kozou verifies a bearer token but does not run the browser sign-in itself — see Sign-in flow below.
Point Kozou at your identity provider
Section titled “Point Kozou at your identity provider”Add an auth block to kozou.config.yaml. Kozou fetches the provider’s keys from its JWKS endpoint (selected by kid, cached, and refreshed on rotation) and checks the issuer and audience. For Entra ID:
auth: jwt: jwksUri: https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys issuer: https://login.microsoftonline.com/<tenant-id>/v2.0 audience: <application-client-id> # the API app's client ID / App ID URI algorithms: [RS256] roleClaim: role allowedRoles: [app_admin, app_editor, app_author, app_viewer] defaultRole: app_viewerThe endpoints differ by provider, but the shape is identical:
| Provider | jwksUri | issuer |
|---|---|---|
| Microsoft Entra ID | https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys | https://login.microsoftonline.com/<tenant-id>/v2.0 |
| Okta | https://<org>.okta.com/oauth2/<server-id>/v1/keys | https://<org>.okta.com/oauth2/<server-id> |
| Google Workspace | https://www.googleapis.com/oauth2/v3/certs | https://accounts.google.com |
Use the provider’s v2.0 / OIDC endpoints (for Entra ID, the v2.0 issuer above, not the legacy v1.0 one). Secrets are not involved on Kozou’s side — verification is public-key only.
Map identities to PostgreSQL roles
Section titled “Map identities to PostgreSQL roles”This is the one step that needs care. Kozou reads a single claim that names the PostgreSQL role to assume — roleClaim (default role) — and runs the request under it. Corporate directories, though, describe membership differently:
- Entra ID emits app roles as a
rolesarray and group membership asgroups(an array of GUIDs). - Okta / Google can emit groups or custom claims, also typically as arrays.
So make the provider emit a single scalar claim whose value is the PostgreSQL role name. In Entra ID, define App Roles on the app registration (for example app_editor) and assign users or groups to them, then surface the chosen role as a scalar claim — through an app-role-to-claim or optional-/mapped-claim configuration — named to match roleClaim. Then:
roleClaim: role # the scalar claim naming the DB role allowedRoles: [app_admin, app_editor, app_author, app_viewer] defaultRole: app_viewer # role when the token omits the claim # anonRole: web_anon # role for requests with NO token (else 401)A token whose role is not in allowedRoles gets 403. A request with no token gets 401 unless you set anonRole, in which case it runs under that anonymous role with empty claims and your RLS decides what it sees.
Today Kozou expects that scalar role claim; consuming a roles array or mapping groups to a role directly is a possible future enhancement. Until then, the App-Role-to-scalar-claim mapping above is the path.
Sign-in flow: front Kozou with a proxy
Section titled “Sign-in flow: front Kozou with a proxy”Kozou verifies tokens; it does not run the OIDC authorization-code sign-in or hold a browser session. In an enterprise deployment, that flow belongs to a layer in front of Kozou:
- an OIDC-aware reverse proxy (for example oauth2-proxy, or Microsoft Entra Application Proxy) that authenticates the user against Entra ID and forwards the resulting bearer token to Kozou’s API, or
- your own application shell that performs the sign-in and calls the API with the token.
The bundled reference Admin UI (kozou dev) is built for the trusted-token model: under an external identity provider it sends a ready-made token supplied via auth.ui.token (or the KOZOU_ADAPTER_TOKEN environment variable), rather than performing an interactive login of its own. For a full interactive corporate sign-in, put one of the layers above in front.
Provider notes
Section titled “Provider notes”- Microsoft Entra ID, Okta, and Google Workspace are OIDC providers with JWKS endpoints and work directly through the
auth.jwtconfiguration above. - GitHub is not a general-purpose OIDC login provider (its OAuth apps issue opaque tokens, not verifiable OIDC JWTs for arbitrary audiences). To offer “Sign in with GitHub”, bridge it through an IdP that supports GitHub as a social connector — Microsoft Entra External ID, Auth0, or Keycloak — and point Kozou at that IdP’s JWKS.
Where to next
Section titled “Where to next”- Authentication and authorization — what Kozou enforces and what it delegates.
- The REST API guide — the
SET LOCAL ROLE+ RLS flow after a token is verified. kozou.config.yaml— the configuration file theauthblock lives in.