# MPC wrapping key rotation

There are several reasons why you may need to rotate the vault keys for an on-premises vault that uses Multi-party Computation (MPC):

* To satisfy compliance and regulatory requirements, such as the Digital Operational Resilience Act (DORA).
* To comply with cybersecurity policies within your institution.


Note
For vaults, rotating the MPC wrapping key means rewrapping the previously wrapped seed with the new key encryption key (KEK). This document refers to this process as **vault key rotation**.

Important
You can rotate the MPC *wrapping key* only for vaults that do not have random accounts generated with the vault.

This page describes the vault key rotation process, which involves the following steps:

1. Do a dry run of the intent for vault wrapping key rotation. This checks that the vault does not have any random accounts generated, to make sure that it is possible to proceed.
2. If Step 1 is successful, for each node, create new enclave contract with a new symmetric key.
3. Trigger the intent to start vault wrapping key rotation.
4. Wait for the `VaultKeyMaterialRewrapCompleted` or `VaultKeyMaterialRewrapFailed` event.
5. Update the enclave contract and use the new symmetric key to restart the enclaves.


Contact your CPE
Ripple DevOps also needs to rotate the *key encryption key* (*KEK*) for the nodes hosted by Ripple.

The details are as follows:

## A note about downtime during key rotation

Although performed rarely, key rotation involves some downtime for normal operations. For this reason, we recommend performing key rotation outside of usual business hours.

Suspend business operations
Suspend any business operations during the key rotation process. If you submit an intent that the vault needs to sign, this intent will be stuck in retrial indefinitely.

## Step 1: Do a dry run of the intent for vault wrapping key rotation

The first step is to do a dry run for an intent to execute the key rotation. This checks that the vault does not have any random accounts generated, to make sure that it is possible to proceed.

To do the dry run:

1. In the Custody API, call the [Perform a dry run for a given intent payload](/products/custody/v1.40/reference/api/openapi/intents/intentdryrun) operation with the `v0_RewrapVaultKeyMaterial` intent. (For more information about dry runs, see [Dry run intents](/products/custody/v1.40/governance/intents/manage-intents-and-approvals#dry-run-an-intent-with-the-api).)
2. You will need to provide the `vaultId` for the vault for which you are rotating the vault key.
3. Approve and sign the intent.


The intent payload has the following form:

```json
{
  "type": "v0_RewrapVaultKeyMaterial",
  "vaultId": "insert-vault-uuid-here",
  "customProperties": {}
}
```

If the dry run is successful, proceed to Step 2.

## Step 2: Create new enclave contract with a new symmetric key

The next step is to create a new *key encryption key (KEK)* and to update the MPC nodes.

Contact your CPE
To complete these steps, you need to coordinate with your Ripple CPE, as Ripple DevOps also needs to rotate the *key encryption key* (*KEK*) for the nodes hosted by Ripple.

As described in the [Multi-party computation (MPC) overview](/products/custody/v1.40/deployment/integrate-kms/mpc/overview), the KEK is an *AES symmetric key* that is securely stored and never leaves the MPC node's secure environment.

Generate a new node contract with `NEXT_KEK_PROVIDER_EMBED` containing a new symmetric key, along with the existing key in `KEK_PROVIDER_EMBED`, for *each* node.

For each customer-hosted node:

1. The customer generates a new symmetric key and stores it in the Secrets Manager.
2. The customer provides this new key in the new node contract as `NEXT_KEK_PROVIDER_EMBED`. The current key encryption key is still present in the contract in `KEK_PROVIDER_EMBED`.
3. The customer deploys the updated node contract.


For each Ripple-hosted node:

1. The Ripple DevOps representative creates a new enclave contract with `NEXT_KEK_PROVIDER_EMBED` containing a new symmetric key.
2. The Ripple DevOps representative deploys the updated node contract, in the same way as the customer.


After you update and deploy the node contracts for *all four MPC nodes*, proceed with Step 3 below.

Important
Before triggering the rewrapping intent in Step 3, you must populate both `KEK_PROVIDER_EMBED` and `NEXT_KEK_PROVIDER_EMBED` in the contract, to allow it to unwrap keys with the old KEK and rewrap with the new one.

If this step fails
If you can't update the MPC node contracts with the new KEKs, the wrapping key rotation hasn't started. You can continue to operate with the existing wrapping key.

## Step 3: Execute the intent to start vault wrapping key rotation

The next step is to execute the intent to complete the key rotation.

To execute the intent:

1. In the Custody API, call the [Propose an intent](/products/custody/v1.40/reference/api/openapi/intents/createintent) operation with the `v0_RewrapVaultKeyMaterial` intent.  (For more information about requesting intents, see [Manage intents and approvals](/products/custody/v1.40/governance/intents/manage-intents-and-approvals).)
2. You will need to provide the `vaultId` for the vault for which you are rotating the vault key.
3. Approve and sign the intent.


During the rotation of the vault key, Ripple Custody rewraps and updates two keys: the seed used for the generation of derived account keys, and the vault signing key.

Ripple Custody *lazy rotates* account keys — the next time you use a key for a signature, Ripple Custody checks `lastKeyMaterialRewrappingDate` and determines if it has updated the key material with the rewrapped seed.

## Step 4: Wait for the `VaultKeyMaterialRewrapCompleted` or `VaultKeyMaterialRewrapFailed` event

After you approve the intent, wait for the intent state to change to **Executed**. If the rewrapping succeeds, Ripple Custody emits a `VaultKeyMaterialRewrapCompleted` event. If it fails, Ripple Custody emits a `VaultKeyMaterialRewrapFailed` event.

If you see the `VaultKeyMaterialRewrapCompleted` event, proceed to Step 5.

If the rewrapping intent fails
If the intent fails with a `VaultKeyMaterialRewrapFailed` error, Ripple Custody is still using the previous wrapping key. Retry the intent until the rewrapping succeeds. If it never succeeds, consider the MPC wrapping key rotation incomplete and keep using the previous KEKs on the MPC nodes until you have investigated the problem.

## Step 5: Update the enclave contract and restart the enclaves

For the final step, generate and deploy a new node contract with `NEXT_KEK_PROVIDER_EMBED` empty and `KEK_PROVIDER_EMBED` containing the newly rotated KEK, *for each node*.

Contact your CPE
To complete this step, you will need to coordinate with your Ripple CPE, as Ripple DevOps also needs to complete the key rotation for the nodes hosted by Ripple.

For each customer-hosted node:

1. The customer puts the new KEK in `KEK_PROVIDER_EMBED` and sets `NEXT_KEK_PROVIDER_EMBED` to an empty value.
2. The customer deploys the updated node contract.


For each Ripple-hosted node:

1. The Ripple DevOps representative creates a new enclave contract with `NEXT_KEK_PROVIDER_EMBED` empty and `KEK_PROVIDER_EMBED` containing the newly rotated KEK.
2. The Ripple DevOps representative deploys the updated node contract, in the same way as the customer.


After you update and deploy node contracts for *all four MPC nodes*, the wrapping key rotation is complete.

If updating the node contracts fails
If the rewrapping intent succeeded (you received the event confirming the rotation is complete) but you can't update the MPC node contracts, regenerate and update the node contracts until it succeeds. Do not submit any other intent to Ripple Custody in the meantime, as business intents will get stuck. Ripple Custody resumes normal operation only after the new wrapping key is committed on the MPC side.