Olympus Docs
CookbookEnterprise SSO

Use Okta as identity provider for Olympus

Federate enterprise customers via Okta SSO

When an enterprise customer wants their employees to access your app using their existing Okta accounts. Configure Okta as an OIDC provider to Olympus.

Customer's side (Okta config)

The customer's IT admin:

  1. Okta admin → Applications → Create New App Integration.
  2. Sign-in method: OIDC - OpenID Connect.
  3. Application type: Web Application.
  4. App name: "[Your App] SSO".
  5. Sign-in redirect URI: https://ciam.your-domain/self-service/methods/oidc/callback/okta-{customer}.
  6. Sign-out redirect URI: https://ciam.your-domain/.
  7. Save.

Capture from Okta:

  • Client ID.
  • Client Secret.
  • Okta domain (e.g., your-customer.okta.com).

Your side (Olympus config)

# kratos.yml
selfservice:
  methods:
    oidc:
      enabled: true
      config:
        providers:
          - id: okta-{customer}
            provider: generic
            issuer_url: https://your-customer.okta.com
            client_id: ...
            client_secret: ...
            scope: [openid, email, profile, groups]
            mapper_url: file:///etc/config/oidc-okta.jsonnet

Restart Kratos.

Mapper

local claims = std.extVar('claims');
{
  identity: {
    traits: {
      email: claims.email,
      first_name: claims.given_name,
      last_name: claims.family_name,
      tenant_id: 'customer-X-uuid',  // Pin to this customer
      role: 
        if 'app-admins' in claims.groups then 'admin'
        else if 'app-users' in claims.groups then 'user'
        else 'guest',
    },
  },
}

Multi-tenant SSO

For multiple customers, each gets their own OIDC provider config:

providers:
  - id: okta-acme
    issuer_url: https://acme.okta.com
    ...
  - id: okta-bigcorp
    issuer_url: https://bigcorp.okta.com
    ...

Each provider's mapper sets the right tenant_id.

UI

In Hera, the social login row shows multiple Okta buttons:

<button onClick={() => signIn("okta-acme")}>Sign in with Acme Okta</button>
<button onClick={() => signIn("okta-bigcorp")}>Sign in with BigCorp Okta</button>

For better UX, decide which provider based on email domain:

function chooseProvider(email: string) {
  const domain = email.split("@")[1];
  if (domain === "acme.com") return "okta-acme";
  if (domain === "bigcorp.com") return "okta-bigcorp";
  return null;
}

User types email; if known domain → Okta button auto-revealed.

Just-in-time provisioning

First time a customer's Okta user signs in: no Olympus identity exists. Kratos's OIDC mapper creates one.

Configure registration to allow OIDC:

selfservice:
  flows:
    registration:
      enabled: true
      after:
        oidc:
          hooks:
            - hook: session  # auto-sign-in after registration

User → Okta → Olympus → app, all in one click. No "register" step.

Group → role mapping

Customer's Okta admin assigns groups. Mapper translates to Olympus roles.

Customer adds user to app-admins group in Okta → next login, user has admin role in Olympus.

For 100+ employees per customer, SCIM provides real-time provisioning:

  • New hire in Okta → SCIM call to your app → identity created in Olympus.
  • Termination in Okta → SCIM call → identity deactivated in Olympus.

Build a SCIM endpoint. See SCIM endpoint.

Logging out

Okta's "Logout from all apps" calls back to your SLO endpoint:

# Hydra OAuth2 client (for SAML-OIDC bridge if needed)
back_channel_logout_uri: https://ciam.your-domain/oauth2/logout

When customer's admin disables an Okta user, you want their Olympus session to end too. SCIM active: false handles this if implemented.

Without SCIM: short Olympus session (~1h) means user is force-re-authed regularly, picks up the Okta deactivation.

When users sign in via Okta the first time, you might still want to show a consent screen:

"By signing in, you agree to [Your App]'s Terms of Service."

In Hera's /consent page, show only on first time per identity.

Or skip entirely if you don't need consent (B2B customer using their employer's IdP).

Testing per-customer

For each customer:

  1. Customer creates test Okta user.
  2. Customer assigns to test group.
  3. You verify sign-in → correct tenant_id and role.
  4. Disable in Okta.
  5. Re-test sign-in fails.

Bake into onboarding checklist.

Self-service customer config (advanced)

For SaaS at scale, customers self-configure SSO:

  1. Customer enters their Okta issuer URL.
  2. Your backend retrieves Okta's OIDC discovery doc.
  3. Validates.
  4. Adds provider config to your runtime Kratos (or to settings vault).
  5. Reloads Kratos.

This is non-trivial but doable. See Per-tenant config.

Alternatives to Okta

  • Microsoft Entra ID (Azure AD): same pattern, different issuer URL.
  • Google Workspace: same.
  • OneLogin, JumpCloud: similar OIDC.

Once you have one Okta integration, others are straightforward.

On this page