Olympus Docs
CookbookPlatform migration

Migrate from Okta CIC to Olympus

Move from Okta Customer Identity Cloud to self-hosted

Okta CIC (formerly Auth0; now under Okta umbrella) is enterprise-grade hosted CIAM. Olympus is the self-hosted alternative.

When this migration makes sense

  • Cost: Okta CIC priced per MAU. At scale, six figures/year.
  • Data sovereignty: customers / regulators require on-prem.
  • Customization beyond Okta's flexibility.
  • Vendor independence.

When to stay on Okta

  • Compliance-as-a-service is valuable (Okta has SOC 2, ISO, FedRAMP).
  • Small team can't operate Olympus.
  • You use Okta's enterprise features (advanced workflows, fraud detection, etc.).

What translates

Okta CICOlympus
UsersKratos identities
ApplicationsHydra OAuth2 clients
Connections (social, enterprise)Kratos OIDC providers
Actions / TriggersKratos web_hooks
Branded UICustomize Hera
MFA factorsKratos credentials (TOTP, WebAuthn)
OrganizationsCustom multi-tenant
RolesIdentity traits

What's different

Okta's Universal Login

Okta hosts the login UI with extensive customization. Olympus's Hera is fully open, you can customize anything but you operate it.

Okta Actions

Okta's Actions (formerly Rules) run in Okta's Node sandbox. Migrate to Kratos webhook handlers.

// Okta Action
exports.onExecutePostLogin = async (event, api) => {
  if (event.user.email.endsWith("@bigcorp.com")) {
    api.user.setAppMetadata("role", "admin");
  }
};

To Kratos webhook:

export async function POST(req: Request) {
  const { identity } = await req.json();
  if (identity.traits.email.endsWith("@bigcorp.com")) {
    await kratos.adminPatch(identity.id, [
      { op: "replace", path: "/metadata_admin/role", value: "admin" }
    ]);
  }
  return Response.json({ ok: true });
}

Workflows (Okta-specific)

Okta has visual workflows for complex multi-step processes. Olympus doesn't. Build equivalents in your app's backend.

User migration

Okta CIC exports password hashes (different from Workforce Okta):

auth0 users export --output-format json --connection username-password > users.json

Each user includes hashed password (bcrypt format).

Convert to Kratos:

const okta = require("./users.json");
const kratos = okta.map(u => ({
  schema_id: "default",
  traits: {
    email: u.email,
    first_name: u.given_name ?? u.user_metadata?.first_name,
    last_name: u.family_name ?? u.user_metadata?.last_name,
  },
  credentials: {
    password: {
      config: {
        hashed_password: u.password_hash,  // bcrypt
      },
    },
  },
  state: u.email_verified ? "active" : "active",
  metadata_admin: {
    legacy_okta_id: u.user_id,
  },
}));

Bulk insert via Kratos admin API.

Apps

For each Okta application, create a Hydra OAuth2 client:

hydra create client \
  --name "App Name" \
  --grant-types authorization_code,refresh_token \
  --response-types code \
  --token-endpoint-auth-method client_secret_basic \
  --scope "openid offline_access profile email" \
  --redirect-uri "https://app.example.com/callback"

Note: Okta's client_secrets are unique; you'll get new ones from Hydra. Update each app.

SAML / WS-Fed

Okta is strong on SAML. Olympus uses OIDC primarily, for SAML support, run Dex or Keycloak in front of Hydra as a SAML bridge.

# dex-config.yaml
issuer: https://saml-bridge.your-domain
connectors:
  - type: oidc
    id: olympus
    name: Olympus
    config:
      issuer: https://ciam.your-domain
      clientID: dex-client
      clientSecret: ...

Enterprise customers connect via SAML to Dex; Dex translates to OIDC to Olympus.

Enterprise SSO

Okta has many pre-built connectors (SAML, WS-Fed, etc.). Olympus's OIDC is universal but doesn't have one-click setup for niche enterprise IdPs.

For typical OIDC IdPs (Google Workspace, Entra ID): straightforward. For SAML-only IdPs: SAML bridge as above. For Active Directory: LDAP sync to Kratos (custom script).

Costs

Okta CIC list price: ~$0.05-1.50/MAU.

At 100k MAU: $5k-150k/mo.

Olympus self-hosted: ~$200/mo infra + 0.5-1 FTE operator time.

Break-even depends on operator cost in your geo. Roughly: $50k+ Okta bills are worth migrating; smaller might not be.

Migration risk

Okta is mission-critical for many. Migrating brings risk:

  • User passwords broken? lockouts.
  • OAuth clients misconfigured? app breakage.
  • Hooks lost? business logic missing.

Mitigate:

  • 30-day parallel run.
  • Detailed test plan.
  • Rollback plan.
  • Communication to internal stakeholders.

Compliance angle

If you have SOC 2 inherited from Okta, that goes away. You need:

  • Your own SOC 2 (audit ~$30-50k).
  • Equivalent controls documented.
  • Penetration test.

Plan for compliance work alongside technical migration.

Timeline

Typical Okta CIC → Olympus migration: 3-6 months.

  • Month 1: Olympus deployed, configured, hardened.
  • Month 2: User import, app cutover begins.
  • Month 3: Cutover complete, parallel run.
  • Month 4-6: Stabilization, decommission Okta.

Don't rush.

On this page