Authenticate an M2M Client
Stytch's M2M Authentication enables your services to communicate and authenticate without any human involvement. Use our M2M Auth API to create clients, retrieve access tokens, and define permissions with scopes to securely communicate between machines.
In this guide, you'll learn how to create and authenticate an M2M Client. By the end, you'll have:
Created an M2M Client.
- Issued an access_token.
- Authenticated the M2M Client by validating the access_token.
Deactivated or deleted an M2M Client.
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 most Stytch API calls.
Step 1: Create an M2M Client
An M2M (machine-to-machine) client represents a machine identity. To create one, call the Create M2M Client endpoint and provide optional attributes like client_name, client_description, scopes, and trusted_metadata that describe the client use case.
If you prefer, you also have a UI option for creating M2M Clients in the Dashboard. For the purposes of this guide, we'll be using the API.
curl --request POST \
--url https://test.stytch.com/v1/m2m/clients/ \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"client_name": "Example client",
"client_description": "Following the Stytch guide.",
"scopes": ["read:settings", "write:settings"],
"trusted_metadata": {
"billing_tier": "standard",
"api_version": "v2"
}
}'
After a successful API call, the response will look like this.
{
"m2m_client": {
"client_description": "Following the Stytch guide.",
"client_id": "m2m-client-test-a50053...",
"client_name": "Example client",
"client_secret": "FXvejQZKicBl7Lq...QqNU",
"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
}
Important: This is the only time you will be able to view the generated client_secret in the API response. Stytch stores a hash of the client_secret and cannot recover the value if lost. Be sure to persist the client_secret in a secure location. If the client_secret is lost, you will need to trigger a secret rotation flow to receive another one.
Step 2: Call the Get Access Token endpoint.
After creating an M2M client, you'll need to issue and retrieve an access token.
Call the Get Access Token endpoint and provide the following parameters in the request body and URL path:
- project_id from the Basic Auth header in Step 1
- client_secret from the response in Step 1
- client_id from the response in Step 1
- grant_type set to the value "client_credentials"
curl --request POST \
--url https://test.stytch.com/v1/public/PROJECT_ID/oauth2/token \
-H 'Content-Type: application/json' \
-d '{
"client_id": "m2m-client-test-a50053..",
"client_secret": "FXvejQZKicBl7Lq...QqNU",
"grant_type": "client_credentials"
}'
The response will contain the access_token, a JWT signed with your project's JWKS. The lifespan of the access_token is one hour.
{
"status_code": 200,
"request_id": "request-id-test-b05c992f-ebdc-489d-a754-c7e70ba13141",
"access_token": "eyJ...",
"token_type": "bearer",
"expires_in": 3600
}
Step 3: Authenticate the access token
At this point, the M2M Client you've created from Step 1 will communicate with your services with the issued access_token from Step 2.
Your services will need to authenticate the access_token locally with one of Stytch's backend SDKs (available in Node, Python, Go, and Ruby). You can also alternatively use a library that supports JWT signature validation.
Using the backend Node SDK as an example, your services will call the Authenticate Access Token method with the provided access_token.
As an option for enforcing permissions, you can also specify required_scopes the access_token must contain in order to be valid: any missing scope will return an error.
const stytch = require('stytch');
const client = new stytch.Client({
project_id: 'PROJECT_ID',
secret: 'SECRET',
});
const params = {
access_token: 'eyJ...',
required_scopes: ['write:settings'],
};
client.m2m
.authenticateToken(params)
.then((resp) => {
console.log(resp);
})
.catch((err) => {
console.log(err);
});
A successful response will contain the M2M Client's client_id, scopes, and custom_claims (Check out our using custom claim templates guide to learn how to pass customized claims to every issued JWT for M2M Clients).
{
"client_id": "m2m-client-test-a50053....",
"scopes": ["read:settings","write:settings"],
"custom_claims": {}
}
At this point, the M2M Client has successfully been authenticated.
Step 4: Deactivate or delete the M2M Client
If the M2M Client needs to be deactivated, call the Update M2M Client endpoint and set the status to inactive, which will prevent the M2M Client from receiving new access tokens.
curl --request POST \
--url https://test.stytch.com/v1/m2m/clients/m2m-client-test-d73... \
-u 'PROJECT_ID:SECRET' \
-H 'Content-Type: application/json' \
-d '{
"status": "inactive"
}'
M2M Clients can be reactivated by setting the status to active.
If the M2M Client needs to be deleted, call the Delete M2M Client endpoint.
curl --request DELETE \
--url https://test.stytch.com/v1/m2m/clients/m2m-client-test-d73... \
-u 'PROJECT_ID:SECRET'
Important: Deactivating or deleting an M2M Client will not invalidate any existing JWTs issued to the client, only prevent it from receiving new ones.
What's next
Keep your M2M Clients' identities secure and learn how to rotate client secrets.
Also, take a look at our comprehensive M2M Authentication example app tutotrial, which includes an open-source GitHub repo utilizing the Node.js SDK.