Need-to-KnowNeed-to-Know
IdentityOIDCMigrationKeycloak

Wallet User Identity is Permanent

Plan migrations up front — the sub claim becomes effectively permanent once bound, and there is no simple 'rename' mechanism.

5 min read

The Problem

What happens to wallet user identity when migrating from one identity provider (IdP) to another (for example Auth0 → Keycloak)?

The Answer

In the Canton wallet flow, the user identity derived from the JWT sub claim becomes effectively permanent once first bound, and there is no simple "rename" mechanism after the initial binding.

If you switch IdPs and the sub values change, the wallet will reject the new tokens because the presented identity no longer matches what was originally recorded.

Quick Mental Model

  1. User logs in to the wallet via OIDC
  2. The wallet receives a JWT; the sub claim identifies the user
  3. That identity becomes bound in the wallet/ledger context and is expected to stay stable
  4. A new IdP typically emits different sub values, so the "same human" looks like a different identity to the system

Symptoms You'll See

After an IdP migration (or even a realm/client rebuild), users who previously logged in can no longer use the wallet with the new IdP tokens.

This often looks like "login succeeds but wallet actions fail" or "user not recognized," depending on where the mismatch is surfaced.

Why Migrations Break (OIDC Reality)

sub is intended to be a stable subject identifier within an issuer, but it is not guaranteed to be the same across different issuers (or across a rebuild where users are re-created).

So Auth0-style sub values and Keycloak-default UUID sub values usually won't match.

ProviderExample sub claim
Auth0google-oauth2|123456789012345678901
Keycloak (default)a1b2c3d4-e5f6-7890-abcd-ef1234567890

Safe Strategies

Strategy A — Decide Before First Login (Best)

Before any production wallet login, decide what your "forever identity" will be and keep it stable.

For new deployments, using Keycloak's default UUID sub is fineif you accept that it must never change for those users.

Strategy B — Preserve the Original sub During Migration

If you must change IdPs but keep existing wallet users working, configure the new IdP to emit thesame sub values as the old one.

In Keycloak, one blunt but effective approach is a "hardcoded claim" protocol mapper that forcessub to a chosen value.

Strategy C — Treat It as a New Identity Domain

If preserving sub is infeasible, you may need to onboard users as "new identities," which can imply new accounts/parties/workflows depending on how you operationalized wallet access.

Keycloak: Hardcoded sub Mapper (Example)

This example shows the mapper conceptually: force Keycloak to emit the original sub value from the previous IdP. Keycloak supports hardcoded claim protocol mappers for inserting a claim with a fixed value into tokens.

Hardcoded sub mapper configuration
{
  "name": "hardcoded-sub",
  "protocol": "openid-connect",
  "protocolMapper": "oidc-hardcoded-claim-mapper",
  "config": {
    "claim.name": "sub",
    "claim.value": "original-sub-value-from-old-idp",
    "jsonType.label": "String",
    "id.token.claim": "true",
    "access.token.claim": "true",
    "userinfo.token.claim": "true"
  }
}
⚠️Operational Warning
Hardcoding sub is powerful and dangerous—use it only with a clear migration plan and tight access controls.

Migration Checklist

Do this before switching IdPs:

  • Export and store the exact sub value(s) used by your existing wallet users
  • Decide whether you are preserving sub (recommended if you need continuity) or forcing a "new identity domain"
  • If preserving, implement the Keycloak mapper approach and test on DevNet/TestNet before touching MainNet

Verify the Fix

After configuring the new IdP, decode a fresh token and confirm sub matches the historical value expected by the wallet.

Critical Check
If sub differs, assume the migrated login will fail for previously-onboarded users.