Skip to content

Commit d6aa27f

Browse files
committed
adding docs pages
running prettier removing redundant ids a "valid" id was in fact - not valid removing unneccessary "s"
1 parent ec0c475 commit d6aa27f

File tree

6 files changed

+221
-11
lines changed

6 files changed

+221
-11
lines changed

docs/backend-requests/handling/manual-jwt.mdx

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
---
2-
title: Manual JWT verification
3-
description: Learn how to manually verify Clerk-generated session tokens (JWTs).
2+
title: Manual JWT Verification
3+
description: Learn how to manually verify Clerk-generated session and machine tokens (JWTs).
44
---
55

6-
Your Clerk-generated [session tokens](/docs/backend-requests/resources/session-tokens) are essentially JWTs which are signed using your instance's private key and can be verified using your instance's public key. Depending on your architecture, these tokens will be in your backend requests either via a cookie named `__session` or via the Authorization header.
6+
## Verifying Tokens
77

8-
For every request, you must validate its token to make sure it hasn't expired and it is authentic (i.e. no malicious user tried to tamper with it). If these validations pass, then it means that the user is authenticated to your application and you should consider them signed in.
8+
Clerk-generated tokens, including [session tokens](/docs/backend-requests/resources/session-tokens) and [machine tokens](/docs/backend-requests/resources/machine-tokens), are JWTs signed using your instance's private key and can be verified using your instance's public key.
99

10-
The `authenticateRequest()` method from the JavaScript Backend SDK does all of this for you. It accepts the `request` object and authenticates the session token in it. See the [reference page](/docs/references/backend/authenticate-request) for more information.
10+
For every request, you must validate the token to ensure it hasn't expired and is authentic (i.e., no malicious user tried to tamper with it). If these validations pass, it means that the user or machine is authenticated to your application.
1111

12-
## Networkless token verification
12+
The `authenticateRequest()` method from the JavaScript Backend SDK handles these validations for you. It accepts the `request` object and authenticates the token in it. See the [reference page](/docs/references/backend/authenticate-request) for more information.
13+
14+
### Session Tokens
15+
16+
Session tokens authenticate users. Depending on your architecture, these tokens will be in your backend requests either via a cookie named `__session` or via the Authorization header.
17+
18+
If the token is valid, you can consider the user signed in to your application.
19+
20+
#### Networkless token verification
1321

1422
{/* Note: this example is duped from /authenticate-request. Probably a good opportunity to use a partial here */}
1523

