You need: a scaffolded project.
The line
Secrets is where a value goes when it must not be a var, the config directory is where dev copies live, pithy env reports what resolved, and rotating a secret is the maintenance.
A var is a value you would put in a screenshot. A secret is one you would not.
| Where | |
|---|---|
BASE_URL, ENVIRONMENT, PROJECT, WORKER | Vars, in wrangler.jsonc |
| A public sitekey | A var — the front end renders with it |
| An API key, a signing key, an OAuth client secret | Secrets |
.dev.vars is generated, not authored
It is generated from your machine-local secrets file, which lives at <config>/<project>/secrets.jsonc — outside every checkout, mode 0600.
Nothing to gitignore. Nothing git add -A can reach. Delete the whole clone and the values are still there.
pithy secrets edit opens it
pithy doctor tells you the pathGeneration is idempotent by content, so a run that changes nothing writes no bytes.
Four vars the kit stamps and reads
| Var | Read by |
|---|---|
PROJECT | The audit recorder |
ENVIRONMENT | The audit recorder, and the Turnstile test-key exception |
WORKER | The audit recorder — the only thing that tells two Workers’ events apart |
BASE_URL | Written by pithy worker sync from your domains block |
An emitter cannot set the first three. Origin is a property of the writer, not of the action — and a route that could claim to be another environment would make the column worth nothing precisely when it mattered.
All three are nullable, permanently. A Worker scaffolded before they existed carries none, a CLI action came from no Worker, and no historical row can be back-filled. null means not recorded.
Per-environment values
Every var lives in its environment’s stanza. pithy worker sync writes the ones derived from your config — the route and the BASE_URL a domains block implies — for every environment it declares.
That is the only non-interactive way to get the route written. A domains block added by hand and never synced declares an address nothing serves.
Do not build a URL from a literal
// wrong
const successUrl = "https://acme.com/thanks";An origin written down is production’s origin written into staging — which lands a staging payer in production on an account that has bought nothing.
Build it from BASE_URL, or from the constant the scaffolded config derives from domains.
Reading a var
c.env.MY_VARValidate it if anything depends on its shape. A var is a string somebody typed into a JSON file, and a Worker that assumes otherwise fails at the first request rather than at boot.
What never goes in a var
No secret. No credential. No token.
If it is in wrangler.jsonc it is in your repository, in every clone, in every CI log that echoes a config, and in the deploy output.
And no secret value is ever printed by any pithy command — not by provision, not by rotate, not by doctor. That is a property of the kit worth not undermining with a var.