# Rotate JWS keys

How to rotate JWS signing keys in the Developer Hub

Rotating your JWS signing key means:

1) generating a new key pair,
2) uploading the **public** key to Wise in DevHub, and
3) switching your system to sign with the matching **private** key.


This limits the impact of a compromised key and helps avoid verification failures when keys expire.

To learn the basics, see [JSON Web Signature (JWS)](/guides/developer/auth-and-security/jose/jose-jws).

This feature is currently **beta**. To participate, contact your Wise Delivery / Implementation Manager.

### Tips before you start

It's best to plan a short **overlap window** where both the old and new public keys are present in DevHub. This lets you switch signers safely before revoking anything.

Choosing a clear `kid` (key ID) naming convention (for example: `signing-2026-05-11`), ensures you can identify keys easily later.

## Step 1: Generate a new key pair

Generate a new key pair and store your **private** key securely (for example in an HSM or a secrets manager).
You’ll upload **only the public key** to Wise.

## Step 2: Upload the new public key in DevHub

Never share or upload your **private** key to Wise. Only upload the **public** key.

1. Log in to DevHub:
  - **Sandbox testing:** log in to the [Developer Hub sandbox](https://wise-sandbox.com/developer-hub/) with your sandbox credentials.
  - **Production:** log in to the [Developer Hub (production)](https://wise.com/developer-hub) with your production credentials.
2. In the left menu, open **Authentication**.
3. Go to the **JOSE** screen.
4. On the **Signing (JWS)** tab, click **Upload new signing key**.
5. Enter a **Key ID (`kid`)** and paste the **public key** content.


After upload, you should see the new key listed alongside any existing keys.

## Step 3: Switch your signing system to the new private key

Update your signing configuration so newly created JWS/JWTs are signed with the **new private key**, and set the JWT/JWS header `kid` to the new Key ID you entered in DevHub.

- Test by [sending signed payloads with the new JWS key](/guides/developer/auth-and-security/jose/jose-jws#flow).
- Ensure the `kid` in your JWT header **exactly matches** the Key ID in DevHub.


Important
Keep the old public key available during the cutover. Don’t revoke it until you are confident all signing traffic is using the new `kid`.

## Step 4: Revoke (delete) the old public key

Once you’ve confirmed your integration is successfully signing with the new key (and requests are verifying as expected):

1. Return to **Authentication → JOSE → Signing (JWS)**.
2. Delete the **old** key and confirm when prompted.


## Troubleshooting checklist

- **Verification failures after rotation:** confirm your signer is using the new private key *and* the JWT header `kid` matches the new Key ID in DevHub.
- **Wrong environment:** keys uploaded in **sandbox** won’t work in **production** (and vice versa).
- **Revoked too early:** if you deleted the old key before all services switched, re-upload the old public key (if you still have it) and repeat the cutover more gradually.