@@ -38,3 +46,37 @@ export async function GET(req: Request) {
3846
return Response.json({ message: 'This is a reply' })
3947
}
4048
```
49+
50+
### Machine Tokens
51+
52+
Machine tokens authenticate machines. They are typically provided via the Authorization header in your backend requests.
53+
54+
If the token is valid, it means that the machine is authenticated to your application.
55+
56+
To authenticate machine requests using `authenticateRequest()`, specify the `entity` parameter as `'machine'`. See the [reference page](/docs/references/backend/authenticate-request) for more information.
57+
58+
The following example uses 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.
59+
60+
```tsx
61+
import { createClerkClient } from '@clerk/backend'
62+
63+
export async function GET(req: Request) {
64+
const clerkClient = createClerkClient({
65+
secretKey: process.env.CLERK_SECRET_KEY,
66+
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
67+
})
68+
69+
const { isMachineAuthenticated, machinedId } = await clerkClient.authenticateRequest(req, {
70+
entity: 'machine',
71+
})
72+
73+
if (!authReq.isMachineAuthenticated) {
74+
return Response.json({ status: 401 })
75+
}
76+
77+
return Response.json({
78+
message: 'Machine is authenticated',
79+
machineId,
80+
})
81+
}
82+
```
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
title: Making Machine Requests
3+
description: Lean about making machine-to-machine requests.
4+
---
5+
6+
If your client is a backend service, you can create a [machine token](/docs/backend-requests/resources/machine-tokens) and use it in the `Authorization` header of your request.
7+
8+
## Using the Node.js SDK
9+
10+
The Node.js SDK has a `machineTokens` object that can be used to create machine tokens.
11+
12+
> [!WARNING]
13+
> Use of the Node.js SDK is still subject to the [Backend API rate limits](/docs/backend-requests/resources/rate-limits)
14+
15+
```tsx
16+
import { createClerkClient } from '@clerk/backend'
17+
18+
export default function machineFetch() {
19+
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })
20+
21+
// creates a token with no additional claims.
22+
const { token } = await clerkClient.machineTokens.create({
23+
machineId: 'mch_cron',
24+
claims: {
25+
permissions: ['read', 'write'],
26+
}, // custom claims customer's can add to their token
27+
expiresInSeconds: 60,
28+
})
29+
30+
const authenticatedFetch = async (...args) => {
31+
return fetch(...args, {
32+
headers: { Authorization: `Bearer ${await getToken()}` },
33+
}).then((res) => res.json())
34+
}
35+
36+
return authenticatedFetch
37+
}
38+
```
39+
40+
## Using the Backend API reference
41+
42+
You can also generate machine tokens by simply making a requests to Clerk's Backend API
43+
44+
Go to the Backend API reference to learn more. **The API reference for this endpoint doesn't exist yet**

docs/backend-requests/overview.mdx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ title: Request authentication
33
description: Learn about various ways to make authenticated requests to the backend when using Clerk SDKs.
44
---
55

6-
A request is considered “authenticated” when the backend can securely identify the user and device that is making the request. The reasons for making authenticated requests to the backend include:
6+
A request is considered “authenticated” when the backend can securely identify the entity that is making the request. The reasons for making authenticated requests to the backend include:
77

8-
- Associating the user with the action being performed
8+
- Associating a user with the action being performed
9+
- Associating a machine with the action being performed
910
- Ensuring the user has permission to make the request
1011
- Keeping an audit log of which device the user is performing actions from
1112

12-
In order to authenticate the user on the backend using Clerk's SDK, the short-lived [session token](/docs/backend-requests/resources/session-tokens) needs to be passed to the server.
13+
In order to authenticate a request on the backend using Clerk's SDK, a short-lived [session token](/docs/backend-requests/resources/session-tokens) or a [machine token](/docs/backend-requests/resources/machine-tokens) needs to be passed to the server.
1314

1415
## Frontend requests
1516

@@ -27,7 +28,7 @@ For same-origin requests, refer to our guide on [making same-origin requests](/d
2728

2829
For cross-origin requests, refer to our guide on [making cross-origin requests](/docs/backend-requests/making/cross-origin).
2930

30-
## Backend requests
31+
## Backend middleware
3132

3233
Clerk provides various middleware packages to set the session property for easy access. These packages can also require a session to be available on the current request. Choose the guide based on the language or framework you're using:
3334

@@ -36,7 +37,13 @@ Clerk provides various middleware packages to set the session property for easy
3637
- [Go](/docs/backend-requests/handling/go)
3738
- [Ruby on Rails / Rack](/docs/backend-requests/handling/ruby-rails)
3839

39-
If there is not middleware available for your preferred language or framework, you can extract the session token manually.
40+
If there is not middleware available for your preferred language or framework, you can extract the token manually.
41+
42+
### Machine
43+
44+
For machine requests, you need to create a machine token using Clerk's backend API. This token is similiar to a session token, but it allows you to authenticate backend requests without a user session. Include the machine token as a Bearer token in the `Authorization` header when making requests to your backend.
45+
46+
You can learn more about [creating machine tokens](/docs/backend-requests/resources/machine-tokens) and [handling machine tokens](/docs/backend-requests/handling/manual-jwt#authenticating-machine-tokens) for additional information
4047

4148
### Same-origin
4249

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: Machine tokens
3+
description: Learn about machine tokens and how to validate them in your backend.
4+
---
5+
6+
When you want a machine to authenticate requests to your backend, you authorize the requests with machine tokens.
7+
8+
Machine tokens are JWTs that contain information about your machine.
9+
10+
## Customizing your 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+
19+
> [!TIP]
20+
> 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.
21+
22+
### Some **valid** machine\_ids
23+
24+
- mch\_cron
25+
- mch\_pub\_sub
26+
- mch\_scheduler
27+
- mch\_device\_ada3f8b7\_d491\_4fe4\_b76e\_99e4c00b56d1
28+
29+
#### Some invalid machine\_ids
30+
31+
- user\_1234
32+
- mch\_OH\_HI
33+
- MCH\_123
34+
- mch-123
35+
36+
### Claims
37+
38+
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.
39+
40+
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.
41+
42+
> [!NOTE]
43+
> You cannot add claims that are [already set by clerk](#default-machine-claims).
44+
45+
### Expires In Seconds
46+
47+
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).
48+
49+
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.
50+
51+
### Clock Skew
52+
53+
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.
54+
55+
Adjusting the clock skew helps prevent token validation failures due to minor time discrepancies between the issuing server and the verifying server.
56+
57+
## Default machine claims
58+
59+
Every generated token has default claims that cannot be overridden by custom claims. Clerk's default claims include:
60+
61+
- `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.
62+
- `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.
63+
- `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.
64+
- `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.
65+
- `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.
66+
- `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.
67+
68+
## Making Machine Requests
69+
70+
To start making machine requests, refer to [making machine requests](/docs/backend-requests/making/machine).
71+
72+
## Validating Machine Tokens
73+
74+
To learn how to manually verify a machine token, refer to [validating machine tokens](/docs/backend-requests/handling/manual-jwt#machine-tokens).

docs/manifest.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,10 @@
697697
{
698698
"title": "JWT Templates",
699699
"href": "/docs/backend-requests/making/jwt-templates"
700+
},
701+
{
702+
"title": "Machine Requests",
703+
"href": "/docs/backend-requests/making/machine"
700704
}
701705
]
702706
]
@@ -753,6 +757,10 @@
753757
"title": "Session tokens",
754758
"href": "/docs/backend-requests/resources/session-tokens"
755759
},
760+
{
761+
"title": "Machine tokens",
762+
"href": "/docs/backend-requests/resources/machine-tokens"
763+
},
756764
{
757765
"title": "Rate limits",
758766
"href": "/docs/backend-requests/resources/rate-limits"

docs/references/backend/authenticate-request.mdx

Lines changed: 35 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

@@ -225,3 +232,31 @@ export async function GET(req: Request) {
225232
return Response.json({ message: 'This is a reply' })
226233
}
227234
```
235+
236+
### Machine token verification
237+
238+
The following example uses the `authenticateRequest()` to verify a machine token.
239+
240+
```tsx
241+
import { createClerkClient } from '@clerk/backend'
242+
243+
export async function GET(req: Request) {
244+
const clerkClient = createClerkClient({
245+
secretKey: process.env.CLERK_SECRET_KEY,
246+
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
247+
})
248+
249+
const { isMachineAuthenticated, machinedId } = await clerkClient.authenticateRequest(req, {
250+
entity: 'machine',
251+
})
252+
253+
if (!authReq.isMachineAuthenticated) {
254+
return Response.json({ status: 401 })
255+
}
256+
257+
return Response.json({
258+
message: 'Machine is authenticated',
259+
machineId,
260+
})
261+
}
262+
```

0 commit comments

Comments
 (0)