-
Discovery - Find all env files and code references
-
Usage Analysis - Identify which variables are used vs unused
-
Service Detection - Recognize services (Stripe, AWS, Supabase, etc.) and their permission implications
-
Code Path Mapping - Document where each variable is used in the codebase
-
Report Generation - Output a structured markdown document
-
Cleanup (optional) - Safely remove unused variables with user confirmation
-
Regression Prevention - Validate no regressions via build/test validation with automatic rollback
<quick_start> Audit only (default):
-
Scan for .env* files in project root
-
Grep codebase for process.env. , import.meta.env. , and destructured env patterns
-
Cross-reference declared vs used variables
-
Identify services by naming patterns and categorize permissions
-
Generate markdown report using the template
With cleanup (--cleanup flag): 6. Check for dynamic access patterns that might hide usage 7. Present unused variables and get user confirmation 8. Create backups, remove confirmed variables 9. Run build/tests to detect regressions 10. Auto-rollback if regressions detected </quick_start>
Find all env-related files:
find . -maxdepth 2 -name ".env*" -o -name "env.d.ts" | grep -v node_modules
Common files:
-
.env
-
Local development
-
.env.local
-
Local overrides
-
.env.development / .env.production
-
Environment-specific
-
.env.example
-
Template for required variables
Step 2: Extract Declared Variables
Parse each env file for variable declarations:
Grep pattern: ^[A-Z][A-Z0-9_]+=
Build a list of all declared variables with their source file.
Step 3: Find Code References
Search for environment variable usage patterns:
Direct access:
process.env.VARIABLE_NAME import.meta.env.VARIABLE_NAME process.env["VARIABLE_NAME"]
Destructured patterns:
const { API_KEY, DATABASE_URL } = process.env
Framework-specific:
// Next.js public vars NEXT_PUBLIC_*
// Vite VITE_*
Use Grep tool with patterns:
process.env.([A-Z][A-Z0-9_]+) import.meta.env.([A-Z][A-Z0-9_]+)
Step 4: Cross-Reference Usage
For each declared variable:
-
Used: Found in code references
-
Unused: Declared but no code references found
-
Undeclared: Referenced in code but not in any env file
Flag potential issues:
-
Unused variables (cleanup candidates)
-
Undeclared variables (missing from .env.example)
-
Variables only in .env but not .env.example (documentation gap)
Step 5: Detect Services and Infer Permissions
Match variable names against known service patterns. See references/service-patterns.md for the complete list.
Categories:
-
Database - Connection strings, credentials
-
Authentication - JWT secrets, OAuth credentials
-
Payment - Stripe, payment processor keys
-
Cloud Services - AWS, GCP, Azure credentials
-
Third-party APIs - Various service integrations
-
Feature Flags - Toggle configurations
-
Application Config - URLs, ports, modes
Permission levels:
-
Critical - Full account access, billing, admin operations
-
High - Read/write access to user data
-
Medium - Limited API access, specific operations
-
Low - Public keys, non-sensitive configuration
Step 6: Map Code Paths
For each used variable, document:
-
File path where it's used
-
Function/component context
-
Purpose (inferred from surrounding code)
Example:
STRIPE_SECRET_KEY ├── src/lib/stripe.ts:15 - Stripe client initialization ├── src/api/webhooks/stripe.ts:8 - Webhook signature verification └── src/api/checkout/route.ts:23 - Create checkout session
Step 7: Generate Report
Use the template in templates/env-audit-report.md to generate the final document.
Output to: ENV_AUDIT.md in project root (or user-specified location)
Step 8: Cleanup Unused Variables (Optional)
Trigger: User passes --cleanup flag or explicitly requests cleanup after reviewing the audit report.
8.1 Present Cleanup Candidates
Display unused variables with context:
UNUSED VARIABLES (candidates for removal):
-
OLD_API_KEY (.env, .env.local)
- Last modified: [file date]
- No code references found
-
DEPRECATED_SERVICE_URL (.env)
- Last modified: [file date]
- No code references found
8.2 Dynamic Access Check
Before confirming removal, search for dynamic access patterns that grep may have missed:
// These patterns indicate variables might be used dynamically:
process.env[variableName] // Dynamic key access
process.env[${prefix}_KEY] // Template literal access
Object.keys(process.env) // Iteration over all env vars
{ ...process.env } // Spread operator
Use Grep with patterns:
process.env[ Object.keys(process.env) Object.entries(process.env) ...process.env
If dynamic access patterns found: Flag affected variables for manual review and warn user.
8.3 User Confirmation
Use AskUserQuestion to confirm each removal:
The following variables appear unused. Select which to remove:
[ ] OLD_API_KEY - Remove from .env, .env.local [ ] DEPRECATED_SERVICE_URL - Remove from .env [ ] Skip cleanup
⚠️ Variables will be backed up before removal.
Safety rules:
-
NEVER auto-delete without explicit user confirmation
-
NEVER remove variables from .env.example (it serves as documentation)
-
Create backup before any modifications
8.4 Create Backups
Before modifying any file:
Create timestamped backup directory
mkdir -p .env-backups/$(date +%Y%m%d_%H%M%S)
Backup each env file being modified
cp .env .env-backups/$(date +%Y%m%d_%H%M%S)/.env.backup cp .env.local .env-backups/$(date +%Y%m%d_%H%M%S)/.env.local.backup
8.5 Remove Confirmed Variables
For each confirmed variable:
-
Use Edit tool to remove the line from each env file
-
Preserve comments associated with the variable (line immediately above if it starts with #)
-
Log the removal
8.6 Document Cleanup
Append cleanup summary to ENV_AUDIT.md:
Cleanup Log
Date: [timestamp] Backup Location: .env-backups/[timestamp]/
Removed Variables
| Variable | Removed From | Reason |
|---|---|---|
| OLD_API_KEY | .env, .env.local | Unused - no code references |
Preserved (Manual Review Required)
| Variable | Reason |
|---|---|
| DYNAMIC_VAR | Dynamic access pattern detected |
Step 9: Regression Prevention
Purpose: Validate that removing unused variables doesn't break the application.
9.1 Pre-Cleanup Baseline
Before removing any variables, capture baseline state:
Check if project builds successfully
npm run build 2>&1 | tee .env-backups/pre-cleanup-build.log echo $? > .env-backups/pre-cleanup-build-status
Run tests if available
npm test 2>&1 | tee .env-backups/pre-cleanup-test.log echo $? > .env-backups/pre-cleanup-test-status
Store exit codes:
-
0 = Success (baseline is green)
-
Non-zero = Already failing (warn user but proceed if they confirm)
9.2 Dynamic Access Detection
Search for patterns that indicate runtime env var access:
High-risk patterns (require manual review):
// Config objects that spread env const config = { ...process.env }
// Dynamic key construction
const key = ${SERVICE}_API_KEY
process.env[key]
// Iteration patterns Object.entries(process.env).filter(([k]) => k.startsWith('FEATURE_'))
// External config loaders require('dotenv').config({ path: customPath })
Detection commands:
Grep: process.env[(?!['"][A-Z]) Grep: Object.(keys|values|entries)(process.env) Grep: ...process.env Grep: dotenv.*config
If detected: List affected files and require explicit user acknowledgment before proceeding.
9.3 Post-Cleanup Validation
After removing variables, run validation:
Verify build still succeeds
npm run build 2>&1 | tee .env-backups/post-cleanup-build.log POST_BUILD_STATUS=$?
Verify tests still pass
npm test 2>&1 | tee .env-backups/post-cleanup-test.log POST_TEST_STATUS=$?
9.4 Regression Detection
Compare pre and post states:
Check Pre-Cleanup Post-Cleanup Status
Build ✅ Pass ✅ Pass OK
Tests ✅ Pass ✅ Pass OK
If regression detected:
-
Immediately alert user
-
Offer automatic rollback: ⚠️ REGRESSION DETECTED
Build/tests failed after removing variables.
Options:
- Rollback all changes (restore from backup)
- Rollback specific variables
- Investigate failure (show diff)
- Proceed anyway (not recommended)
9.5 Automatic Rollback
If user requests rollback:
Restore from backup
cp .env-backups/[timestamp]/.env.backup .env cp .env-backups/[timestamp]/.env.local.backup .env.local
Verify restoration
npm run build && npm test
9.6 Git Integration (Optional)
If in a git repository, offer branch-based cleanup:
Create cleanup branch
git checkout -b env-cleanup/$(date +%Y%m%d)
After cleanup, changes can be reviewed via PR
git add .env .env.local git commit -m "chore: remove unused environment variables
Removed:
- OLD_API_KEY (unused)
- DEPRECATED_SERVICE_URL (unused)
Backup: .env-backups/[timestamp]/"
Benefits:
-
Easy rollback via git checkout -
-
Changes visible in PR review
-
CI/CD will validate before merge
<reference_index> Service Patterns: references/service-patterns.md - Known services and their variable naming conventions </reference_index>
<success_criteria> Audit is complete when:
-
All .env files discovered and parsed
-
All code references found
-
Variables categorized as used/unused/undeclared
-
Services detected and permission levels assigned
-
Code paths documented for each variable
-
Markdown report generated with all sections
-
Report saved to specified location
Cleanup is complete when (if --cleanup requested):
-
Dynamic access patterns checked
-
User confirmed variables to remove
-
Backups created in .env-backups/
-
Variables removed from env files (not .env.example)
-
Cleanup log appended to report
Regression prevention is complete when:
-
Pre-cleanup build/test baseline captured
-
Post-cleanup validation run
-
No regressions detected OR rollback performed
-
Git branch created (if opted in) </success_criteria>