Skip to content

Commit b932d01

Browse files
committed
feat: flesh out M2M section of docs
1 parent 2f6af8a commit b932d01

13 files changed

+987
-81
lines changed
Lines changed: 12 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,21 @@
11
---
2-
page_id: bbcccc7e-2a7a-44f2-8069-1c4bd37141b1
3-
title: Machine-to-Machine (M2M) access scoped to organizations
2+
page_id: 44a1ac1e-3e17-44e1-b503-2e0e678f5cc2
3+
title: Give API access to an organization using M2M
44
sidebar:
5-
order: 10
5+
order: 8
66
relatedArticles:
7-
- 815f10b0-7bd2-407a-9ac2-9fb582862a5b
8-
- 8f6af95a-14ef-436d-862f-bfa82e836558
9-
- 263176d3-d823-4bba-a95f-02f6df00bd10
7+
- 9f832d29-1b76-4bb2-b4dc-e4a9a9c327b3
8+
- d2c841f1-78b4-47e0-b899-4d32ae857e0a
109
---
1110

12-
<Aside type="upgrade">
11+
If you want to give automated systems, AI agents, or backend services access to data in a specific organization, you can do this securely using an **organization-scoped machine-to-machine (M2M) application**.
1312

14-
This is an advanced feature that is only available on the [Kinde Plus or Scale plans](https://kinde.com/pricing/)
13+
This type of app is tied to a single organization and can only be used to access resources for that org.
1514

16-
</Aside>
15+
To create an org-scoped M2M app:
1716

18-
Kinde supports creating machine-to-machine (M2M) applications that are scoped to a specific organization. This lets you securely issue access tokens tied to an organization, ensuring that any automation or service calling your APIs is restricted to the correct customer context.
17+
1. In Kinde, go to **Organizations**, then select the organization.
18+
2. Select **Machine-to-machine apps**.
19+
3. Follow the steps to create the app and assign the appropriate scopes.
1920

20-
Global (unscoped) M2M applications are still supported for broader use cases, such as internal automation across multiple orgs.
21-
22-
## When to use an org-scoped M2M application
23-
24-
You should use an organization-scoped M2M app when:
25-
26-
- You are building automation that acts on behalf of a specific customer or tenant.
27-
- You are deploying AI agents, bots, or backend services that must be restricted to a single organization’s data.
28-
- You want to issue different tokens with separate scopes or permissions per organization.
29-
- You need to simplify tenant isolation and avoid passing or validating org codes manually.
30-
31-
## How it works
32-
33-
1. Create an M2M application inside an organization in the Kinde dashboard.
34-
2. Assign scopes that define what the app can access (e.g. `read:users`, `write:flags`).
35-
3. Use the client credentials flow to request an access token using the generated `client_id` and `client_secret`.
36-
4. Kinde returns a token with trusted claims about the organization and app.
37-
5. The token can be used to interact with Kinde APIs on behalf of that organization.
38-
39-
Each org-scoped app is tightly bound to a single organization. Tokens issued from that app cannot be used across orgs.
40-
41-
## Token structure
42-
43-
An example tokens issued to an org-scoped M2M app may include the following claims:
44-
45-
```json
46-
{
47-
"aud": ["https://api.foobar.com/v1/"],
48-
"azp": "12ce25d1109d4c66b0f469e47d33f8eb",
49-
"exp": 1751212288,
50-
"gty": ["client_credentials"],
51-
"iat": 1751125888,
52-
"iss": "https://example.kinde.com",
53-
"jti": "28a8d6a8-fe7c-4c90-84a6-1b3ccaaeabf2",
54-
"org_code": "org_1234567890",
55-
"scope": "read:users write:flags",
56-
"scp": ["read:users", "write:flags"],
57-
"v": "2"
58-
}
59-
```
60-
61-
These claims can be used by your backend services to authorize access to specific APIs or resources.
62-
63-
## Org-scoped vs global M2M applications
64-
65-
| Feature | Global M2M app | Org-scoped M2M app |
66-
| --------------------- | ---------------------------------- | ------------------------------ |
67-
| Org context in token | No | Yes |
68-
| Tenant data isolation | Manual | Enforced |
69-
| Use case | Admin scripts, internal automation | Per-tenant agents, scoped APIs |
70-
| Token restrictions | None | Scoped to one org |
71-
| Token claims | Basic | Includes `org_code`, `scope` |
72-
73-
## Create an org-scoped M2M app
74-
75-
1. In Kinde, go to **Organizations**, then view an organization.
76-
2. Select **M2M apps**.
77-
3. Select **Add M2M application**
78-
4. Enter a name for the application
79-
5. Select **Save**.
80-
81-
Kinde generates a `client_id` and `client_secret` tied to the selected organization.
82-
Use the credentials in a standard client credentials flow to request a token.
83-
84-
## Best practices
85-
86-
- Use separate M2M apps for different scopes or services.
87-
- Limit the [scopes](https://docs.kinde.com/developer-tools/your-apis/custom-api-scopes/) assigned to each M2M app to the minimum required for its function.
88-
- [Rotate client secrets](https://docs.kinde.com/build/applications/rotate-client-secret/) periodically using the UI.
89-
- Audit token usage by tracking `client_id` and `org_code` in logs.
90-
- Avoid including any personally identifiable information (PII) in token claims.
21+
For full details, see [M2M access scoped to organizations](/machine-to-machine-applications/m2m-applications-for-organizations/).
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
page_id: 524fa2a5-62b1-4c78-8786-b5aa9d7dc1ff
3+
title: Assign feature flags for use in M2M tokens
4+
sidebar:
5+
order: 7
6+
relatedArticles:
7+
- 3a16e08b-62c7-4725-8884-7065bfb2dbf2
8+
- 5b13e167-b032-4a61-a67a-81a12d6e20d5
9+
- f1c72f80-4f8e-4b5e-bc4d-6f2a798ec7f1
10+
---
11+
12+
You can include feature flags in the tokens issued to machine-to-machine (M2M) applications in Kinde. This is helpful for enabling or disabling functionality in downstream systems based on feature access.
13+
14+
> **Note:** At this time, only **environment-level feature flags** can be included in M2M tokens. Support for organization-assigned flag values may be added in future releases.
15+
16+
## Define environment-level feature flags
17+
18+
Before including a flag in a token, you need to define it in your environment.
19+
20+
1. In Kinde, go to **Releases**
21+
2. Select **Add flag**
22+
3. Give the flag a key and (optionally) description
23+
4. Choose the flag type (boolean, string, number)
24+
5. Add a default value (optional)
25+
6. Select **Save**
26+
27+
Once defined, this flag will be available for inclusion in any M2M token issued in the same environment.
28+
29+
## Include a flag in an M2M token
30+
31+
1. Go to **Applications > Your M2M app**
32+
2. Select the **Tokens** tab
33+
3. Under **Feature flags**, toggle on the flags you want included in the token
34+
35+
These flags will be embedded in the token under the `feature_flags` claim:
36+
37+
```json
38+
{
39+
"feature_flags": {
40+
"new-ai-agent": {
41+
"t": "b",
42+
"v": true
43+
},
44+
"access-level": {
45+
"t": "s",
46+
"v": "beta"
47+
}
48+
}
49+
}
50+
```
51+
The `t` and `v` are short codes for the type and value of the feature flag.
52+
53+
- `t` = `type` (boolean, string, number)
54+
- `v` = `value` (true | false, "beta", 1, etc.)
55+
56+
Only the feature flags you explicitly toggle on will be included.
57+
58+
## Common use cases
59+
60+
- Enable or disable AI models or endpoints
61+
- Drive conditional logic in APIs or job runners
62+
- Gate functionality in distributed workers
63+
64+
## Notes
65+
66+
- Flags are set at the **environment** level — they are global, not org-specific
67+
- Token customization is configured per-app in the **Tokens** tab
68+
- Tokens remain small: only enabled flags are included
69+
- Flag values are read-only for the recipient — you must update them via the dashboard or API
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
page_id: 6f82d354-7b77-4560-99d7-20a5b723b4b3
3+
title: Add metadata to an M2M application using properties
4+
sidebar:
5+
order: 6
6+
relatedArticles:
7+
- 3a16e08b-62c7-4725-8884-7065bfb2dbf2
8+
- 5b13e167-b032-4a61-a67a-81a12d6e20d5
9+
- 9f832d29-1b76-4bb2-b4dc-e4a9a9c327b3
10+
---
11+
12+
You can use **Properties** in Kinde to add structured metadata to a machine-to-machine (M2M) application. These properties can store configuration or contextual data like `region`, `tier`, or `model_version`.
13+
14+
This is useful for:
15+
- Customizing tokens
16+
- Driving logic in downstream systems
17+
- Managing AI agent behavior
18+
19+
If you're looking to include properties inside tokens, see [Customize the contents of an M2M token](/build/applications/m2m-customize-token/).
20+
21+
## Step 1 — Define your property
22+
23+
Before you can assign a property to an app, you need to define it.
24+
25+
1. In Kinde, go to **Properties**
26+
2. Select **Add property**
27+
3. Choose the object type: **Application**
28+
4. Give the property a name (e.g. `tier`, `region`, `model_version`)
29+
5. Add a description and data type (optional)
30+
6. You can opt for whether a property is allowed to be included in tokens (optional)
31+
7. Select **Save**
32+
33+
Once saved, this property is now available across all M2M applications.
34+
35+
## Step 2 — Assign the property to an M2M application
36+
37+
1. In Kinde, go to **Applications > M2M apps**
38+
2. Select the app you want to assign metadata to
39+
3. Open the **Properties** tab
40+
4. Add or edit values for the available fields
41+
42+
For example:
43+
44+
| Property | Value |
45+
|----------------|-----------|
46+
| region | eu |
47+
| model_version | v2 |
48+
| tier | pro |
49+
50+
These values are stored with the app but are not included in tokens unless explicitly enabled.
51+
52+
## Next: Use properties as token claims
53+
54+
If you want to include these properties inside tokens issued to the app:
55+
56+
→ See [Customize the contents of an M2M token](/build/applications/m2m-customize-token/)
57+
58+
There, you can toggle which properties are included in the token under the `custom` claim.
59+
60+
## Notes
61+
62+
- Properties are available for applications, users, and organizations
63+
- Only **Application** properties are relevant for M2M apps
64+
- This feature is useful for setting up per-customer configuration without hardcoding or external storage
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
page_id: f1c72f80-4f8e-4b5e-bc4d-6f2a798ec7f1
3+
title: Authenticate with Machine-to-Machine (M2M) Applications
4+
sidebar:
5+
order: 3
6+
relatedArticles:
7+
- d2c841f1-78b4-47e0-b899-4d32ae857e0a
8+
- 9f832d29-1b76-4bb2-b4dc-e4a9a9c327b3
9+
- 90134c89-16e4-4981-b988-b0cb4f1722c5
10+
---
11+
12+
You can use a machine-to-machine (M2M) application in Kinde to request access tokens using the OAuth 2.0 client credentials flow. These tokens can be used to call Kinde’s APIs or your own APIs with no user interaction required.
13+
14+
## Authorize your application
15+
Before a machine-to-machine (M2M) app can request a token for a specific API audience, it must be authorized for that API.
16+
17+
You can do this in the Kinde dashboard:
18+
19+
1. Go to the M2M application
20+
2. Select **APIs**
21+
3. Choose which APIs this app is allowed to call
22+
4. Select **Save**
23+
24+
You can also authorize apps programmatically using the Kinde Management API.
25+
26+
If the app is not authorized for the given audience, the token request will fail.
27+
28+
## Get an access token
29+
30+
Your M2M application will be provided with a `client_id` and `client_secret` which can be used to request a token.
31+
32+
To get a token, make a `POST` request to your Kinde environment’s token endpoint:
33+
34+
```http
35+
POST https://<your-subdomain>.kinde.com/oauth2/token
36+
```
37+
38+
### Required parameters
39+
40+
The request body must include:
41+
42+
```text
43+
grant_type=client_credentials
44+
&client_id=<your-client-id>
45+
&client_secret=<your-client-secret>
46+
&audience=<your-api-audience>
47+
```
48+
49+
If your app has scopes assigned, you can optionally request them:
50+
51+
```text
52+
&scope=read:users write:flags
53+
```
54+
55+
**Note**: The `audience` parameter tells Kinde which API the token is intended for. Use `https://<your-subdomain>.kinde.com/api/v1` when calling Kinde’s management API. If you're protecting your own custom API, the audience should match the identifier you registered for that API in Kinde.
56+
57+
### Example (cURL)
58+
59+
```bash
60+
curl --request POST 'https://your-subdomain.kinde.com/oauth2/token' \
61+
--header 'Content-Type: application/x-www-form-urlencoded' \
62+
--data-urlencode 'grant_type=client_credentials' \
63+
--data-urlencode 'client_id=your-client-id' \
64+
--data-urlencode 'client_secret=your-client-secret' \
65+
--data-urlencode 'audience=your-api-audience' \
66+
--data-urlencode 'scope=read:users write:flags'
67+
```
68+
69+
### Successful response
70+
71+
A successful request returns a JSON response with an access token:
72+
73+
```json
74+
{
75+
"access_token": "<token>",
76+
"token_type": "Bearer",
77+
"expires_in": 3600
78+
}
79+
```
80+
81+
## Use the token
82+
83+
Once you have a token, include it as a Bearer token in the `Authorization` header when making API calls:
84+
85+
```http
86+
Authorization: Bearer <token>
87+
```
88+
89+
## Example usage
90+
91+
Calling a Kinde API:
92+
93+
```bash
94+
curl https://your-subdomain.kinde.com/v1/organizations \
95+
-H "Authorization: Bearer <token>"
96+
```
97+
98+
## Notes
99+
100+
- Access tokens are valid for 1 hour by default.
101+
- The `audience` must match the intended API — tokens are only valid for the audience they’re issued for.
102+
- You can request multiple audiences
103+
- If your M2M app is scoped to an organization, the token will include the `org_code` trusted claim.
104+
- Tokens are JWTs and can be decoded to inspect claims using standard libraries or tools like [Kinde's JWT decoder](https://kinde.com/tools/online-jwt-decoder/).
105+
106+
## Test your M2M app from the Kinde dashboard
107+
108+
You can also generate a token from the UI:
109+
110+
1. Go to your M2M app in Kinde
111+
2. Select the **Test** tab
112+
3. Choose the API you want to test against
113+
4. Select **Generate token**
114+
5. Copy the access token and use it in your API requests
115+
116+
This is useful for debugging or verifying scopes and claims without writing code.

0 commit comments

Comments
 (0)