Introducing the next era of Duende IdentityServer.

Read our CEO’s announcement

Common Approaches to Migrating to Duende IdentityServer

Robert Phillips
Two blue circles

Whether you're coming from Auth0, Keycloak, OpenIddict, Entra ID, Authlete, or Curity, migrations to Duende IdentityServer share the same handful of moves. This post collects them so the product-specific posts can stay focused.

1. Stand Up an Identity Host (Separate From Your Apps)

The first step is not "add a package to your app." It is to create a small, dedicated ASP.NET Core identity host, a project whose job is to be your token server. This host is separate from the applications and APIs it secures, so that:

  • Users get single sign-on across all of your applications
  • Clients, scopes, and signing keys are managed in one place
  • Each host has a single, clean security boundary

Start from the quickstarts to get the shape right.

2. You Own the Login Experience

Duende IdentityServer provides the protocol endpoints. The interactive pages (login, logout, consent, error) are ordinary ASP.NET Core pages that live in your identity host. Migrating from a platform with a hosted login (Auth0's Universal Login, Keycloak themes, Entra or B2C flows) means rebuilding those pages, which is also your opportunity to fully own branding and UX. See the UI documentation.

3. Map Clients and Resources

Applications become clients. APIs and scopes become API resources, API scopes, and identity resources. You can keep configuration in code or in Entity Framework stores. Client secrets can't be exported from most source systems, so plan to issue new ones.

4. Shape Claims with IProfileService

Whatever produced your token claims before (Auth0 Rules and Actions, Keycloak protocol mappers, Entra app roles) becomes an IProfileService implementation in C#. It is the single place where your user store's data becomes claims.

You don’t have to implement it. You can use ASP.NET Identity or Duende User Management as the user store and use that data as teh source of claims.

5. Bring Users Across, and Mind the Passwords

Users can be imported with Duende User Management. Whether passwords come across depends entirely on the source:

  • Keycloak can export password hashes (hash, salt, and PBKDF2 params). Implement a custom IPasswordHashAlgorithm and users keep their existing passwords, with no reset.
  • Auth0 and Entra ID cannot export password hashes. Your options are to federate first (below) or trigger a one-time reset as users onboard.

On multi-factor: User Management provides passkeys, TOTP, OTP, and recovery codes, so you're not giving up MFA by moving.

6. Federate First, Migrate Gradually

The lowest-risk pattern, and the one we recommend for Auth0 and Entra ID especially:

  1. Stand up your Duende identity host.
  2. Add the existing provider as an upstream identity provider (via external or dynamic providers).
  3. Point applications at Duende one at a time. They only ever integrate with one issuer.
  4. Move users into your own store on your schedule, or keep the federation permanently.

Because Duende issues its own tokens to your applications, you can migrate the back of the system without touching the front.

7. Test the Core Flows Before Cutover

  • Discovery loads at /.well-known/openid-configuration with the expected issuer and keys.
  • Each client completes its intended flow (auth code + PKCE, or client credentials).
  • Access and ID tokens carry the expected audience, scopes, and claims.
  • APIs accept the new tokens; refresh and sign-out work end to end.
  • Claim mapping reproduces the authorization decisions your apps relied on.

The Throughline

Every one of these steps is the same idea: you are taking ownership of identity as part of your own system. That is the cost and the benefit. The identity host becomes a first-class, versioned, testable part of your architecture, running where you run everything else, with your data in your own infrastructure.