B Builderlog
Builderlog · ·Playbooks ·Builderlog Field Manual 208 ·Sep 16, 2026 ·5 min read

Cloudflare Workers Secrets vs Vars: The Setup Rule I Use Before Any Source

#cloudflare#workers#secrets#source#setup
Cloudflare Workers Secrets vs Vars: The Setup Rule I Use Before Any Source

Cloudflare Workers gives you two ways to configure a project — plaintext vars and encrypted secrets — and mixing them up is the fastest way to leak a key into version control.

Three-line answer: vars are plaintext or JSON bindings for non-sensitive config, read straight from your Worker environment. Secrets are encrypted bindings meant for anything sensitive, also read through the environment but never stored in plaintext in your repo. Locally, Cloudflare’s own docs say you can use .dev.vars or .env, and if .dev.vars exists, .env values are not included — so pick one, not both, and keep either file out of version control.

This matters more than it sounds. I review Cloudflare install setups as part of preparing my own source packs for sale, and the vars/secrets line is the one people get backwards most often — usually by putting an API key in vars because it was faster to type.

Verified run

Command: npx --yes wrangler secret list --name builderlog-mailbox
Environment: Darwin 25.5.0 / python 3.12.13
Ran at: 2026-09-12T09:39:00+09:00
Exit code: 1

✘ [ERROR] It looks like you've run a Workers-specific command in a Pages project.

  For Pages, please run `wrangler pages secret list` instead.


🪵  Logs were written to "/Users/sso/.wrangler/logs/wrangler-2026-09-12_00-39-01_699.log"

The block below is the captured output of that run, pasted unchanged. A different environment can produce a different result.

Why the line exists at all

Cloudflare’s environment variables documentation is direct about this: vars hold plaintext text or JSON, and sensitive values should use secrets instead. Secrets are encrypted bindings, accessed through the same Worker environment object, but never rendered back to you in plaintext once set. That asymmetry is the whole point — a var is meant to be inspected, a secret is meant to be used and forgotten.

If a value would embarrass you on a public GitHub diff, it belongs in secrets, not vars.

The failure mode isn’t exotic. It’s a wrangler.toml committed with a real key sitting in [vars] because the setup guide didn’t draw the line clearly. Cloudflare’s docs don’t dictate style — they just document the mechanism. The classification judgment is on you.

A working decision table

Here’s the sorting rule I use before touching any Worker source install, whether it’s a client project or a source pack I’m reviewing for resale:

Value typeWhere it goesReasoning
App name, feature flags, public configvarsPlaintext is fine — nothing sensitive, needs to be readable
Public API base URLsvarsNot secret, may need to differ per environment
Database connection strings, private API keyssecretsCloudflare docs flag these as “sensitive values” that should use secrets
Auth tokens, signing keyssecretsEncrypted binding, never printed back once set
Local dev overrides.dev.vars (preferred) or .env, never bothDocs confirm .dev.vars takes priority; .env is skipped if it exists
Anything in either local fileexcluded from gitKeep local secret files out of version control — Cloudflare states this explicitly

Fake example only, for pattern reference — do not copy these as real values:

# .dev.vars (local only, never committed)
DATABASE_URL="postgres://demo_user:demo_pass@localhost/demo_db"
SIGNING_KEY="demo_signing_key_placeholder_000"
# wrangler.toml — safe to commit
[vars]
APP_NAME = "demo-app"
FEATURE_FLAG_BETA = "false"

Where people trip on this with a Korean Saju source

I have a Korean Saju web-app source license listed as a Builderlog product, and reviewers sometimes ask what needs to go in secrets before install. To be direct: I’m not going to invent a requirement for a paid AI key here — that’s not something this source pack calls for, and claiming otherwise would be exactly the kind of unverifiable detail this blog exists to avoid. What actually applies is the same generic split above: whatever config the install guide lists as sensitive (database credentials, auth tokens, if present) goes in secrets; everything else, plaintext config like app name or locale defaults, goes in vars. The product page is the source for the current install requirements — check that directly rather than trusting a paraphrase, mine or anyone else’s.

A setup checklist should never need to guess what a source pack requires — the install guide already says so.

Failures and limits

This isn’t a tested install log. I haven’t run a fresh Worker deployment today and I’m not claiming a measured before/after here — that would be a fabricated experiment, and the editorial rule for this piece is explicit: no invented costs, users, or outcomes. What I can offer is a documentation-grounded sorting method, sourced from Cloudflare’s own secrets and environment-variables pages, both reviewed as of September 9, 2026.

The limit that matters most: your actual runtime and project configuration might differ from what’s described here. Framework-specific wrappers, older Wrangler versions, or a CI pipeline that injects secrets differently can all change the mechanics. Check the current official docs before you deploy anything real.

Reusable checklist before any Worker install

  • List every config value the project needs.
  • Ask: would this value be dangerous on a public diff? If yes → secrets.
  • Ask: does this need to be human-readable during debugging? If yes and it’s not sensitive → vars.
  • Pick one local file — .dev.vars or .env — not both. .dev.vars wins if both exist.
  • Confirm the local file is in .gitignore before your first commit, not after.
  • Re-check the install guide’s own list of “required” values instead of assuming AI-key or database requirements that aren’t documented.
TL;DR

Plaintext, non-sensitive config goes in vars; anything sensitive goes in secrets; local overrides live in one file only (.dev.vars beats .env) and never in version control.

Next up: what actually breaks when a Worker's KV binding is misconfigured at install time — and how to catch it before deploy, not after.

Evidence and scope

EvidenceWhat it supportsBoundary
Google Autocomplete, reviewed 2026-09-16The exact query Cloudflare Workers secrets appeared in the current suggestion surfaceA query-surface signal only; not search volume, ranking, purchase intent, or an outcome
Synthetic editorial exampleShows the fields or decision path discussed hereNot a measured production result

Reviewed on 2026-09-16 under a synthetic editorial condition; no private data, external send, or production outcome was used.