From 27 September to 1 November 2026, a coding agent ran 184 logged actions on my Cloudflare account: 48 OpenTofu applies and 136 raw API calls, 113 of them cache purges. 23 actions carried one of 13 distinct approval quotes; the other 161 needed none.
Why I handed it over
Until then I made every Cloudflare change by hand. On 27 September a DNS record kept pointing at a server I had already moved away from, for hours. The agent had handed the DNS step to me, and nobody checked back. That evening I gave the agent account-wide tokens.
Does this apply to you?
- One person, a few zones, an agent that already writes your infrastructure code: yes.
- Several people share the account: not as written. You need per-person audit and SSO first.
- You cannot pin a token to one machine’s IP: no; most of the safety rests on that lock.
The guardrails
- Three account-owned tokens, IP-locked to one build server: one only mints tokens, one operates (every account permission except API tokens read and write, billing and account settings write), one reads.
- One wrapper runs OpenTofu and raw API calls, only on that server. Before an apply it also refuses a dirty or unpushed tree, or a
HEADwithout currentorigin/main. - Most of the account is OpenTofu code, changed by pull request: 56 merged PRs from 28 September to 1 November, 44 merged by the agent’s bot account.
- Risky changes need a quote. Any delete except a DNS record, turning a record’s proxy off, security settings such as SSL, TLS and WAF, an update to a resource type the wrapper has not reviewed, and any non-GET API call outside a three-entry allowlist require
--owner-approved "<quote>". The quote goes into a JSON-lines audit log. - A pre-tool hook refuses agent commands that load the operations token directly, and loads of the mint-only token without an approval flag.
- A health job verifies the tokens and runs a drift plan. From 26 October to 2 November it ran 9 times (8 in the nightly 03:00 slot, 1 at 09:28): 7 clean, 2 drift.
What broke
- The token was exposed in argv. The first wrapper passed the token to
curlas an argument./proc/<pid>/cmdlinewas readable by every local user, and 3 CI runner accounts shared that server then (5 now), so the IP lock did not cover them. All three token values were rolled on 28 September in three minutes; Cloudflare’s roll keeps the token id, permissions and IP lock. Since 18 October a hook refuses secrets in argv and/procis mounted withhidepid=invisible. - The IP lock held only IPv4. The server reaches the API over IPv6, so calls failed with error 9109 until the lock got the IPv6 /64.
- 2 of 136 API calls failed: one HTTP 409, one HTTP 400.
The trade-off
Is it safe? Safe enough for one person who reads the audit log; not a set-and-forget setup. The cost is attention: 23 approved actions with 13 distinct quotes in 35 days, all from 13 October on. Risks remain: a token with near-full account rights sits on a shared build server. The hook matches command patterns; it is not a sandbox. The wrapper only checks that a quote exists, so it cannot tell my words from words the agent wrote.
Check your own agent’s log
Over a JSON-lines log, two jq lines show what the agent did and what claims approval. My log, as of 2 November 2026 06:36 +07:
$ jq -r '.action // "apply"' cloudflare-applied.json | sort | uniq -c
136 api
48 apply
$ jq -c 'select(.owner_approved)' cloudflare-applied.json | wc -l
23
Then match each approved quote to a message you actually sent.