# Migration guide

This guide describes specific tasks you need to perform as part of a migration to a new version of Ripple Custody.

## 1.15 and above

As part of the upgrade from version 1.14 or below to version 1.15 or higher, all user entries must be migrated to a new format, in preparation for the single sign-on (SSO) feature. You must perform these steps regardless of whether you intend to use SSO.

### Migration process

The process for migrating to version 1.15 or above is as follows:

| Step | Description | More information |
|  --- | --- | --- |
| 1 | Install Ripple Custody version 1.15 without SSO enabled | SaaS customers: Contact your Ripple liaisonOn-premise customers: See the on-premise deployment details in the [1.15 change history](/products/custody/v1.19/support/change-history/v115#on-premise) |
| 2 | Check for conflicts in user entries | SaaS customers: Contact your Ripple liaisonOn-premise customers: See [Check for user conflicts](#check-for-user-conflicts) |
| 3 | Update user entries with conflicts | SaaS and on-premise customers: See [Fix user conflicts](#fix-user-conflicts) |
| 4 | Install Ripple Custody version 1.15 with SSO enabled | SaaS customers: Contact your Ripple liaisonOn-premise customers: For details of feature flags to enable, contact your Ripple liaison |


Once you have completed these steps, to use SSO, contact your Ripple liaison to configure your external identity providers.

Once migration is completed, the URL of the authentication endpoint changes, as follows:

- Old URL format: `https://auth.<HOST_URL>/token`
- New URL format: `https://openid.<HOST_URL>/realms/Metaco/protocol/openid-connect/token`


### Check for user conflicts

This procedure checks for conflicts in user records that are not allowed from version 1.15 of Ripple Custody.
There are two possible types of conflicts:

- `sameAlias`: Users with the same alias and the same domain.
- `samePublicKey`: Users with the same public key but a different alias and domain.


To check for conflicts between existing user definitions, call the `GET /internal/v1/users/conflicts` API operation.

The following example shows both types of conflicts:


```json User conflict examples
{
    "sameAlias":[
        {
            "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e",
            "alias": "op1@ripple.com",
            "userIds":[
                "497f6eca-6276-4993-bfeb-53cbbbba6f08",
                "47ecb890-2e2b-4d53-9428-bf08f2ee56dc"
            ]
        }
    ],
    "samePublicKey":[
        {
            "publicKey": "MFkw...NfPfw/q9YW74Q==",
            "users":[
                {
                    "domainId": "8a0b02c3-fdd8-452e-bc6e-ef07a335ec7e",
                    "alias": "op2@ripple.com",
                    "userId": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
                },
                {
                    "domainId": "89hd02c3-fdd8-452e-bc6e-ef07a335ec7e",
                    "alias": "op1@ripple.com",
                    "userId": "hks86eca-6276-4993-bfeb-53cbbbba6f08"
                }
            ]
        }
    ]
}
```

### Fix user conflicts

To fix the user conflicts, update users to have an alias which is unique in the domain.

For more information about how to update users:

- In the API, see [Propose an intent to update an entity](/products/custody/v1.19/api/get-started/key-operations/update/intent-proposal#propose-an-intent-to-update-an-entity)
- In the UI, see [Update a user](/products/custody/v1.19/ui/environment/user/update#update-a-user)


The alias is shown in the UI as **Email address**.