Feature request: supply secret values programmatically in the new config (cloudflare.config.ts) #15122
Replies: 2 comments 3 replies
|
An important wrinkle for the Vite flow ( With wrangler, With Vite, the config is evaluated at build time and serialized to disk: So
Either way, the invariant worth preserving: secret values should exist only in memory during the deploy process, never in build artifacts. |
|
@jamesopstad - full proposal outlining how this could work in various scenarios Goal: the config (optionally backed by a tool like varlock) supplies the Worker's complete runtime env - vars and secrets - with secret values existing only in memory during build/deploy. Never in the build output, never in logs. Works with the Build Output Spec constraint: the output is complete, and deploy never reads APIbindings.secret() // declared; value arrives out-of-band; required by default
bindings.secret({ value }) // value supplied by the config (string or thunk)
bindings.secret({ fromEnv: true }) // deployer reads it from its own env, same name
bindings.secret({ fromEnv: "OTHER" }) // ...or from a different env var name
bindings.secret({ required: false }) // declared for types/dev, not enforced
bindings.text({ value?, fromEnv?, required? }) // same options for vars; text(value) unchanged
Declarations (names only) always serialize into the build output - they drive type generation, dev var scoping, and a fail-loudly backstop if values never arrive at deploy. Vars need a declarations field in the output to match Core invariant: resolved values are never placed on the config object. They travel a separate in-memory channel from config evaluation to the uploader, so they structurally cannot reach the serialized output, type-gen, or config dumps. Getting values to deploy (three tiers, no config evaluation at deploy)The config is evaluated once, at build. Values cross the build/deploy boundary one of three ways:
Fallback when none apply (deployer has no key, no matching env): today's behavior - Open question: should the encrypted payload live inside the Build Output Spec (self-contained artifact, key out-of-band) or adjacent to it (no secret material in the artifact, even encrypted)? Needs-values signalThe evaluation context tells resolvers whether values will be consumed (e.g. key present at build). A build that only produces the output resolves nothing sensitive: declaration-only bindings come from names, and a missing deploy-time secret cannot fail the build. Replace semanticsPer #15343, merge-vs-replace is a property of the declared state, not a CLI flag: a settings-level Non-goalsPipeline credentials ("secret zero", vault tokens) are not runtime bindings - they live in build/CI secret stores and are read from the pipeline environment during resolution. Internal/build-only items emit no binding. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Please excuse the AI authored text below. I reviewed it and it is all accurate and clear. I'm working through integrating varlock with the new cf stuff to discover what bumps I find along the way. My hope is that we can remove the need for a cli wrapper like we currently do with our wrangler integration. We need that in order to inject secrets using the
--secret-fileoption and a FIFO. With the new setup, we should be able to resolve the secrets and inject them directly - with the important restriction of not writing any plaintext secrets to disk. This should work for local dev and deployment, and for both vite and non-vite apps.Problem
In the new experimental config (
cloudflare.config.ts/@cloudflare/config),bindings.secret()declares that a secret must exist, but provides no way to supply its value. Values must arrive out-of-band (wrangler secret put,--secrets-file, dashboard).This undercuts the main benefit of config-as-code: since the config is executable TypeScript evaluated at deploy time, it can already resolve values from a secure source (a secrets manager, an env tool) — but has nowhere to put them.
Consequences:
cf deployhas no--secrets-file/--varequivalent, so there is currently no value channel for it at all.--secrets-filejust becomes{"type": "secret_text", "text": ...}metadata bindings.Workaround today
The unsafe escape hatch forwards verbatim to upload metadata, so this works:
…but it's explicitly unsupported, warns on every deploy, and the warning suggests migrating to exactly the out-of-band flows this avoids.
Request
First-class support for programmatic secret values, e.g.:
wrangler deploy --experimental-new-configandcf deploy(same conversion path).Context
Building an integration for varlock (env/secrets management). With the classic config we wrap wrangler to inject
--varflags and a--secrets-file; the new config format lets us move all of that intocloudflare.config.tsdirectly — secret values are the one missing piece. Tested withwrangler@4.120.1,@cloudflare/config@0.5.0,cf@0.6.0.All reactions