Rotate client secrets
Stytch's M2M Authentication supports secret rotation to ensure security best practices with zero downtime. Regular rotation can prevent the prolonged misuse of any compromised credentials by updating the secrets for an M2M Client.
In this guide, you'll learn how to rotate secrets for an M2M Client. By the end, you'll have:
Started a secret rotation.
Completed a secret rotation.
Canceled a secret rotation.
Before you start
In order to complete this guide, you'll need the following:
- A Stytch project (either Consumer or B2B). If you don't have one already, in the Dashboard, click on your existing project name in the top left corner of the Dashboard, click Create a new project, and then select B2B Authentication or Consumer Authentication.
- The project Test environment's project_id and secret from the API keys section. You'll need to pass these values into the Authorization request header for every Stytch API call.
- An active M2M Client. If you haven't created one yet, you can follow the Authenticate an M2M Client guide.
Step 1: Get the M2M Client
If you completed the Authenticate an M2M Client guide, you should have an active M2M Client. To confirm, call the [Get M2M Client endpoint] with its client_id.
curl --request GET \
--url https://test.stytch.com/v1/m2m/clients/{CLIENT_ID} \
-u 'PROJECT_ID:SECRET'
The response should look similar to this:
{
"m2m_client": {
"client_description": "Following the Stytch guide.",
"client_id": "m2m-client-test-a50053...",
"client_name": "Example client",
"client_secret_last_four": "QqNU",
"next_client_secret_last_four": null,
"scopes": [
"read:settings",
"update:settings"
],
"status": "active",
"trusted_metadata": {
"billing_tier": "standard",
"api_version": "v2"
}
},
"request_id": "request-id-test-c50eb06f-69b4-41be-8640-0d9fd2f561ae",
"status_code": 200
}
The important field to evaluate is next_client_secret_last_four. If the value is null, proceed to the next step. If the field is already populated, the client is already in a secret rotation flow. Create a new M2M Client instead.
Step 2: Start the secret rotation
Take the client_id of your active M2M Client and call the Start Secret Rotation endpoint.
curl --request POST \
--url https://test.stytch.com/v1/m2m/clients/{CLIENT_ID}/secrets/rotate/start \
-u 'PROJECT_ID:SECRET'
{
"m2m_client": {
"client_description": "Following the Stytch guide.",
"client_id": "m2m-client-test-a50053...",
"client_name": "Example client",
"client_secret_last_four": "QqNU",
"next_client_secret":"NHQhc7ZqsXJ...DzJj",
"next_client_secret_last_four": "DzJj",
"scopes": [
"read:settings",
"update:settings"
],
"status": "active",
"trusted_metadata": {
"billing_tier": "standard",
"api_version": "v2"
}
},
"request_id": "request-id-test-c50eb06f-69b4-41be-8640-0d9fd2f561ae",
"status_code": 200
}
After a successful API call, the response will return the M2M Client with two newly populated fields: next_client_secret and next_client_secret_last_four.
Important: This is the only time you will be able to view the generated next_client_secret in the API response. Stytch stores a hash of the next_client_secret and cannot recover the value if lost. Be sure to persist the next_client_secret`` in a secure location. If the next_client_secret`` is lost, you will need to cancel the secret rotation (Step 3b) and start the rotation all over.
At this point, the active M2M Client has two valid secrets associated with it. Both the client_secret and next_client_secret can be used to issue access tokens.
This is an opportune time to update your secret store to use the next_client_secret and replace the client_secret for your existing services.
Step 3a: Complete the secret rotation
Once updated with next_client_secret, your services can now retire the client_secret by completing the secret rotation.
Call the Rotate Secret endpoint with the client_id.
curl --request POST \
--url https://test.stytch.com/v1/m2m/clients/{CLIENT_ID}/secrets/rotate \
-u '{PROEJCT_ID}:{SECRET}'
{
"m2m_client": {
"client_description": "Following the Stytch guide.",
"client_id": "m2m-client-test-a50053...",
"client_name": "Example client",
"client_secret_last_four": "DzJj",
"next_client_secret_last_four": null,
"scopes": [
"read:settings",
"update:settings"
],
"status": "active",
"trusted_metadata": {
"billing_tier": "standard",
"api_version": "v2"
}
},
"request_id": "request-id-test-c50eb06f-69b4-41be-8640-0d9fd2f561ae",
"status_code": 200
}
A successful API call completes the secret rotation and results in the following updates:
- The M2M Client's client_secret from Steps 1 and 2 will be invalidated.
- The M2M Client's client_secret from Steps 1 and 2 will be replaced by the next_client_secret. To confirm, check the M2M Client's client_secret_last_four updated value.
- The M2M Client's next_client_secret_last_four will be set back to null.
Step 3b: Cancel the secret rotation
If for any reason after Step 2 you need to stop or revert the secret rotation process, call the Cancel Secret Rotation endpoint with the client_id.
curl --request POST \
--url https://test.stytch.com/v1/m2m/clients/{CLIENT_ID}/secrets/rotate/cancel \
-u '{PROEJCT_ID}:{SECRET}'
{
"m2m_client": {
"client_description": "Following the Stytch guide.",
"client_id": "m2m-client-test-a50053...",
"client_name": "Example client",
"client_secret_last_four": "DzJj",
"next_client_secret_last_four": null,
"scopes": [
"read:settings",
"update:settings"
],
"status": "active",
"trusted_metadata": {
"billing_tier": "standard",
"api_version": "v2"
}
},
"request_id": "request-id-test-c50eb06f-69b4-41be-8640-0d9fd2f561ae",
"status_code": 200
}
A successful API call cancels the secret rotation and results in the following updates:
- The M2M Client's client_secret from Steps 1 and 2 will not be updated and will remain valid.
- The M2M Client's next_client_secret and next_client_secret_last_four will be invalidated and set back to null.
What's next
Learn how to import M2M Clients from other platforms like Auth0.
Also, take a look at our comprehensive M2M Authentication example app tutotrial, which includes an open-source GitHub repo utilizing the Node.js SDK.