[FEATURE] Mark sensitive environment variables and file paths to prevent secret exposure
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Claude Code can access secrets through multiple vectors that existing mitigations don't cover:
File reads - .claudeignore and permission hooks are bypassed via system reminders (#8031) and indexing (#4160). In one case Claude read .env.local and committed the values to an env.example file that was pushed to git (#7921).
Shell environment - env, printenv, or echo $VAR exposes any exported variable regardless of file protections. Even when using external secret managers (1Password CLI, HashiCorp Vault, AWS SSM etc.) to keep secrets off disk, once values are resolved into the shell environment they're fully visible.
Aggressive debugging - Claude hunts for credentials when troubleshooting auth errors and injects them into curl commands (#9637).
Current workarounds like .claudeignore, permission hooks, and per-command wrapping with op run are either incomplete (only covering file access, not shell environment) or too restrictive (limiting Claude's ability to help with debugging).
Proposed Solution
A single sensitive config in .claude/settings.json that lets users mark env var names and file paths as sensitive. Claude sees they exist but never sees the values/contents.
{
"sensitive": {
"envPatterns": ["*_TOKEN", "*_KEY", "*_SECRET", "*_PASSWORD", "*_API_*"],
"paths": [".env.local", ".env.production", "secrets/", "*.pem", "*.key"]
}
}
Env var behaviour - when Claude encounters a matching variable via shell output, file read, or system reminder:
STRIPE_SECRET=*****
DATABASE_URL=*****
NODE_ENV=development // not matched, visible as normal
File/directory behaviour - matched paths are fully blocked from context injection. Unlike .claudeignore (which only prevents indexing), this filter applies to all access vectors including system reminders, indirect reads, and command output like cat .env.local. Claude sees the file/directory exists (so it can reference it in scripts or configs) but never sees the contents.
The filter applies at the context injection boundary - glob match on variable names and file paths, redact/block before anything enters Claude's context. No secret detection heuristics, no proxy architecture, no specific tool integrations required.
Alternative Solutions
.claudeignore- only prevents indexing, bypassed via system reminders (#8031) and indirect access (#4160)- Permission hooks - can deny file reads but don't cover shell environment access, and Claude can still see file contents via system reminders
op runper-command - secrets only exist in child process, but this limits Claude to running individual wrapped commands rather than freely debugging- Not exporting secrets - breaks tooling that depends on env vars
- #2695 proposed a "Zero-Trust Architecture" with pattern-based secret detection, placeholder replacement, local execution proxies, and encrypted stores - far more complex than needed
Priority
High - Significant impact on productivity
Feature Category
Configuration and settings
Use Case Example
- I'm working on a Node.js app that uses Stripe, a database, and various third-party APIs
- My
.env.localhas raw credentials; my.zshrcexports API keys viaop read - I ask Claude Code to debug a failing API call
- Claude runs
env | grep STRIPEorcat .env.localto find credentials and stuffs them into a curl command - now my secrets are in Claude's context - With this feature, I'd add
"sensitive": { "envPatterns": ["*_KEY", "*_SECRET", "*_TOKEN"], "paths": [".env.local", "*.pem"] }to my.claude/settings.json - Claude would see
STRIPE_SECRET=*****and know the variable is configured without ever seeing the value - Claude could still help debug by checking the variable exists, verifying the format of non-sensitive config, and suggesting fixes - just without accessing the actual secret
Additional Context
Related issues showing this is a recurring problem:
- #2695 - Zero-trust env var architecture (open, 9 upvotes, proposes a more complex version of this)
- #9637 - Claude aggressively reads secrets from .env files
- #7921 - Claude committed .env.local secrets to git via env.example
- #8031 - System reminders bypass .env read permissions
- #4160 -
.claudeignoreinsufficient - Claude finds indirect access routes - #2637 - Original
.claudeignorefor env files request - #112 - .env file access security risk
- #401 - Automatic .env loading into bash environment
This proposal consolidates these into one focused, minimal solution: glob patterns on var names and file paths, filtered at the context boundary. Tool-agnostic, composable with existing workarounds, and simple enough to ship without major architectural changes.
This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