惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
Lohrmann on Cybersecurity
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Azure Blog
Microsoft Azure Blog
G
Google Developers Blog
TaoSecurity Blog
TaoSecurity Blog
博客园_首页
Vercel News
Vercel News
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
The Exploit Database - CXSecurity.com
量子位
Project Zero
Project Zero
A
Arctic Wolf
小众软件
小众软件
NISL@THU
NISL@THU
C
CERT Recently Published Vulnerability Notes
有赞技术团队
有赞技术团队
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Troy Hunt's Blog
P
Privacy & Cybersecurity Law Blog
Security Latest
Security Latest
B
Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
D
DataBreaches.Net
Schneier on Security
Schneier on Security
The Hacker News
The Hacker News
K
Kaspersky official blog
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Webroot Blog
Webroot Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
人人都是产品经理
人人都是产品经理
AI
AI
Cisco Talos Blog
Cisco Talos Blog
MyScale Blog
MyScale Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
S
Schneier on Security
P
Palo Alto Networks Blog

Flavio Copes

Workers Cache: a cache in front of your Cloudflare Worker Cloudflare Drop: drag a folder, get a live site Temporary Cloudflare accounts: agents can now deploy without signing up Moondream 3.1 on Workers AI: fast vision at the edge inferencecost.dev: what will AI inference cost you at 10k users? Sitebase: all the features your website needs, in one place StackPlan: figure out where to deploy your app, and what it How the Cloudflare Pages build cache works The Summer of Code How I generate an Open Graph image for every post New: 90 free tools for developers How I added search to my static site with Pagefind How to rebuild a Cloudflare site on a schedule Cloudflare Email Workers: run code when an email arrives Cloudflare Turnstile: stop bots without annoying CAPTCHAs Cloudflare Workers observability: logs and traces Cloudflare Analytics Engine: store and query metrics The AI Workshop (July 2026 cohort) Cloudflare Cron Triggers: run a Worker on a schedule Cloudflare Durable Objects: state that lives in one place Cloudflare Queues: run work in the background Cloudflare R2: object storage without egress fees Cloudflare KV: a key-value store for your Workers Cloudflare D1: a SQL database for your Workers Serving a website with Cloudflare Workers static assets Wrangler: the Cloudflare Workers command line tool Executor: one gateway to connect your AI agent to every tool Cloudflare Workers: your first serverless function Vercel eve: an open framework for building AI agents Flue: the open framework for building AI agents Val Town: write and deploy code in seconds A hands-on guide to The Agency, a collection of AI agents The AI Workshop (June 2026 cohort) The AI Workshop (May 2026 cohort) The AI Workshop (Apr 2026 cohort)
Cloudflare Workers: secrets and environments
Flavio Copes · 2026-07-01 · via Flavio Copes

By Flavio Copes

How to handle config, secrets, and multiple environments (staging, production) in Cloudflare Workers without leaking anything.

~~~

Every real app has two kinds of config: stuff that’s fine to see, and stuff that must stay secret. And most apps run in more than one place: production, and at least a staging copy to test on.

Cloudflare Workers handle both cleanly. Let me walk through how I set it up.

Plain variables

For config that isn’t sensitive, like a feature flag or your app’s public URL, use vars in wrangler.jsonc:

{
  "vars": {
    "APP_URL": "https://myapp.com",
    "DEBUG_LOG": "0"
  }
}

These show up on env in your Worker:

export default {
  async fetch(request, env) {
    return new Response(env.APP_URL)
  },
}

These live in your config file, in your repo. So only put things here that you’re fine with the world seeing.

Secrets

API keys, tokens, signing keys: these must never go in your repo. They’re secrets, and you set them with Wrangler:

npx wrangler secret put STRIPE_KEY

It prompts you for the value, encrypts it, and stores it on Cloudflare. It’s not written to any file. In your code, a secret looks exactly like a var:

const key = env.STRIPE_KEY

The difference is where it lives. Vars are in your config; secrets are encrypted on Cloudflare and never in your repo.

Secrets in local development

When you run wrangler dev, you still need those secrets, but you obviously don’t want the real production ones on your laptop.

Put local values in a file called .dev.vars:

STRIPE_KEY=sk_test_local_key

Wrangler loads it automatically in dev. Add .dev.vars to your .gitignore so it never gets committed.

Multiple environments

Now the environments. You define named environments in your config, each with its own settings:

{
  "name": "myapp",
  "vars": { "APP_ENV": "dev" },
  "env": {
    "staging": {
      "name": "myapp-staging",
      "vars": { "APP_ENV": "staging" }
    },
    "production": {
      "name": "myapp-prod",
      "vars": { "APP_ENV": "production" }
    }
  }
}

Deploy a specific one with --env:

npx wrangler deploy --env production

Each environment is a separate Worker with its own name, its own URL, its own secrets. Set a secret for just production:

npx wrangler secret put STRIPE_KEY --env production

So staging can use test keys and production uses live ones, with no chance of mixing them up.

The gotcha that gets everyone

Here’s the one that cost me time, so learn it from me.

Environment blocks do not inherit the top-level config. If you put triggers, vars, or bindings at the top level, your named environments do not get them automatically. You have to repeat them inside each environment.

So if you have a cron trigger at the top level and a production environment, production won’t run the cron unless you also add the trigger inside the production block.

It feels wrong the first time, but it’s deliberate: every environment is fully explicit, so nothing leaks across by accident. When you add a binding, remember to add it to each environment that needs it.

The setup I use

Three environments: a local dev one, a staging copy that mirrors production, and production. Public config in vars, anything sensitive as a secret, local values in .dev.vars.

It’s a little boilerplate to repeat bindings per environment, but the payoff is that production and staging can never accidentally share a database or a key. The full reference is in the secrets docs and the environments docs.

~~~

Related posts about cloudflare: