-
Notifications
You must be signed in to change notification settings - Fork 535
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Showing
4 changed files
with
231 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
--- | ||
title: Machine-to-Machine Requests | ||
description: Learn how to use machine tokens to make and verify authenticated requests. | ||
--- | ||
|
||
## Introduction | ||
|
||
Machine-to-machine (M2M) authentication allows services, scripts, or devices to securely communicate with each other without the need for a user's session. | ||
|
||
For example, you might need machine tokens for: | ||
|
||
- Cron jobs that update your database | ||
- Background workers processing queued tasks | ||
- Microservices communicati\@ng with each other | ||
|
||
## Creating Machine Requests | ||
|
||
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. | ||
|
||
### Creating requests with the JavaScript Backend SDK | ||
|
||
Use the `clerkClient.machineTokens` object to create a [machine token](/docs/machine-requests/machine-tokens), then use the created token to make authenticated requests. | ||
|
||
> [!WARNING] | ||
> Creating machine tokens is subject to the [Backend API rate limits](/docs/backend-requests/resources/rate-limits) | ||
```tsx | ||
import { createClerkClient } from '@clerk/backend' | ||
|
||
export default async function cronJob() { | ||
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }) | ||
|
||
const { token } = await clerkClient.machineTokens.create({ | ||
machineId: 'mch_cron', | ||
claims: { | ||
permissions: ['read', 'write'], | ||
}, | ||
expiresInSeconds: 60, | ||
}) | ||
|
||
await fetch('https://api.example.com/cron', { | ||
method: 'POST', | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
}, | ||
body: JSON.stringify({ | ||
message: 'Hello World!', | ||
}), | ||
}) | ||
} | ||
``` | ||
|
||
## Verifying Machine Requests | ||
|
||
For a machine request to be valid, it must include a valid [machine token](/docs/machine-requests/machine-tokens) in the Bearer `Authorization` header. | ||
|
||
You can verify machine tokens in two ways: | ||
|
||
1. Using Clerk's Backend SDK (recommended) | ||
1. Manually verifying the JWT using your instance's public key. | ||
|
||
### Verifying requests with the JavaScript Backend SDK | ||
|
||
#### Using the `authenticateRequest()` method | ||
|
||
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. | ||
|
||
```tsx | ||
import { createClerkClient } from '@clerk/backend' | ||
|
||
export async function GET(req: Request) { | ||
const clerkClient = createClerkClient({ | ||
secretKey: process.env.CLERK_SECRET_KEY, | ||
publishableKey: process.env.CLERK_PUBLISHABLE_KEY, | ||
}) | ||
|
||
const { isMachineAuthenticated, machineId } = await clerkClient.authenticateRequest(req, { | ||
entity: 'machine', | ||
}) | ||
|
||
if (!isMachineAuthenticated) { | ||
return Response.json({ status: 401 }) | ||
} | ||
|
||
return Response.json({ | ||
message: `Machine is authenticated with ID: ${machineId}`, | ||
}) | ||
} | ||
``` | ||
|
||
#### Using the `await auth()` Next.js helper | ||
|
||
You can use the `await auth()` Next.js helper to verify that the request is authenticated and that the user is a machine. | ||
|
||
NOTE FOR REVIEWER: | ||
|
||
> [!NOTE] | ||
> Currently the `auth()` helper does not support **any** parameters, adding the `entity` paramter would be a big change to the sdk. | ||
> 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. | ||
> Also, in the Next.js `auth()` function, will it know that the token is in the Authorization header? Not the cookie? | ||
```tsx | ||
import { auth } from '@clerk/nextjs/server' | ||
|
||
export async function GET() { | ||
const { isMachineAuthenticated, machineId } = await auth({ entity: 'machine' }) | ||
|
||
if (!isMachineAuthenticated) { | ||
return new Response('Machine authentication failed.', { status: 401 }) | ||
} | ||
|
||
return new Response(`Machine is authenticated with ID: ${machineId}`, { status: 200 }) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
--- | ||
title: Machine tokens | ||
description: Learn about machine tokens and how to validate them in your backend. | ||
--- | ||
|
||
**Machine tokens** are JWTs used to authenticate machine requests. | ||
|
||
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. | ||
|
||
## Creating machine tokens | ||
|
||
### Machine ID | ||
|
||
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: | ||
|
||
- It must be prefixed with `mch_` | ||
- It must only contain lowercase letters and numbers | ||
- It must be 96 characters or less | ||
|
||
> [!TIP] | ||
> 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. | ||
- Examples: | ||
- ✅ `mch_cron_service` | ||
- ✅ `mch_background_worker` | ||
- ✅ `mch_device_6580fc77_afca_47ac_8973_b7261d14e4c7` | ||
- ❌ `user_2p94zsO6sBvVZR5Ca0KfBNLM36Z` | ||
- ❌ `mch-invalid` | ||
- ❌ `MCH_UPPERCASE` | ||
|
||
### Claims | ||
|
||
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. | ||
|
||
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. | ||
|
||
> [!NOTE] | ||
> You cannot add claims that are [already set by clerk](#default-machine-claims). | ||
### Expires In Seconds | ||
|
||
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). | ||
|
||
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. | ||
|
||
### Clock Skew | ||
|
||
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. | ||
|
||
Adjusting the clock skew helps prevent token validation failures due to minor time discrepancies between the issuing server and the verifying server. | ||
|
||
## Default machine claims | ||
|
||
Every generated token has default claims that cannot be overridden by custom claims. Clerk's default claims include: | ||
|
||
- `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. | ||
- `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. | ||
- `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. | ||
- `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. | ||
- `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. | ||
- `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. | ||
|
||
## Using Machine Tokens to create and verify requests | ||
|
||
To start using machine tokens to create and verify requests, refer to [making machine requests](/docs/machine-requests/machine-requests). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters