Environment And Bindings¶
R-ENV-1 - Client environment variables are public¶
Severity. blocker when a secret-like value is exposed to the client bundle; otherwise
medium when the split between public config and server config is undocumented.
Rule. Frontend environment variables may contain public configuration only. Secrets live in Cloudflare bindings or deployment secrets.
Why. Vite-style client env values are bundled into browser assets.
vcqa. Flag secret-like VITE_* variables and frontend imports from server-only config.
Concretely: any VITE_-prefixed name matching SECRET|TOKEN|PRIVATE|PASSWORD|_KEY that is
not explicitly marked publishable; any browser module importing the Functions Env type or
a server config module; any .env* with real values that is not gitignored.
Evidence.
- Source/config:
.env*files,vite.config.*, browser env access sites, the deploy workflow's build-time environment block. - CI/artifacts: build log or secret scan over the published output directory.
- Negative evidence: no production secret string appears in built assets.
- Exception: not available for secret values. A publishable key may carry an
acceptedExceptionnaming why it is safe to publish.
References.
- Vite env and mode: https://vite.dev/guide/env-and-mode
- Workers secrets: https://developers.cloudflare.com/workers/configuration/secrets/
R-BIND-1 - Bindings are environment-scoped¶
Severity. blocker when preview and production resolve to the same underlying
resource ID or the same secret value; otherwise high when the separation exists but the
deploy path does not select an environment explicitly.
Rule. Preview, staging, and production bindings are named and reviewed separately, and the deploy path selects the intended environment explicitly.
Why. Accidental reuse of production bindings in previews is a common fullstack Pages failure mode.
vcqa. Inspect Wrangler config and deployment workflows for environment-specific binding names. Compare the concrete identifiers, not just the binding names:
[[d1_databases]]database_nameanddatabase_id;[[kv_namespaces]]idandpreview_id;[[r2_buckets]]bucket_nameandpreview_bucket_name;[[queues.producers]]queue names,[[hyperdrive]]ids, and service bindings;[env.preview]/[env.production](or the Pages preview/production variable and secret sets) carrying different values for each of the above.
Flag any resource ID that appears in more than one environment, any environment block that inherits a production ID by omission, and any deploy command that does not select the environment or branch it intends.
Evidence.
- Source/config:
wrangler.toml/wrangler.jsoncenvironment blocks, or the documented Pages project preview/production variable and secret sets. - CI/artifacts: deploy log showing the selected environment or branch, and the binding set applied.
- Runtime/deploy: a preview deployment reading a preview resource, demonstrated by a smoke request whose data is preview data.
- Exception:
acceptedExceptionfor a deliberately shared non-production sandbox, naming owner, scope, environments, compensating controls, evidence, and expiry/review date. Sharing a production resource with preview is not an acceptable exception.
References.
- Wrangler environments: https://developers.cloudflare.com/workers/wrangler/environments/
- Pages preview deployments: https://developers.cloudflare.com/pages/configuration/preview-deployments/
- Workers bindings: https://developers.cloudflare.com/workers/runtime-apis/bindings/
R-BIND-2 - Binding types are documented at the Function boundary¶
Severity. medium, escalating to high when an undeclared binding is used by a
handler that performs writes or authorization.
Rule. Function context bindings must have TypeScript definitions or documented runtime
names, and every binding a handler reads from env must appear in that declaration.
Why. Unclear binding names cause runtime-only failures and make scanner findings less actionable.
Scoring. A pass requires a single declared source of binding names — an Env
interface, a worker-configuration.d.ts generated by wrangler types, or an equivalent
documented list — and no env.X access whose X is missing from it.
vcqa. Check for environment binding types, generated Cloudflare types, or equivalent
interfaces; diff the declared binding names against env. property accesses across
functions/** and against the binding blocks in Wrangler config.
Evidence.
- Source/config: the
Envinterface or generated types, Wrangler binding blocks,env.access sites. - CI/artifacts:
tsc/wrangler typesstep in the pipeline and its freshness relative to the config. - Exception:
acceptedExceptionnaming the undeclared binding, why it is dynamic, and the compensating runtime check.
References.
- Workers bindings: https://developers.cloudflare.com/workers/runtime-apis/bindings/
- Cloudflare Pages Functions: https://developers.cloudflare.com/pages/functions/
R-ENV-2 - Local and preview configuration are explicit¶
Severity. medium, escalating to high when the undocumented local path is the one a
contributor would reach for first and it silently binds production resources.
Rule. Local development and preview deployments must document how bindings are mocked, seeded, or replaced, and the documented commands must exist in the repo.
Why. A fullstack Pages app often behaves differently locally unless bindings are accounted for.
vcqa. Check docs, scripts, or Wrangler config for local binding strategy. Look for a
local dev command (wrangler pages dev <dir> or the package script that wraps it), local
binding flags or [env.local]-style configuration, .dev.vars handling and gitignore
status, and a seed/migration script for local data.
Evidence.
- Source/config:
package.jsonscripts,.dev.vars.example, Wrangler local config, seed or migration scripts. - CI/artifacts: any workflow that runs the same local preview path.
- Runtime/deploy: the documented command starts a preview that serves both the assets and the Functions.
- Exception:
acceptedExceptionwhen local development is intentionally unsupported, naming the owner and the supported alternative.
References.
- Pages preview deployments: https://developers.cloudflare.com/pages/configuration/preview-deployments/
- Wrangler environments: https://developers.cloudflare.com/workers/wrangler/environments/