1---
2title: cloudflare
3description: Cloudflare provider commands — bootstrap the state-store worker, mint API tokens, and inspect state-store logs.
4---
5
6import Terminal from "../../../components/Terminal.astro";
7
8```sh
9alchemy provider cloudflare <subcommand> [options]
10```
11
12Cloud-provider commands for Cloudflare — managing the state-store
13worker that backs `Cloudflare.state(...)`, and inspecting its logs.
14
15## `provider cloudflare bootstrap`
16
17```sh
18alchemy provider cloudflare bootstrap [options]
19```
20
21Manually deploy (or repair) the Cloudflare-hosted HTTP State Store —
22the worker + Secrets Store + auth-token secret that back the
23remote-state layer used by `Cloudflare.state(...)`.
24
25You normally don't need to run this: the very first stack deploy
26that uses `Cloudflare.state(...)` will prompt you to bootstrap
27automatically. Use this command to re-run that flow on demand —
28typically to recover from a previous deploy that was interrupted
29mid-bootstrap.
30
31| Option | Description |
32| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
33| `--profile <name>` | Alchemy auth profile (defaults to `$ALCHEMY_PROFILE` or `default`). Determines which `~/.alchemy/profiles.json` entry is used. |
34| `--force` | Force a full redeploy even if the worker already exists. Without this flag, an existing worker is **adopted** and only its credentials are refreshed. |
35| `--worker-name <name>` | Override the default state-store worker name. Advanced; only needed if you run multiple state stores per Cloudflare account. |
36| `--env-file <path>` | Load environment variables from a file |
37
38The bootstrap is idempotent and self-healing:
39
40- An existing worker is **adopted** — its auth token is re-fetched live and `~/.alchemy/credentials/<profile>/cloudflare-state-store.json` is rewritten with the current token.
41- A partial failure resumes from the leftover local state stack; the bootstrap only completes once local state has been hoisted into the remote store.
42- `--force` redeploys unconditionally, but still reconciles existing resources (worker, Secrets Store, secret) in place rather than replacing them.
43
44```sh
45# First-time bootstrap (or repair after a failed deploy)
46alchemy provider cloudflare bootstrap
47
48# Bootstrap a separate profile
49alchemy provider cloudflare bootstrap --profile staging
50
51# Force a full redeploy (e.g. to roll out an updated state-store worker)
52alchemy provider cloudflare bootstrap --force
53```
54
55## `provider cloudflare teardown`
56
57```sh
58alchemy provider cloudflare teardown [options]
59```
60
61Tear down the state-store Worker and its backing resources. It accepts
62`--profile`, `--worker-name`, and `--env-file`, plus `--yes` to skip the
63destructive confirmation.
64
65## `provider cloudflare token`
66
67```sh
68alchemy provider cloudflare token [options]
69```
70
71Mint a Cloudflare API token (`POST /user/tokens`) from the CLI. Useful
72for creating the `CLOUDFLARE_API_TOKEN` you hand to CI, or a broad local
73token for `alchemy deploy`. You'll be pointed to
74[your Cloudflare profile](https://dash.cloudflare.com/profile/api-tokens)
75once to grab your Global API Key (unless it's already in the environment);
76everything else happens in the terminal.
77
78This command is **standalone** — it takes no `--profile` and does not
79use an Alchemy auth profile. Cloudflare only mints a token whose
80permissions the authenticating credential is allowed to grant, and
81OAuth/scoped tokens silently produce a token with **zero** permissions.
82So this command always authenticates with your account's **Global API
83Key**, read from `CLOUDFLARE_API_KEY` / `CLOUDFLARE_EMAIL` (or
84prompted). The key is used only to create the token and is never stored.
85
86By default you pick permission groups from an interactive multi-select,
87resolved live from your account — restricted to the three scopes that
88can actually become a token policy (account, zone, r2). Pass
89`--all-permissions` for a "superuser" token spanning **every** permission
90group your account exposes (after a confirmation prompt).
91
92<Terminal content={`◇ Select a Cloudflare account
93│ My Account
94│
95◇ Token name
96│ alchemy-superuser
97│
98◇ Create a superuser token with all permissions?
99│ Yes
100
101Created Cloudflare API token "alchemy-superuser" (7cb070fe...).
102Granted 360 permission group(s) across 3 policy(ies); token status: active.
103
104cfut_pMtBzTOGHWyFC2RSNvfw8f7p2cc...
105
106Store this value now — Cloudflare only shows it once. Use it as CLOUDFLARE_API_TOKEN.`} />
107
108| Option | Description |
109| ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
110| `--all-permissions` | Grant every Cloudflare permission group (a "superuser" token). Prompts for confirmation. |
111| `--name <name>` | Token name. Prompted (required) if omitted. |
112| `--account-id <id>` | Account ID(s) to scope the token to — comma-separated for multiple. If omitted, you'll be prompted with a multi-select spanning your accounts. |
113| `--env-file <path>` | Load environment variables (e.g. `CLOUDFLARE_API_KEY`, `CLOUDFLARE_EMAIL`) from a file |
114
115The permission groups are resolved **live** from your account (so the
116token always uses IDs valid for that account), and the freshly minted
117token is verified against `/user/tokens/verify` before the value is
118printed.
119
120If the result reports `Granted 0 permission group(s)`, the token is
121useless: a token can only carry permissions the authenticating user
122already holds, so this usually means the Global API Key's user is not
123a Super Administrator on the selected account. Check the user's role
124under Members in the Cloudflare dashboard and retry.
125
126:::note
127The Cloudflare dashboard has a long-standing rendering bug where
128API-created tokens show a **blank** permission summary (and a greyed-out
129"View") on first load. The permissions are applied regardless — the
130`Granted N permission group(s)` line and `token status: active` confirm
131it. To see them in the UI, open the token and click "← Edit token".
132:::
133
134```sh
135# Pick permission groups interactively for a typical Alchemy deploy token
136alchemy provider cloudflare token --name ci-token
137
138# Full-access "superuser" token
139alchemy provider cloudflare token --all-permissions --name admin
140
141# Non-interactive: key/email from the environment, explicit account
142CLOUDFLARE_API_KEY=... CLOUDFLARE_EMAIL=you@example.com \
143 alchemy provider cloudflare token --name ci --account-id <account-id>
144```
145
146## `provider cloudflare state logs`
147
148```sh
149alchemy provider cloudflare state logs [options]
150```
151
152Get or tail logs from the `alchemy-state-store` Worker on your
153Cloudflare account. Talks directly to the Workers Observability
154Telemetry API — no stack file required — so you can debug the
155state-store itself.
156
157Requires `workers_observability:read` and
158`workers_observability_telemetry:write` OAuth scopes (included in the
159default scope set; existing profiles need to re-run
160`alchemy profile edit --reconfigure Cloudflare` to pick them up).
161
162| Option | Description |
163| ---------------------- | ------------------------------------------------------------------------------------------------------------ |
164| `--tail`, `-t` | Stream logs in real time via the Cloudflare tail websocket instead of fetching past entries |
165| `--limit <n>` | Number of log entries to fetch (default: 100). Ignored with `--tail`. |
166| `--since <time>` | Fetch logs since this time — a duration (`1h`, `30m`, `2d`) or ISO date |
167| `--worker-name <name>` | Override the default state-store worker name. Only needed if you run multiple state stores per account. |
168| `--profile <name>` | Alchemy auth profile (defaults to `$ALCHEMY_PROFILE` or `default`) |
169| `--env-file <path>` | Load environment variables from a file |
170
171```sh
172# Last hour of state-store logs
173alchemy provider cloudflare state logs
174
175# Stream live in a separate terminal while you reproduce a bug
176alchemy provider cloudflare state logs --tail
177
178# Just the last 30 minutes
179alchemy provider cloudflare state logs --since 30m --limit 200
180```
181
182## Where next
183
184- [aws](/cli/aws) — provider commands for AWS
185- [Inspecting State](/cli/inspecting-state) — read and manage the state store from the CLI
186- [State Store](/state-store) — where resource state lives
187- [Cloudflare](/cloudflare) — the Cloudflare provider hub