[Feature Request] varlock audit: detect cloudflare:workers, IaC bindings, and framework env usage
Maintainers usually reply within 1 day
@theoephraim is already working on this.
Since Jun 1, 2026.
Assessment
This issue has not been assessed yet.
Description
Description
varlock audit compares keys defined in .env.schema against environment-variable references found in source code. Today it works well for direct process.env.VAR usage and ENV.VAR from varlock/env, but it reports false positives ("unused in schema") for several common deployment patterns — especially Cloudflare Workers deployed via IaC tools other than varlock-wrangler.
In a monorepo using Alchemy for Cloudflare Workers + D1 + Astro:
- Deploy time: secrets and vars are declared as Worker bindings via
alchemy.env.VAR/alchemy.secret.env.VARinalchemy.run.ts. Alchemy reads resolved values fromprocess.env(injected byvarlock run --), but audit does not scan those binding declarations. - Worker runtime: application code reads
env.VARfromcloudflare:workers(sometimes via a thin package re-export). Audit does not trace property access on that import. - Astro marketing site: public vars are consumed via
astro:env/clientimports, notprocess.env.
Running varlock audit from the infra package entry point flags every binding key (e.g. BETTER_AUTH_SECRET, PUBLIC_SERVER_URL, ALCHEMY_PASSWORD) as unused, even though they are actively used.
We currently work around Alchemy-only keys with # @auditIgnore per the audit hint ("If this is used by an external tool…"), but Worker and Astro keys are genuinely referenced in code — audit just cannot see them yet.
Motivation
Accurate varlock audit is important for:
- Solo developers using AI coding agents (detecting drift between schema and code)
- Monorepos where schema lives in
packages/infrabut consumption is spread across apps/packages - Alchemy / better-t-stack adopters who use
varlock run -- <deploy>withoutvarlock-wrangler
Without improved detection, audit either fails noisily or teams blanket @auditIgnore, which defeats the purpose.
Proposed Solution
Extend varlock audit (and/or document first-class patterns) for:
cloudflare:workersenv access — detectenv.VAR, destructuring fromcloudflare:workers, and common re-export wrappers (e.g.@talkiva/env/server).- IaC binding declarations — optional detectors for known patterns such as
alchemy.env.VAR,alchemy.secret.env.VAR, and potentially SST/Pulumi equivalents. - Framework env modules — e.g.
import { VAR } from "astro:env/client"mapped back to schema keys. - Monorepo-aware scanning — when
varlock.loadPathspans multiple packages, default audit scan roots could include sibling app/package directories referenced by the schema entry point.
If full static analysis is out of scope for some patterns, documenting recommended @auditIgnore categories (external CLI tools vs. runtime bindings) would still help.
Alternatives
@auditIgnoreon all binding keys — works today but removes audit coverage for real drift.- Wait for
@varlock/cloudflare-integration+varlock-wrangleronly — does not help Alchemy/SST/Pulumi deploy paths where Worker code still usescloudflare:workerswithout migrating imports tovarlock/env. - Custom audit scripts — possible but duplicates logic Varlock already owns.
Additional Information
- Related runtime binding request (separate concern): #735 — public API to build
__VARLOCK_ENVfor non-wrangler deploy tools. - better-t-stack adoption context: AmanVarshney01/create-better-t-stack#1029 — stacks deploying via Alchemy hit both #735 (runtime redaction) and this audit gap.
- Real-world repro: Alchemy deploy with
varlock run -- alchemy dev; schema atpackages/infra/.env.schemaimportingapps/server/.env.schema; audit run frompackages/infrawith explicit scan paths still reports all binding keys unused.
Example binding declaration audit should recognize:
export const server = await Worker("server", {
bindings: {
BETTER_AUTH_SECRET: alchemy.secret.env.BETTER_AUTH_SECRET!,
CORS_ORIGIN: alchemy.env.CORS_ORIGIN!,
},
});
Example runtime usage audit should recognize:
import { env } from "cloudflare:workers";
// or: import { env } from "@talkiva/env/server";
const origin = env.CORS_ORIGIN;
- Dominant language
- TypeScript
- Stars
- 4.9k
- Forks
- 140
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 35
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from dmno-dev/varlock
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
dmno-dev/varlock#1279 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 69/100
dmno-dev/varlock#1100 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 78/100
dmno-dev/varlock#1278 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 72/100
dmno-dev/varlock#1275 · 1 comment ·
Maintainers usually reply within 1 day
-
core:varlock RFC
Difficulty 5/5 Over a week Newbie friendliness 28/100
dmno-dev/varlock#1258 · 1 comment ·
Maintainers usually reply within 1 day
All issues in dmno-dev/varlock
Similar issues
-
documentation good first issue roadmap
Difficulty 1/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
resend/react-email#3876 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
siyuan-note/siyuan#21324 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
himynameisdave/bsky-profanity-counter#59 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100