- In Sign in with Cativa, Cativa is the IdP: a third-party app authenticates the user with the community account.
- Here, the company is the IdP: members sign into the Cativa community using the login system the company already has. Cativa acts as the Relying Party and federates to the client’s IdP.
cativa-sso repo ships a runnable mock OIDC IdP in the cliente-idp folder (Node + Express): discovery, RS256 JWKS, authorize/token/userinfo. Run it behind a public tunnel and register it as a provider to exercise the flow end to end.Scenario
The Makers community belongs to Acme, a company that runs Google Workspace for everyone. You don’t want employees to create yet another password: they click “Sign in with your Acme account”, go through the Google login they already use, and land inside the community already authenticated. On first access, Cativa creates the account automatically from the Google data (name, email, avatar). Cativa is the Relying Party: it delegates authentication to the company IdP, validates theid_token that comes back, and links (or provisions) the user in the community.
How it works
Cativa verifies theid_token signature (via the provider’s JWKS), checks the audience (your client_id) and requires the email claim. On first login, if auto-provisioning is on, the user is created in the community from the IdP data.
Prerequisites
-
An OAuth/OIDC app in your IdP — create a client in the company provider and note its
client_id(YOUR_CLIENT_ID) andclient_secret(YOUR_SECRET). -
Cativa’s callback URL, registered in your IdP as an allowed redirect URI. You don’t have to build it by hand: when you open the Identity Provider form in the Cativa admin (next section), it shows the exact callback URL with your slug already filled in, plus a Copy button. Paste that value into your IdP client. The shape is:
{customerName}is your community’s slug — the public Cativa subdomain (https://{customerName}.cativa.digital). It’s fixed per tenant, and the admin who sets this up already knows it (it’s their own community). If in doubt, copy the URL the form shows rather than typing the slug yourself. - Admin access to the Cativa community to register the provider.
Step 1 — Register the Identity Provider
In the community admin, under Integrations → SSO → Providers → New provider, pick your IdP preset (Google, Microsoft, Okta, Auth0, Keycloak) or Custom (OIDC) and fill in:Discovery
.well-known/openid-configuration) and click Discover endpoints — Cativa fills authorize/token/userinfo/jwks for you. (For providers without discovery, enter the endpoints manually.)Credentials
Client ID and Client Secret of the client you created in the IdP, and the Scopes (at minimum openid email profile).Provisioning
Slug
company) — it goes in the federated login start URL.Step 2 — Trigger the login at runtime
Once registered, federated login is a chain of redirects that Cativa orchestrates. All you have to do is point a button at the start URL; everything else happens server-side.Point the login button at the start URL
302 to the company IdP’s /authorize.The user authenticates on the company IdP
The IdP returns to Cativa's callback
state against the cookie, exchanges the code for an id_token at the IdP’s /token, and verifies the signature via the provider’s jwks.Cativa links or provisions and redirects already signed in
id_token validated, Cativa extracts the email, looks for an existing community user, and:- If it exists: links the external identity and opens the session.
- If it doesn’t and auto-provision is on: creates the user from the claims (
email,given_name,family_name,picture) with the default Role.
302 to the community frontend with the user already authenticated. No code on your side runs in this step.What the IdP must return
- A signed
id_token, verifiable against the provider’sjwks(Cativa fetches the public key from discovery/JWKS). - The
emailclaim is required — it’s the identity key. Without it, login is rejected. given_name/family_name/pictureare used (when present) when auto-provisioning the user.
id_token Cativa expects from your IdP looks like this (illustrative):
Test with the mock IdP
Before wiring your production Google Workspace or Okta, you can exercise the whole flow with the mock IdP in thecativa-sso repo:
Run the mock IdP behind a tunnel
cliente-idp folder (Node + Express), start the server and expose it with a public tunnel (e.g. ngrok http 3000). Note the public URL (e.g. https://abc123.ngrok.app) — discovery lives at https://abc123.ngrok.app/.well-known/openid-configuration.Register the provider on Cativa
client_id/client_secret the mock accepts (they’re in the folder README). Turn on Auto-provision with default Role User and set the slug mock.Run the flow end to end
https://apis.cativalab.digital/tenant/api/v2/sso/external/{customerName}/mock/authorize. The mock shows a fake login form, issues an RS256 id_token with the email claim, and Cativa returns you signed into the community. A new user should show up in the admin with the email you typed.Common errors
Invalid or expired state at the callback
Invalid or expired state at the callback
sso_state) didn’t come back. Make sure the IdP redirected to the exact registered callback URL (.../tenant/api/v2/sso/external/{customerName}/callback, with the full prefix) and the flow completed within 10 minutes.The provider did not return a valid email
The provider did not return a valid email
id_token came without the email claim. Adjust the scopes/claims on your IdP client to include email (and email_verified where applicable).Identity provider could not be determined
Identity provider could not be determined
/sso/external/{customerName}/{slug}/authorize URL (with the right slug).Invalid identity token
Invalid identity token
id_token signature didn’t validate, or the audience doesn’t match. Confirm the registered Client ID equals the aud your IdP issues, and that the Metadata URL points to the right JWKS.User signs in but doesn't see the expected groups/courses
User signs in but doesn't see the expected groups/courses
Next steps
Sign in with Cativa
Badges as Permissions
Example IdP (GitHub)
cliente-idp folder is a runnable mock OIDC IdP to test this flow.