From c5e0c703c45d35a4783fe4acb9cd6be1e8548f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Zapf?= Date: Mon, 21 Sep 2026 13:33:02 +0000 Subject: [PATCH 1/2] Document permission group IDs in API token template URLs --- .../how-to/account-owned-token-template.mdx | 67 ++++++++++++++++--- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/src/content/docs/fundamentals/api/how-to/account-owned-token-template.mdx b/src/content/docs/fundamentals/api/how-to/account-owned-token-template.mdx index 09d503c6a42..4fc524e0ac6 100644 --- a/src/content/docs/fundamentals/api/how-to/account-owned-token-template.mdx +++ b/src/content/docs/fundamentals/api/how-to/account-owned-token-template.mdx @@ -1,7 +1,7 @@ --- title: API token template URLs description: Generate Cloudflare API tokens with pre-configured permissions using template URLs. Learn how to create and customize template URLs for any use case. -lastUpdated: 2025-01-14 +lastUpdated: 2026-09-21 products: - fundamentals - api @@ -65,12 +65,18 @@ Account token template URLs do not use `accountId` or `zoneId` parameters. Resou ## Permission format -Both user token and account token template URLs use the same permission encoding. Permissions are encoded as a JSON array with the following structure: +Both user token and account token template URLs use the same permission encoding: a JSON array with the following structure. ```json [{ "key": "permission_name", "type": "read|edit|revoke|run|purge" }] ``` +The two token types resolve these entries differently, as described below. + +For **account token URLs**, each `key` can be either a short permission key (for example, `dns`) or a [permission group ID](#use-permission-group-ids). Using the permission group ID is the most reliable option, since it maps to exactly one group. See [Use permission group IDs](#use-permission-group-ids). + +For **user token URLs**, each `key` must be a short permission key that matches a group `name` exactly, and the `type` must be `edit` (not `write`), `read`, `revoke`, `run`, or `purge`. Permission group IDs are not supported, and any entry that does not match is dropped silently. + ### Permission types | Type | Description | @@ -81,6 +87,47 @@ Both user token and account token template URLs use the same permission encoding | `run` | Execute permissions | | `purge` | Purge permissions | +## Use permission group IDs + +:::note + +Permission group IDs are supported in **account token URLs** only. User token URLs must use short keys. + +::: + +To address any permission group in an account token URL, including groups that do not have a short key in the [permission reference](#permission-reference), use its permission group ID as the `key`: + +```json +[{ "key": "82e64a83756745bbbb1c9c2701bf816b", "type": "edit" }] +``` + +Permission group IDs are the stable, canonical identifier for a permission group. They are the same IDs accepted by the [Create token](/api/resources/user/subresources/tokens/methods/create/) endpoint and the Cloudflare Terraform provider, so a template URL can pre-select any permission group by ID. Because the ID names one specific group, the `type` field is ignored when you pass an ID. + +Combine multiple IDs in the same array, just as you would with short keys: + +```json +[ + { "key": "e086da7e2179491d91ee5f35b3ca210a", "type": "edit" }, + { "key": "7cf72faf220841aabcfdfab81c43c4f6", "type": "read" } +] +``` + +Because account token URLs create account-owned tokens, look up their permission group IDs with the **account-scoped** [List permission groups](/api/resources/accounts/subresources/tokens/subresources/permission_groups/methods/list/) endpoint. The request needs a token with the `API Tokens Read` account permission: + +```bash +curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/tokens/permission_groups" \ + --header "Authorization: Bearer " +``` + +For user tokens, use the [user-scoped endpoint](/api/resources/user/subresources/tokens/subresources/permission_groups/methods/list/) instead, which returns the permission groups available to user tokens: + +```bash +curl "https://api.cloudflare.com/client/v4/user/tokens/permission_groups" \ + --header "Authorization: Bearer " +``` + +Each result includes the permission group `id` and `name`. The [API token permissions](/fundamentals/api/reference/permissions/) reference also lists these IDs. + ## Create custom templates ### 1. Identify required permissions @@ -256,12 +303,16 @@ Follow these guidelines when creating and sharing template URLs. Review the list of common issues and solutions. -| Issue | Solution | -| --------------------------------- | --------------------------------------------------------- | -| URL does not pre-fill permissions | Verify the JSON is properly URL-encoded | -| Permissions are missing | Check permission keys in the reference table | -| Token name does not appear | Ensure the name parameter is URL-encoded | -| Access denied error | Verify the user has required permissions in their account | +| Issue | Solution | +| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| URL does not pre-fill permissions | Verify the JSON is properly URL-encoded | +| Permissions are missing | Check permission keys against the reference table, or address the group by its [permission group ID](#use-permission-group-ids) | +| Token name does not appear | Ensure the name parameter is URL-encoded | +| Access denied error | Verify the user has required permissions in their account | + +For **account token URLs**, when a template URL contains a key that cannot be resolved, or the `permissionGroupKeys` value is not valid JSON, the dashboard still opens the token creation form with whatever it could resolve and shows a notice naming the keys it could not apply. It does not redirect back to the token list, so a mistyped key surfaces in the form instead of failing silently. + +For **user token URLs**, unresolved entries are dropped silently and no notice is shown, so verify each key against the [permission reference](#permission-reference) before sharing the URL. Additionally, review the checklist before sharing a template URL. From 22a77d36bba7c7d494c059748b523b038bd894cc Mon Sep 17 00:00:00 2001 From: "bonk[bot]" Date: Thu, 24 Sep 2026 16:35:33 +0200 Subject: [PATCH 2/2] docs: address style guide review findings on token template page Replace directional "below" with a direct reference and use "refer to" instead of "see" before a link, per the documentation style guide. --- .../fundamentals/api/how-to/account-owned-token-template.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content/docs/fundamentals/api/how-to/account-owned-token-template.mdx b/src/content/docs/fundamentals/api/how-to/account-owned-token-template.mdx index 4fc524e0ac6..62473c751e0 100644 --- a/src/content/docs/fundamentals/api/how-to/account-owned-token-template.mdx +++ b/src/content/docs/fundamentals/api/how-to/account-owned-token-template.mdx @@ -71,9 +71,9 @@ Both user token and account token template URLs use the same permission encoding [{ "key": "permission_name", "type": "read|edit|revoke|run|purge" }] ``` -The two token types resolve these entries differently, as described below. +The two token types resolve these entries differently, as described in the following sections. -For **account token URLs**, each `key` can be either a short permission key (for example, `dns`) or a [permission group ID](#use-permission-group-ids). Using the permission group ID is the most reliable option, since it maps to exactly one group. See [Use permission group IDs](#use-permission-group-ids). +For **account token URLs**, each `key` can be either a short permission key (for example, `dns`) or a [permission group ID](#use-permission-group-ids). Using the permission group ID is the most reliable option, since it maps to exactly one group. Refer to [Use permission group IDs](#use-permission-group-ids). For **user token URLs**, each `key` must be a short permission key that matches a group `name` exactly, and the `type` must be `edit` (not `write`), `read`, `revoke`, `run`, or `purge`. Permission group IDs are not supported, and any entry that does not match is dropped silently.