anchanto-pii-guard
v1.0.2
Published
Lightweight local AI DLP system for Cursor — detects and prevents PII and secrets from being sent to LLMs
Maintainers
Readme
Anchanto Guard
Lightweight, fully local PII and secret detection for Cursor. Prevents sensitive data from reaching LLMs through Cursor's hook system — no cloud, no telemetry, zero data leaves your machine.
How It Works
Anchanto Guard hooks into Cursor's beforeSubmitPrompt and beforeReadFile events. Before any prompt or file reaches the LLM, it is scanned. If sensitive data is found, the prompt is blocked and Cursor shows a message explaining what was detected and what to do.
Note: Cursor's hook API does not support modifying prompt text — hooks can only allow or deny. This means all detected PII and secrets result in the prompt being blocked. The user must remove or replace the sensitive value before retrying.
What Gets Blocked
Credentials (must be removed)
| Pattern | Example |
|---|---|
| AWS Access Keys | AKIAIOSFODNN7EXAMPLE |
| OpenAI API Keys | sk-abc123... |
| Anthropic API Keys | sk-ant-api03-... |
| GitHub Tokens | ghp_abc123... |
| GCP API Keys | AIza... |
| JWTs | eyJhbGci... |
| Private Keys | -----BEGIN RSA PRIVATE KEY----- |
| DB connection strings | postgres://user:pass@host/db |
| Passwords in code | password="hunter2" |
| Bearer tokens | Bearer eyJhb... |
| npm / Slack / SendGrid / Shopify / Twilio tokens | service-specific formats |
| High-entropy secrets | Random base64/hex tokens |
PII (replace with placeholder before retrying)
| Pattern | What to use instead |
|---|---|
| Email addresses | [email protected] |
| Indian phone numbers | a dummy number |
| PAN numbers | a dummy PAN |
| Aadhaar numbers | a dummy Aadhaar |
| Credit card numbers | a test card number |
Allowed through (no action)
| Pattern | Behaviour | |---|---| | Internal/private IP addresses | logged, passes through | | Internal domain URLs | logged, passes through | | UUIDs | logged, passes through |
Installation & Setup
# Install globally
npm install -g anchanto-pii-guard
# Setup hooks in your project (run from project root)
cd /your/project
anchanto-guard init
# Restart Cursor to activateinit creates or updates .cursor/hooks.json with absolute paths to Node and the script. Safe to re-run — merges with existing hooks.
Verify Installation
anchanto-guard checkOutput when healthy:
[anchanto-guard] Checking hooks in /your/project
[ OK ] .cursor/hooks.json exists
[ OK ] beforeSubmitPrompt hook present
[ OK ] beforeReadFile hook present
[ OK ] Node path is current
[ OK ] Script path exists
[anchanto-guard] All checks passed. Hooks are healthy.Policy Customization
Create .anchanto-guard.json in your project root or home directory to override defaults:
{
"rules": [
{ "type": "UUID", "action": "ALLOW" },
{ "type": "EMAIL", "action": "WARN" }
],
"allowlist": {
"values": ["[email protected]"],
"patterns": ["@example\\.com$"],
"types": ["UUID"]
}
}Default allowlisted email domains (pass through without blocking)
example.com, example.net, example.org, test.com, foo.com, bar.com, mailinator.com, yopmail.com, sample.com, dummy.com
Use these domains in test/dummy data and they will not be blocked.
Policy file lookup order
<project>/.anchanto-guard.json<project>/.cursor/anchanto-guard.json~/.anchanto-guard.json
Environment Variables
| Variable | Default | Description |
|---|---|---|
| PII_GUARD_LOG_LEVEL | info | Log level: debug, info, warn, error |
Troubleshooting
Hooks are not triggering at all
- Confirm
.cursor/hooks.jsonexists in your project root:cat .cursor/hooks.json - Run the health check:
anchanto-guard check - Restart Cursor — hooks are loaded at startup, not hot-reloaded.
- Check your Cursor version supports hooks (requires Cursor ≥ 0.40).
"command not found" or hook silently fails
Cursor runs hooks with a minimal PATH that often does not include your npm global bin. The init command handles this by writing absolute paths for both Node and the script. Re-run init to fix:
anchanto-guard init
# Restart CursorNode version changed (nvm / fnm / volta)
init bakes the current Node binary path into hooks.json. After switching Node versions that path goes stale — hooks silently fail.
Fix: after every nvm use or Node upgrade, run:
anchanto-guard init
# Restart Cursoranchanto-guard check detects a stale Node path and warns you.
Cursor shows "hook timed out"
Default timeout is 10 seconds. Increase in .cursor/hooks.json:
{ "command": "...", "timeout": 30 }Hook blocks a legitimate prompt (false positive)
Option 1 — use an allowlisted test domain:
Use [email protected] instead of a real email. These domains are allowlisted by default and pass through without blocking.
Option 2 — allowlist a specific value or pattern:
{
"allowlist": {
"values": ["[email protected]"],
"patterns": ["@yourcompany\\.com$"]
}
}Save as .anchanto-guard.json in your project root.
Option 3 — change action for a rule:
{
"rules": [
{ "type": "EMAIL", "action": "WARN" }
]
}Windows
- After
initon Windows, verify the generatedhooks.jsonpaths are valid. - If hooks fail, set the command manually in
.cursor/hooks.json:{ "command": "C:\\Program Files\\nodejs\\node.exe C:\\path\\to\\anchanto-guard.js hook prompt" } - Use
where anchanto-guardin PowerShell to find the installed binary location.
Re-running init is safe
init removes existing Anchanto Guard entries and adds fresh ones with current absolute paths. Other hooks in your hooks.json are preserved.
Security
- Runs entirely locally — no data leaves your machine
- No network calls of any kind
- Dependencies:
libphonenumber-js,validatoronly — no heavy frameworks - Logs never contain raw secret values (SHA-256 fingerprints only)
- No background daemon or persistent process
License
MIT
