Cloudflare api token permissions
Skill okayus/okayus-skills/skills/cloudflare-api-token-permissions
Agent Skills for Claude Code / agentskills.io-compatible agents. Cloudflare Workers + Discord integration patterns.
npx -y skills add okayus/okayus-skills --skill cloudflare-api-token-permissionsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Map a Cloudflare CI deploy auth error (code 10000 / 7403 / 9106) to the missing API token permission, and show how to extend the token in-place without regenerating its value (so the GitHub Secret stays untouched). Use when `wrangler deploy` or `wrangler d1 migrations apply` fails in GitHub Actions with `Authentication error`, or when adding a new binding (`r2_buckets` / `kv_namespaces` / `queues` / `vectorize` / `hyperdrive`) to `wrangler.jsonc` and the deploy starts failing in CI even though it works locally. Covers the permission matrix per binding, the "Edit Cloudflare Workers" template's silent omission of D1 / R2 / Queues, and the diagnostic flow when multiple permissions are missing.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
9.2 KB, ~2.1k tokens by cl100k_base, as published. Nobody here has run it
Cloudflare API Token Permissions
When wrangler deploy (or wrangler d1 migrations apply) fails in CI with code: 10000, code: 7403, or code: 9106, the cause is almost always: the GitHub Secret CLOUDFLARE_API_TOKEN is missing a permission for a binding or operation that wrangler.jsonc references.
Adding a binding to wrangler.jsonc doesn't fail locally (your wrangler login session has full account access), but CI's narrow API token does. The error surfaces only when CI runs — typically after the PR is already merged.
When to use this skill
- A CI
wrangler deployjob that previously succeeded now fails withAuthentication error [code: 10000]/[code: 7403]/[code: 9106] - You're about to add a binding (
r2_buckets,kv_namespaces,queues,vectorize,hyperdrive,ai,browser) towrangler.jsoncand want to predict whether the token needs an extension - Token rotation: the secret value leaked or expired and needs replacement
- You used the
Edit Cloudflare Workerstemplate to create a token and need to verify what's actually included (it omits D1 / R2 / Queues — see below)
Error code → missing permission
| First error in deploy log | Cloudflare API path that failed | Missing permission |
|---|---|---|
Authentication error [code: 10000] | /accounts/<id>/r2/buckets/<name> | Account / Workers R2 Storage / Edit |
not authorized [code: 7403] | /accounts/<id>/d1/database/<id>/query | Account / D1 / Edit |
Authentication failed [code: 9106] | /memberships | Account / Account Settings / Read (typically a follow-on after the first failure) |
Authentication error [code: 10000] | /accounts/<id>/workers/scripts/<name> | Account / Workers Scripts / Edit |
Authentication error [code: 10000] | /accounts/<id>/storage/kv/namespaces/<id> | Account / Workers KV Storage / Edit |
Authentication error [code: 10000] | /accounts/<id>/queues/<id> | Account / Workers Queues / Edit |
The first error in the log is the actionable one; subsequent errors (especially code: 9106 on /memberships) are usually consequences of the first failed auth call. Fix the first one and the rest disappear.
Permission matrix (binding / command → required permission)
| Binding or wrangler command | Required token permission |
|---|---|
wrangler deploy core (Worker upload) | Account / Workers Scripts / Edit |
wrangler d1 migrations apply --remote | Account / D1 / Edit |
wrangler d1 export --remote (backup) | Account / D1 / Edit (Read may suffice; Edit is the safe pick) |
r2_buckets binding (existence check on deploy) | Account / Workers R2 Storage / Edit |
kv_namespaces binding | Account / Workers KV Storage / Edit |
queues_producers / queues_consumers binding | Account / Workers Queues / Edit |
vectorize binding | Account / Vectorize / Edit |
hyperdrive binding | Account / Hyperdrive / Edit |
ai (Workers AI) binding | Account / Workers AI / Read |
browser (Browser Rendering) binding | Account / Browser Rendering / Edit |
| Memberships lookup (wrangler boilerplate) | Account / Account Settings / Read |
For the typical small-app stack (SPA + API + D1 + R2 served from one Worker), the minimum token permission set is:
Account / Workers Scripts / EditAccount / D1 / EditAccount / Workers R2 Storage / EditAccount / Account Settings / Read- Account Resources:
<your specific account>(don't grant All accounts unless you have a reason)
The "Edit Cloudflare Workers" template trap
Cloudflare offers a one-click template named Edit Cloudflare Workers. It looks complete but silently omits D1, R2, Queues, and Vectorize — these were added to the platform after the template was set, and the template has not been updated.
What the template includes:
Workers Scripts / EditWorkers KV Storage / EditWorkers Tail / ReadWorkers Routes / EditAccount Settings / Read
What you must add manually if your wrangler.jsonc uses them:
D1 / EditWorkers R2 Storage / EditWorkers Queues / EditVectorize / EditHyperdrive / Edit
Recommendation: skip the template. Use Create Custom Token and pick exactly what you need from the matrix above. Faster than auditing the template's gaps.
In-place permission edit (keeps the token value)
A common misconception: editing a Cloudflare API Token's permissions regenerates its value, requiring a GitHub Secret update.
It doesn't. Cloudflare keeps the same token value when you edit permissions; only rotating (deleting + recreating) generates a new value.
Workflow:
- https://dash.cloudflare.com/profile/api-tokens
- Locate the token used by GitHub Actions (sort by Last Used — CI tokens are touched on every
mainpush) - Click Edit (not "Roll")
- Add the missing permission row → Continue to summary → Update Token
- Token value unchanged → no GitHub Secret update needed
- Re-run the failed CI:
gh run rerun <run-id> --failed
Identifying which token is the CI token
If you have multiple tokens in your account and aren't sure which value lives in CLOUDFLARE_API_TOKEN:
- The GitHub Secret value is one-way encrypted — not retrievable
gh secret list -R <owner>/<repo>only shows theupdatedAttimestamp; correlate with the Cloudflare token's Created / Last Used timestamps- Cloudflare dashboard sorts tokens by Last Used. The most-recently-used should be the CI token (Actions runs on every
mainpush) - If you can't tell, rotate: create a fresh token with the full matrix,
gh secret set CLOUDFLARE_API_TOKEN, delete the old one. Avoids a long bisect.
Diagnostic flow when CI deploy fails
gh run view <run-id> --log-failed→ find the first[ERROR] code: <number>line- Look up the code in the Error code → missing permission table above
- Edit the token's permissions in-place (value stays the same)
gh run rerun <run-id> --failed- If a new
code: <different number>appears, repeat from step 2 (cumulative permissions across the deploy stages — e.g. R2 binding check fails first → fix R2 → D1 migrations apply fails next → fix D1) - If the same code persists, check that the token you edited is actually the one in
CLOUDFLARE_API_TOKEN(see Identifying which token is the CI token above) — most common cause of "I added the permission but it still fails"
When you do need to rotate (regenerate)
- The secret value leaked publicly
- Cloudflare flagged the token as compromised
- The token expired (if you set a TTL when creating)
- You can't tell which token the CI uses (rotate to break the ambiguity)
In that case:
- Create a new token with the full permission matrix above (Custom Token, not the template)
- Copy the new value (shown once)
- Update the GitHub Secret:
gh secret set CLOUDFLARE_API_TOKEN -R <owner>/<repo>and paste the value - Delete the old token in the Cloudflare dashboard (avoids accumulation of stale tokens)
- Re-run the failed CI
What this skill does NOT cover
- Local
wrangler loginsession permissions —wrangler loginuses OAuth and grants full account access; it never has the narrow-permission problem. Only CI tokens hit this. - R2 bucket-scoped object access tokens (S3-compatible API): those are a different token type (created under R2 → Manage R2 API Tokens) and unrelated to CI deploy. Workers R2 Storage binding uses the account API token, not the bucket-scoped one.
- Deploying via
wrangler deploy --account-id <id>instead of via secret: same permission requirements, just authenticated differently.
Related skills
cloudflare-workers-deploy-skeleton— initial project setup. The token created during that skill should already follow this matrix from day 1; consult this skill when adding new bindings later.cloudflare-d1-drizzle-migration— D1 migration pitfalls (PRAGMA foreign_keys=OFFignored). NeedsD1 / Edit.cloudflare-d1-weekly-backup-via-pr— weekly D1 backup workflow. Reuses the sameCLOUDFLARE_API_TOKEN(no new token needed if the matrix is met).