{"version":"1.1.0","schema":"https://oneagentaday.com/api/schema.json","agent":{"title":"Env Var Auditor","slug":"env-var-auditor","date":"2026-09-29","issue":25,"category":"coding","categoryLabel":"Coding & Vibe Coding","tags":["vibe-coding","env","security"],"difficulty":"medium","runtimes":["Cursor","Claude","ChatGPT"],"excerpt":"Paste .env.example and the code that reads it. Get missing keys, unused keys, and names that look like live secrets.","problem":"The example file and the code drifted apart, and you cannot tell which key the app will demand at boot.","videoUrl":null,"url":"https://oneagentaday.com/agents/env-var-auditor","apiUrl":"https://oneagentaday.com/api/agents/env-var-auditor.json","promptUrl":"https://oneagentaday.com/agents/env-var-auditor/prompt.txt","configUrl":"https://oneagentaday.com/agents/env-var-auditor/config.json","configFilename":"env-var-auditor.defaults.json","license":"CC-BY-4.0","howItWorks":"The auditor compares two pastes: the example file and the lines that read environment variables. A key the code requires and the example hides will break the next boot. A key in the example that nothing reads is how secrets linger. A value that looks like a live credential does not belong in an example, even when you believe it is fake.\n\nIt does not need the real secret and should not be given one. It will not tell you how to use a leaked key. It tells you to rotate if a live-looking value was committed, and it shows the placeholder shape.\n\nUpdate the example in the same commit as the code that reads the new name. Drift is how this list comes back.","steps":[{"name":"Paste the example and the reads","text":"Copy .env.example and the lines that read process.env or the equivalent. Redact any real secret first; leave the name. A placeholder is fine."},{"name":"Paste the prompt","text":"You get three lists: required by code and missing from the example, present in the example and unread, and names whose values look like live credentials."},{"name":"Fix the example, not the secret store","text":"Add the missing key with an obvious fake value. Remove or comment the unused key. Replace any live-looking value with a placeholder like sk_test_replace_me."},{"name":"Do not paste a rotated secret back into chat","text":"If a real key was in the file, rotate it in the provider. The auditor's job is the drift. It does not need the secret to finish."}],"demo":[{"second":0,"label":"The drift","detail":"PORT and DATABASE_URL are read. DATABASE_URL is required. FLY_REGION is read and missing from the example."},{"second":8,"label":"Unused","detail":"Nothing in the example is unread. FLY_REGION is the gap, the other way."},{"second":16,"label":"The live-looking value","detail":"STRIPE_SECRET_KEY's example starts with sk_live_. That prefix does not belong in an example even if they say it is fake."},{"second":24,"label":"The fix","detail":"Add FLY_REGION=local. Change the Stripe example to a sk_test_ placeholder. Do not print a real key."}],"sampleInput":".env.example\nPORT=3000\nDATABASE_URL=postgres://localhost/ledger\nSTRIPE_SECRET_KEY=sk_live_replace_me\n\nCode:\nconst port = process.env.PORT ?? \"3000\";\nconst db = process.env.DATABASE_URL;\nif (!db) throw new Error(\"DATABASE_URL is required\");\nconst stripe = process.env.STRIPE_SECRET_KEY;\nconst region = process.env.FLY_REGION;\n\nNobody reads FLY_REGION in the paste. The example contains a value that starts with sk_live_. I have not committed a real key. Tell me if the example is unsafe anyway.","prompt":"You compare an env example file to the code that reads env vars. You flag drift and live-looking placeholders. You do not ask for real secrets and you do not explain how to abuse a key.\n\nINPUTS\n- The example file.\n- The lines that read env vars, with enough context to see a required check.\n\nRULES\n- Missing: read by code, absent from the example. Mark required if the code throws or refuses to boot without it.\n- Unused: in the example, not read in the paste. Say the paste may be incomplete rather than claiming the key is dead in the whole repo.\n- Live-looking: values that use a live prefix (sk_live_, rk_live_, AKIA, a private key header, a real-looking connection string with a password). Tell them to replace with an obvious fake. Do not repeat the secret; repeat the name and the prefix only.\n- Do not invent keys.\n- Do not provide exploit steps for a leaked key. The remediation is: rotate in the provider, then replace the example.\n- If they pasted a real-looking full key, tell them to rotate and do not echo the value.\n\nOUTPUT\n## Missing\n## Unused\n## Live-looking\n## Example lines to change\nName and a safe placeholder.\n\n## Rotate\nYes or no, and which name. No values.","config":"{\n  \"version\": 1,\n  \"livePrefixes\": [\n    \"sk_live_\",\n    \"rk_live_\",\n    \"AKIA\",\n    \"-----BEGIN\"\n  ],\n  \"echoSecretValues\": false,\n  \"exploitSteps\": false\n}\n"}}