Skip to main content
This guide is the inverse of Sign in with Cativa.
  • 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.
Use this when the community belongs to an organization that already has an identity directory (Google Workspace, Microsoft Entra/Azure AD, Okta, Auth0, Keycloak, or any OIDC provider) and members shouldn’t create a separate password.
Want to test without a real IdP? The 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 the id_token that comes back, and links (or provisions) the user in the community.

How it works

Cativa verifies the id_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

  1. An OAuth/OIDC app in your IdP — create a client in the company provider and note its client_id (YOUR_CLIENT_ID) and client_secret (YOUR_SECRET).
  2. 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.
  3. 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:
1

Discovery

Paste the Metadata URL (your IdP’s .well-known/openid-configuration) and click Discover endpoints — Cativa fills authorize/token/userinfo/jwks for you. (For providers without discovery, enter the endpoints manually.)
2

Credentials

Enter the Client ID and Client Secret of the client you created in the IdP, and the Scopes (at minimum openid email profile).
3

Provisioning

Turn on Auto-provision to create the user on first login, and choose the Default role (User or Admin). Without auto-provisioning, only already-existing (and linked) users can sign in.
4

Slug

Set a slug (e.g. company) — it goes in the federated login start URL.
Keep only one provider enabled while testing. The callback identifies the provider via a cookie set at the start; with multiple providers enabled and the cookie missing, identification is ambiguous.

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.
1

Point the login button at the start URL

The “Sign in with your company account” button only needs to navigate (GET) to:
Plain HTML example:
Cativa sets a state cookie (anti-CSRF + provider identification) and responds 302 to the company IdP’s /authorize.
2

The user authenticates on the company IdP

The browser follows the redirect and lands on the login screen the company already uses (Google, Microsoft, Okta…). The user authenticates there. Cativa never sees the password.
3

The IdP returns to Cativa's callback

The IdP redirects to the callback URL you registered:
Cativa validates 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.
4

Cativa links or provisions and redirects already signed in

With the 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.
Finally, it responds 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’s jwks (Cativa fetches the public key from discovery/JWKS).
  • The email claim is required — it’s the identity key. Without it, login is rejected.
  • given_name / family_name / picture are used (when present) when auto-provisioning the user.
The 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 the cativa-sso repo:
1

Run the mock IdP behind a tunnel

In the 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.
2

Register the provider on Cativa

In the admin, register a Custom (OIDC) provider pointing the Metadata URL at the tunnel’s discovery. Use the 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.
3

Run the flow end to end

Navigate to 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

The anti-CSRF cookie (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 id_token came without the email claim. Adjust the scopes/claims on your IdP client to include email (and email_verified where applicable).
More than one provider is enabled and the identification cookie was lost. Keep only one enabled, or always start from the /sso/external/{customerName}/{slug}/authorize URL (with the right slug).
The 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.
Federated login only authenticates and provisions the account. Access to groups and courses is controlled by badge-as-permission. After first login, assign the badges (via CRM, purchase, or Console) to unlock the content.

Next steps

Sign in with Cativa

The inverse flow: Cativa as the IdP for third-party apps.

Badges as Permissions

Login authenticates; a badge unlocks access. How to assign badges after the first federated login.

Example IdP (GitHub)

The cliente-idp folder is a runnable mock OIDC IdP to test this flow.