/
Contact usSee pricingStart building
Node
​

    About Stytch

    Introduction
    Integration Approaches
      Full-stack overview
      Frontend (pre-built UI)
      Frontend (headless)
      Backend
    Migrations
      Migration overview
      Migrating users statically
      Migrating users dynamically
      Additional migration considerations
      Zero-downtime deployment
      Defining external IDs for users
      Exporting from Stytch
    Custom Domains
      Overview

    Authentication

    DFP Protected Auth
      Overview
      Setting up DFP Protected Auth
      Handling challenges
    Magic Links
    • Email Magic Links

      • Getting started with the API
        Getting started with the SDK
        Replacing your password reset flow
        Building an invite user flow
        Add magic links to an existing auth flow
        Adding PKCE to a Magic Link flow
        Magic Link redirect routing
    • Embeddable Magic Links

      • Getting started with the API
    MFA
      Overview
      Backend integration
      Frontend integration
    Mobile Biometrics
      Overview
    M2M Authentication
      Authenticate an M2M Client
      Rotate client secrets
      Import M2M Clients from Auth0
    OAuth
    • Identity providers

      • Overview
        Provider setup
      Getting started with the API (Google)
      Add Google One Tap via the SDK
      Email address behavior
      Adding PKCE to an OAuth flow
    Connected AppsBeta
      Setting up Connected Apps
    • Integration Guides

      • Integrate with AI agents
        Integrate with MCP servers
        Integrate with CLI Apps
    • Resources

      • About Remote MCP Servers
    Passcodes
      Getting started with the API
      Getting started with the SDK
    • Toll fraud

      • What is SMS toll fraud?
        How you can prevent toll fraud
      Unsupported countries
    Passkeys & WebAuthn
    • Passkeys

      • Passkeys overview
        Set up Passkeys with the frontend SDK
    • WebAuthn

      • Getting started with the API
        Getting started with the SDK
    Passwords
      Getting started with the API
      Getting started with the SDK
      Password strength policy
    • Email verification

      • Overview
        Email verification before password creation
        Email verification after password creation
    Sessions
      How to use sessions
      Backend integrations
      Frontend integrations
      Custom claims
      Custom claim templates
      Session tokens vs JWTs
      How to use Stytch JWTs
    TOTP
      Getting started with the API
      Getting started with the SDK
    Web3
      Getting started with the API
      Getting started with the SDK

    Authorization

    Implement RBAC with metadata

    3rd Party Integrations

    Planetscale
    Supabase
    Feathery
    Unit

    Testing

    E2E testing
    Sandbox values
Get support on SlackVisit our developer forum

Contact us

Consumer Authentication

/

Guides

/

Authentication

/

M2M Authentication

/

Rotate client secrets

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_id and secret for the Test environment you would like to use. These values can be accessed from the API keys section of the Stytch dashboard. You'll need to pass these values into the Authorization request header for most Stytch API calls.
  • 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 tutorial, which includes an open-source GitHub repo utilizing the Node.js SDK.

Before you start

Step 1: Get the M2M Client

Step 2: Start the secret rotation

Step 3a: Complete the secret rotation

Step 3b: Cancel the secret rotation

What's next