Skip to content

Commit cfb62cb

Browse files
committed
adding docs pages
running prettier removing redundant ids a "valid" id was in fact - not valid removing unneccessary "s" reverting adding pages back in different folder some minor changes machine_id has a 255 character limit Some Colin Notes
1 parent 22d79ec commit cfb62cb

File tree

4 files changed

+203
-0
lines changed

4 files changed

+203
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
title: Machine-to-Machine Requests
3+
description: Learn how to use machine tokens to make and verify authenticated requests.
4+
---
5+
6+
## Introduction
7+
8+
Machine-to-machine (M2M) authentication allows services, scripts, or devices to securely communicate with each other without the need for a user's session.
9+
10+
For example, you might need machine tokens for:
11+
12+
- Cron jobs that update your database
13+
- Background workers processing queued tasks
14+
- Microservices communicati\@ng with each other
15+
16+
## Creating Machine Requests
17+
18+
If your client is a backend service, you can create a [machine token](/docs/machine-requests/machine-tokens) and use it in the `Authorization` header of outgoing request.
19+
20+
### Creating requests with the JavaScript Backend SDK
21+
22+
Use the `clerkClient.machineTokens` object to create a [machine token](/docs/machine-requests/machine-tokens), then use the created token to make authenticated requests.
23+
24+
> [!WARNING]
25+
> Creating machine tokens is subject to the [Backend API rate limits](/docs/backend-requests/resources/rate-limits)
26+
27+
```tsx
28+
import { createClerkClient } from '@clerk/backend'
29+
30+
export default async function cronJob() {
31+
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })
32+
33+
const { token } = await clerkClient.machineTokens.create({
34+
machineId: 'mch_cron',
35+
claims: {
36+
permissions: ['read', 'write'],
37+
},
38+
expiresInSeconds: 60,
39+
})
40+
41+
await fetch('https://api.example.com/cron', {
42+
method: 'POST',
43+
headers: {
44+
Authorization: `Bearer ${token}`,
45+
},
46+
body: JSON.stringify({
47+
message: 'Hello World!',
48+
}),
49+
})
50+
}
51+
```
52+
53+
## Verifying Machine Requests
54+
55+
For a machine request to be valid, it must include a valid [machine token](/docs/machine-requests/machine-tokens) in the Bearer `Authorization` header.
56+
57+
You can verify machine tokens in two ways:
58+
59+
1. Using Clerk's Backend SDK (recommended)
60+
1. Manually verifying the JWT using your instance's public key.
61+
62+
### Verifying requests with the JavaScript Backend SDK
63+
64+
#### Using the `authenticateRequest()` method
65+
66+
You can use the `authenticateRequest()` method with the [JavaScript Backend SDK](/docs/references/backend/overview) to verify that the token is a valid machine token generated by Clerk.
67+
68+
```tsx
69+
import { createClerkClient } from '@clerk/backend'
70+
71+
export async function GET(req: Request) {
72+
const clerkClient = createClerkClient({
73+
secretKey: process.env.CLERK_SECRET_KEY,
74+
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
75+
})
76+
77+
const { isMachineAuthenticated, machineId } = await clerkClient.authenticateRequest(req, {
78+
entity: 'machine',
79+
})
80+
81+
if (!isMachineAuthenticated) {
82+
return Response.json({ status: 401 })
83+
}
84+
85+
return Response.json({
86+
message: `Machine is authenticated with ID: ${machineId}`,
87+
})
88+
}
89+
```
90+
91+
#### Using the `await auth()` Next.js helper
92+
93+
You can use the `await auth()` Next.js helper to verify that the request is authenticated and that the user is a machine.
94+
95+
NOTE FOR REVIEWER:
96+
97+
> [!NOTE]
98+
> Currently the `auth()` helper does not support **any** parameters, adding the `entity` paramter would be a big change to the sdk.
99+
> I think we can add this and default to `entity: 'user'` -- but I am not confident here, so we probably want some back and forth on this.
100+
> Also, in the Next.js `auth()` function, will it know that the token is in the Authorization header? Not the cookie?
101+
102+
```tsx
103+
import { auth } from '@clerk/nextjs/server'
104+
105+
export async function GET() {
106+
const { isMachineAuthenticated, machineId } = await auth({ entity: 'machine' })
107+
108+
if (!isMachineAuthenticated) {
109+
return new Response('Machine authentication failed.', { status: 401 })
110+
}
111+
112+
return new Response(`Machine is authenticated with ID: ${machineId}`, { status: 200 })
113+
}
114+
```
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
title: Machine tokens
3+
description: Learn about machine tokens and how to validate them in your backend.
4+
---
5+
6+
**Machine tokens** are JWTs used to authenticate machine requests.
7+
8+
Unlike [session tokens](/docs/backend-requests/resources/session-tokens), machine tokens are not associated with a user or session. Instead **you** are responsible for determining the identity of the machine making the request.
9+
10+
## Creating machine tokens
11+
12+
### Machine ID
13+
14+
Every machine token you create needs to be associated with a `machine_id`. You can pick any value for the `machine_id` as long as it meets the following requirements:
15+
16+
- It must be prefixed with `mch_`
17+
- It must only contain lowercase letters and numbers
18+
- It must be 96 characters or less
19+
20+
> [!TIP]
21+
> It is a good idea to have the `machine_id` correspond with the identity of the service generating the token. For example if you have a cron service, a `machine_id` of `mch_cron` would make sense.
22+
23+
- Examples:
24+
-`mch_cron_service`
25+
-`mch_background_worker`
26+
-`mch_device_6580fc77_afca_47ac_8973_b7261d14e4c7`
27+
-`user_2p94zsO6sBvVZR5Ca0KfBNLM36Z`
28+
-`mch-invalid`
29+
-`MCH_UPPERCASE`
30+
31+
### Claims
32+
33+
You can add custom claims to your machine token to include any additional information that your application might need. Claims are key-value pairs included in the token's payload, and they can convey important data such as permissions, roles, or any other attributes relevant to the machine's identity.
34+
35+
For example, it is a good practice to include any permissions that your service requires directly in the claims. This allows your backend to easily verify what actions the machine is authorized to perform.
36+
37+
> [!NOTE]
38+
> You cannot add claims that are [already set by clerk](#default-machine-claims).
39+
40+
### Expires In Seconds
41+
42+
The `expiresInSeconds` parameter defines how long the machine token remains valid, specified in seconds. This parameter is optional and defaults to 60 seconds (1 minute).
43+
44+
If you need the machine token to be valid for a longer period of time, you can set the `expiresInSeconds` parameter to a higher value. However, keep in mind that longer-lived tokens can present a higher security risk if compromised, while shorter-lived tokens may require more frequent token generation, potentially impacting your [Backend API rate limits](/docs/backend-requests/resources/rate-limits). Therefore, it's important to balance token lifespan with security requirements and rate limit considerations.
45+
46+
### Clock Skew
47+
48+
The `allowedClockSkew` parameter provides a leeway in seconds to account for clock differences between servers. This setting affects the `nbf` (Not Before) claim in the token, calculated as `nbf = current_time - allowed_clock_skew`. The default value is 5 seconds.
49+
50+
Adjusting the clock skew helps prevent token validation failures due to minor time discrepancies between the issuing server and the verifying server.
51+
52+
## Default machine claims
53+
54+
Every generated token has default claims that cannot be overridden by custom claims. Clerk's default claims include:
55+
56+
- `exp`: expiration time - the time after which the token will expire, as a Unix timestamp. Determined using the **Token Expires In Seconds** request body parameter when creating machine tokens. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4) for more information.
57+
- `iat`: issued at - the time at which the token was issued as a Unix timestamp. For example: `1516239022`. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6) for more information.
58+
- `jti`: JWT ID - the ID of the token internally generated by Clerk. For example: `a1b2c3d4e5f67890abcd`. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.7) for more information.
59+
- `iss`: issuer - the Frontend API URL of your instance. For example: `https://clerk.your-site.com` for a production instance or `https://your-site.clerk.accounts.dev` for a development instance. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1) for more information.
60+
- `nbf`: not before - the time before which the token is considered invalid, as a Unix timestamp. Determined using the **Allowed Clock Skew** request body parameter when creating machine tokens. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5) for more information.
61+
- `sub`: subject - the ID of the machine that created the token. Determined using the **Machine ID** request body parameter when creating machine tokens. For example: `mch_123`. See [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.2) for more information.
62+
63+
## Using Machine Tokens to create and verify requests
64+
65+
To start using machine tokens to create and verify requests, refer to [making machine requests](/docs/machine-requests/machine-requests).

docs/manifest.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,23 @@
831831
{
832832
"title": "Transfer ownership",
833833
"href": "/docs/guides/transferring-your-app"
834+
},
835+
{
836+
"title": "Machine Requests",
837+
"collapse": true,
838+
"tag": "(Beta)",
839+
"items": [
840+
[
841+
{
842+
"title": "Machine requests",
843+
"href": "/docs/machine-requests/machine-requests"
844+
},
845+
{
846+
"title": "Machine tokens",
847+
"href": "/docs/machine-requests/machine-tokens"
848+
}
849+
]
850+
]
834851
}
835852
]
836853
]

docs/references/backend/authenticate-request.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ It is recommended to set these options as [environment variables](/docs/deployme
6161

6262
---
6363

64+
- 'entity?'
65+
- 'session' | 'machine'
66+
67+
Determines what type of authentication to perform. If set to `'session'`, the function will authenticate a user session. If set to `'machine'`, the function will authenticate a machine-to-machine request. Defaults to `session`
68+
69+
---
70+
6471
- `domain?`
6572
- `string`
6673

0 commit comments

Comments
 (0)