Cloudflare Secrets Manager is a small, scriptable toolkit for managing Cloudflare Workers secrets and plaintext variables without using the Cloudflare dashboard for every change.
It gives you a repeatable workflow for:
- Uploading encrypted Worker secrets from local env files.
- Keeping production and staging secret sets separate.
- Previewing plaintext variables before deploys.
- Deploying Workers with plaintext variables applied through Wrangler.
- Rotating secrets with a local backup of the previous secret listing.
- Running a live example Worker to verify that secret injection works.
The project is intentionally simple: it wraps Wrangler, keeps the behavior visible, and avoids hiding Cloudflare's underlying model.
- When To Use This
- Install And Setup
- Secrets And Plaintext Variables
- Quick Start
- Common Workflows
- Templates
- Command Reference
- Project Layout
- Documentation
- Security Notes
- Troubleshooting
- License
Use this project when you want a checked-in, repeatable workflow around Cloudflare Workers configuration.
It is useful for:
- Teams that want the same commands for local, staging, and production deployments.
- Projects that need many Cloudflare secrets and do not want to enter them one by one.
- Workers that use both encrypted secrets and non-secret config values.
- Developers who want an auditable rotation process.
- Starter Workers that need a known-good secret and plaintext variable setup.
This project is not a hosted secret manager and it does not store secret values remotely. Secret values remain in your local ignored env files until you upload them to Cloudflare with Wrangler.
This project works best as a repository or template because it contains scripts, example config files, and a starter Worker:
git clone https://github.com/nyigoro/cloudflare-secrets-manager.git
cd cloudflare-secrets-manager
npm install
npx wrangler loginThe package is also published on npm:
npm install cloudflare-secrets-managerThe npm package is most useful as a distributable copy of the scripts and examples. For day-to-day use, cloning the repository is usually more convenient because the npm scripts in package.json assume you are working from the project root.
- Node.js with
nodeandnpmavailable. - Wrangler installed locally through
npm install, or available globally aswrangler. - A Cloudflare account with access to the target Worker or Pages project.
- A configured
wrangler.toml,wrangler.json, orwrangler.jsonc. - Bash for the shell helper scripts. On Windows, use Git Bash, WSL, or another Bash-compatible shell for
manage-secrets.shandrotate-secrets.sh.
Cloudflare Workers expose configuration to Worker code through the env object, but not every value should be managed the same way.
Cloudflare uses two dashboard labels for these bindings:
Secretmeans the value is encrypted and hidden after upload.Plaintextmeans the value is a normal Worker variable. Wrangler andwrangler.tomlcall thesevarsor variables.
This project uses the phrase plaintext variables for values that Cloudflare shows as Plaintext.
| Dashboard type | Stored in this project | Uploaded with | Dashboard value display | Intended for |
|---|---|---|---|---|
| Secret | production.env, staging.env |
wrangler secret bulk |
Secret names only | Tokens, API keys, database URLs, JWT secrets |
| Plaintext | production.vars.env, staging.vars.env |
wrangler deploy --var KEY:VALUE |
Values are visible | Public URLs, feature flags, environment names |
Use secrets for anything private. Use plaintext variables only for configuration that can safely be visible to operators and potentially returned by your Worker if your code exposes it.
npm install
npx wrangler loginEdit wrangler.toml:
name = "your-worker-name"
main = "src/index.js"
compatibility_date = "2026-04-23"
[vars]
ENVIRONMENT = "production"
[env.staging]
name = "your-worker-name-staging"
[env.staging.vars]
ENVIRONMENT = "staging"Copy the production template:
cp production.env.example production.envThen replace the placeholders:
MY_SECRET_KEY=replace-with-a-real-secret
DATABASE_URL=postgres://app_user:replace_with_db_secret@host:5432/database
JWT_SECRET=replace-with-a-long-random-valueCopy the staging template:
cp staging.env.example staging.envThen replace the placeholders:
MY_SECRET_KEY=replace-with-a-staging-secret
DATABASE_URL=postgres://app_user:replace_with_db_secret@staging-host:5432/database
JWT_SECRET=replace-with-a-different-long-random-valueThese files are ignored by git.
Copy the examples:
cp production.vars.env.example production.vars.env
cp staging.vars.env.example staging.vars.envExample plaintext variable file:
PUBLIC_APP_NAME=My Production Worker
PUBLIC_API_BASE_URL=https://api.example.com
FEATURE_SIGNUPS_ENABLED=truenpm run show-vars
npm run show-vars:stagingnpm run deploy:dry-run
npm run deploy:dry-run:stagingProduction:
npm run deployStaging:
npm run deploy:stagingnpm run sync-secretsThis uploads values from production.env to the default Worker configured in wrangler.toml.
npm run sync-secrets:stagingThis uploads values from staging.env to the staging Wrangler environment.
npm run show-varsThis prints the plaintext variables that would be applied from production.vars.env.
npm run deploy:dry-runThis runs the deploy wrapper with --dry-run. It is useful before a real release because it shows whether Wrangler accepts the target config and plaintext variables.
For production, the deploy wrapper explicitly targets Wrangler's top-level environment, so configs that also define env.staging do not trigger Wrangler's multiple-environment warning.
Pass additional Wrangler deploy arguments after --:
node scripts/deploy-with-vars.mjs --vars-file production.vars.env -- --minifybash manage-secrets.sh deploy --config path/to/wrangler.toml --env-file production.env --vars-file production.vars.envnpm run rotateThe rotation helper:
- Saves the current secret listing to
.secret-backups/. - Shows which keys will be uploaded from the env file.
- Requires you to type
yes. - Uploads the new values.
- Lists the resulting secret names.
The repository includes a reusable template catalog in templates/:
| Path | Purpose |
|---|---|
production.env.example |
Root production secret template |
staging.env.example |
Root staging secret template |
templates/secrets/ |
Minimal, API, and database secret templates |
templates/variables/ |
Minimal, web API, and feature flag plaintext variable templates |
templates/wrangler/ |
Basic, production/staging, and cron Worker configs |
templates/workers/ |
Starter Worker implementations |
templates/github-actions/ |
GitHub Actions deploy workflow template |
Common copies:
cp templates/secrets/api-worker.env.example production.env
cp templates/variables/web-api.vars.env.example production.vars.env
cp templates/wrangler/production-staging.toml wrangler.toml
cp templates/workers/health-config-worker.js src/index.jsSee Template Catalog and Template Guide for details.
| Command | What it does |
|---|---|
npm run sync-secrets |
Upload production.env secrets to the default Worker |
npm run sync-secrets:staging |
Upload staging.env secrets to the staging Worker |
npm run sync-secrets:pages |
Upload production secrets to Cloudflare Pages |
npm run show-vars |
Print plaintext variables from production.vars.env |
npm run show-vars:staging |
Print plaintext variables from staging.vars.env |
npm run list-secrets |
List production Worker secret names |
npm run list-secrets:staging |
List staging Worker secret names |
npm run list-secrets:pages |
List Cloudflare Pages secret names |
npm run delete-secret -- KEY_NAME |
Delete one production Worker secret |
npm run delete-secret:staging -- KEY_NAME |
Delete one staging Worker secret |
npm run rotate |
Back up and rotate production Worker secrets |
npm run rotate:staging |
Back up and rotate staging Worker secrets |
npm run rotate:pages |
Back up and rotate production Pages secrets |
npm run deploy:dry-run |
Dry-run production deploy with plaintext variables |
npm run deploy:dry-run:staging |
Dry-run staging deploy with plaintext variables |
npm run deploy |
Sync production secrets, then deploy with production plaintext variables |
npm run deploy:staging |
Sync staging secrets, then deploy with staging plaintext variables |
npm run example:sync |
Upload the throwaway live-test secret |
npm run example:list |
List example Worker secret names |
npm run example:deploy |
Sync and deploy the live example Worker |
npm run example:test-live -- <url> <expected> |
Verify the example Worker's runtime secret |
npm run example:delete-live-test |
Delete the example live-test secret |
npm run example:delete-worker |
Delete the example Worker |
cloudflare-secrets-manager/
|-- docs/
| |-- configuration.md
| |-- getting-started.md
| |-- publishing.md
| |-- security.md
| |-- templates.md
| `-- troubleshooting.md
|-- example/
| |-- live-test.env.example
| |-- live-test.mjs
| |-- live-test.sh
| |-- README.md
| |-- src/index.mjs
| `-- wrangler.toml
|-- scripts/
| |-- deploy-with-vars.mjs
| `-- show-vars.mjs
|-- src/index.js
|-- templates/
|-- LICENSE
|-- manage-secrets.sh
|-- package.json
|-- production.env.example
|-- production.vars.env.example
|-- rotate-secrets.sh
|-- staging.env.example
|-- staging.vars.env.example
|-- wrangler.toml
`-- README.md
Read the detailed guides:
- Getting Started
- Configuration Guide
- Publishing And Release Guide
- Security Guide
- Template Guide
- Troubleshooting Guide
- Live Example Worker
- Never commit
production.env,staging.env,.dev.vars, or any other file containing real secrets. - Do not put private values in
*.vars.envfiles. Cloudflare shows those bindings asPlaintext. - Review
git status --ignored --shortbefore publishing or creating releases. - Treat
.secret-backups/as sensitive operational history even though it stores secret names, not values. - Rotate secrets immediately if an env file is accidentally committed, pasted into a ticket, or shared in chat.
See Security Guide for the detailed model and incident checklist.
Start with:
npm install
npx wrangler whoami
git status --ignored --short
npm run deploy:dry-runSee Troubleshooting Guide for common Wrangler, npm, shell, and Cloudflare errors.
MIT. See LICENSE.