How to Create a Cloudflare API Token with Least Privilege
Create a scoped Cloudflare API token in 5 steps — not the Global API Key — per-zone permissions. Ringtail mints it from Cloudflare's official API, value-free.

Rocco walked past the Global API Key like it was a trap. It kind of is. He took a scoped token instead.

🦝 Rocco: the global key can do everything. that's the problem. i want a token that can do one thing.
To create a Cloudflare API token, sign in at dash.cloudflare.com, open My Profile → API Tokens, click Create Token, choose a template or Create Custom Token, set the exact permissions and zone resources you need, optionally add IP filtering and a TTL, then copy the token once. Use a scoped API token, never the account-wide Global API Key. Below is the full flow, the least-privilege choices, and how Ringtail mints the scoped token from Cloudflare's official API without exposing the value to your coding agent.
Where do you create a Cloudflare API token?
You create it at dash.cloudflare.com under My Profile → API Tokens (the profile menu is top-right). This is where scoped, permission-limited tokens live — distinct from the legacy Global API Key, which sits on the same page but grants full access to your entire account.
Reach for a scoped token every time. The Global API Key can read and modify every zone, every DNS record, billing, and account settings; if it leaks, the whole account is exposed. A scoped token does exactly what you granted and nothing else, which is the entire point of least-privilege API key provisioning.
What are the steps to create a scoped token?
Five steps:
- Go to My Profile → API Tokens and click Create Token.
- Pick a template (for example Edit zone DNS) or click Create Custom Token for full control.
- Under Permissions, add each permission group you need — for example
Zone · DNS · Edit. Add only what the job requires. - Under Zone Resources, narrow from "All zones" to the specific zone this token should touch. Do the same for Account Resources if the permission is account-level.
- Optionally set Client IP Address Filtering (limit to your CI runner's egress IPs) and a TTL (an expiry date). Click Continue to summary, then Create Token, and copy the value — Cloudflare shows it once.
Store it as CLOUDFLARE_API_TOKEN in .env.local, never committed. If keeping secrets out of your repo is new territory, stop committing secrets to git has the practical steps.
How do you scope it to least privilege?
Grant the narrowest permission on the narrowest resource. A token that only edits DNS for one zone should have:
- Permissions:
Zone · DNS · Edit— and nothing else. - Zone Resources:
Include · Specific zone · acme.com— not "All zones." - Client IP filtering: your CI egress range, so a stolen token is useless off your network.
- TTL: an expiry that forces rotation.
Compare that to the Global API Key, which is all-permissions on all-resources with no IP filter and no expiry. The scoped token is a small blast radius; the Global Key is your whole account. For CI specifically, pair this with a similarly narrow deploy token — the same discipline applies to getting a Vercel API token for CI.

🦝 Rocco: include one zone, edit dns, expire in 90 days. a leaked token that can barely do anything is a good day.
How do you verify and use the token?
Verify it against Cloudflare's official verify endpoint before wiring it into anything:
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN"
A "status": "active" response means the token is live and its scope is intact. In code, read it from the environment and pass it as a Bearer token — never inline the string. Wrangler and the Cloudflare SDKs both read CLOUDFLARE_API_TOKEN from the environment automatically.
How does Ringtail create the token for you?
Once you've connected your Cloudflare account to Ringtail one time, Ringtail mints the scoped token for you by driving Cloudflare's official API — you never hand-build another permission list. Ringtail reads CLOUDFLARE_API_TOKEN from your .env.example, calls Cloudflare's token API to create a token with the least-privilege permissions and single-zone resource your project needs, verifies it against the same /tokens/verify endpoint, and writes the value into .env.local and your Infisical.
It's value-free: the token string is returned by Cloudflare's API straight into your local files. Your coding agent decides which permissions to request and which zone to bind, but never sees the secret value. Install it once:
curl -fsSL ringtail.sh | sh
ringtail up
Ringtail uses official provider APIs only — never a browser bot with your login. Cloudflare's token API is first-class, so after the one-time connection the whole thing is zero-touch. For provisioning every key in a project this way, see how to stop juggling 15 API keys on every new project.
FAQ
What's the difference between a Cloudflare API token and the Global API Key?
The Global API Key grants full read-write access to your entire Cloudflare account — every zone, DNS record, and setting — and can't be scoped. A scoped API token is limited to the exact permissions and resources you grant it, can be IP-filtered, and can carry an expiry. Use scoped tokens; reserve the Global API Key only for the rare legacy integration that demands it.
How do I scope a Cloudflare API token to one zone?
When creating the token, under Zone Resources change the selector from "All zones" to Include · Specific zone, then choose the single zone the token should manage. Combined with a narrow permission group like Zone · DNS · Edit, the token can only touch DNS for that one domain — a small blast radius if it ever leaks.
How do I test that my Cloudflare token works?
Call Cloudflare's official verify endpoint: curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN". A response with "status": "active" confirms the token is valid and unexpired. This is also how tooling like Ringtail validates a freshly minted token before writing it to your files.
Can Ringtail mint a Cloudflare token without me building the permission list?
Yes. After you connect your Cloudflare account to Ringtail once, Ringtail calls Cloudflare's official token API to create a least-privilege, single-zone token for each project, verifies it, and writes it to .env.local and Infisical — value-free, so the token never reaches your coding agent. It uses the official API only, never browser automation.
