chore(secrets): rotate cloudflare_api_token to scoped Workers-Edit token#17
Merged
cooper (czxtm) merged 1 commit intomainfrom Apr 29, 2026
Merged
Conversation
Replace the old `cfat_KJ57…` token (which lacked Workers Scripts:Edit and triggered "Unauthorized: Authentication error" 401s during PR-16 web/docs Worker deploys) with the new `cfut_…` token issued with the scopes required by the Cloudflare Worker provider: Workers Scripts:Edit, Workers Routes:Edit, Account Settings:Read, plus the standard Workers KV / R2 / Secrets Store edit groups so future Cloudflare.state() bootstrapping works for staging/prod. Read via `himitsu read cloudflare-api-token`; encrypted into .stack/secrets/vars/shared.sops.yaml under the same key, so loadDeployEnv → @gen/env automatically picks it up at runtime without any code change.
PR SummaryMedium Risk Overview No application code changes; this is a credentials rotation intended to restore/maintain Cloudflare API access for deployment automation. Reviewed by Cursor Bugbot for commit 2d1d1db. Configure here. |
cooper (czxtm)
added a commit
that referenced
this pull request
Apr 29, 2026
PR #17 rotated the Cloudflare API token in `.stack/secrets/vars/shared.sops.yaml` but did not regenerate the codegen-emitted runtime payload at `packages/gen/env/src/runtime/generated-payloads/_envs/deploy.ts`. The embedded JSON is what `loaders.deploy()` actually decrypts at runtime, so both `main` and this branch have continued shipping the old `cfat_KJ57…` token (which lacks `Workers Scripts: Edit`) into CI — explaining why every post-rotation deploy still fails with `Unauthorized: Authentication error` despite the underlying SOPS YAML being correct. Re-running the devshell hook on this branch regenerates both the encrypted data file and the TypeScript module from the (already-rotated) source YAML. Decrypting the regenerated payload yields `cfut_A8wV…` (verified locally) and the `curl` probe earlier confirmed that token has full read+write scopes for `workers/scripts`, `workers/subdomain`, `kv/namespaces`, `zones/.../workers/routes`, and `workers/domains` — i.e. exactly what `Cloudflare.Worker` needs. Plaintext for every other secret in the payload is unchanged; only IVs and ciphertext rotated as a side effect of SOPS re-encrypting the whole file. Follow-up (separate change): `chore: rekey`-style flows and the source SOPS edit path should both trigger codegen so this drift can't happen silently again. Filing as a beads issue.
cooper (czxtm)
added a commit
that referenced
this pull request
Apr 29, 2026
PR #17 rotated the Cloudflare API token in `.stack/secrets/vars/shared.sops.yaml` but did not regenerate the codegen-emitted runtime payload at `packages/gen/env/src/runtime/generated-payloads/_envs/deploy.ts`. The embedded JSON is what `loaders.deploy()` actually decrypts at runtime, so both `main` and this branch have continued shipping the old `cfat_KJ57…` token (which lacks `Workers Scripts: Edit`) into CI — explaining why every post-rotation deploy still fails with `Unauthorized: Authentication error` despite the underlying SOPS YAML being correct. Re-running the devshell hook on this branch regenerates both the encrypted data file and the TypeScript module from the (already-rotated) source YAML. Decrypting the regenerated payload yields `cfut_A8wV…` (verified locally) and the `curl` probe earlier confirmed that token has full read+write scopes for `workers/scripts`, `workers/subdomain`, `kv/namespaces`, `zones/.../workers/routes`, and `workers/domains` — i.e. exactly what `Cloudflare.Worker` needs. Plaintext for every other secret in the payload is unchanged; only IVs and ciphertext rotated as a side effect of SOPS re-encrypting the whole file. Follow-up (separate change): `chore: rekey`-style flows and the source SOPS edit path should both trigger codegen so this drift can't happen silently again. Filing as a beads issue.
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Rotate the SOPS-stored
cloudflare_api_tokenfromcfat_KJ57…to the newcfut_A8wV…token issued with the scopes the Cloudflare provider in alchemy v2 actually needs (Workers Scripts:Edit, Workers Routes:Edit, Account Settings:Read, plus the standard KV / R2 / Secrets-Store edit groups).This commit was authored on the PR #16 branch but PR #16 was merged before it landed, so
mainis still using the old token. The post-merge production deploys ofDeploy WebandDeploy Docsare 401-ing because the old token lacksWorkers Scripts:Read/Edit(the symptom that originally surfaced during PR #16 preview deploys).Token value pulled from the user's local store via
himitsu read cloudflare-api-tokenand written viasops set --value-stdinso the encryption/recipient set is preserved (thechore: rekeycommit on main is fully compatible).No code change.
loadDeployEnv→@gen/envreads the new value from SOPS at runtime, so the next push tomainpicks it up.Test plan
Deploy Web(production) reaches resource creation past the Cloudflare auth checkDeploy Docs(production) reaches resource creation past the Cloudflare auth checklocalState(), no Cloudflare token needed for state)