@pratikw/datacloak
v0.3.0
Published
datacloak CLI: cloak/restore/scan/guard plus shell integration and hooks for 11 coding agents.
Readme
DataCloak — swap real secrets for fakes before AI ever sees them

DataCloak is a local-first sensitive-data protection layer for AI prompts.
Paste a .env, a DSN, or an API key into your agent — DataCloak swaps every
secret and PII value for a realistic synthetic fake (same shape, same
meaning, zero real data) before it reaches the model, then swaps the
originals back into the response. The model reasons over a structurally
identical prompt and its answers come back with your real values restored —
result quality never compromised.
cloak('contact [email protected], key sk-abcdefghij1234567890')
// → 'contact [email protected], key sk-SYNTHQ4j985lvvRXTkYUwtqW8'
restore(/* model reply with synthetics */)
// → originals back, byte-identicalFull guides: https://pratikwayal01.github.io/datacloak/
What it detects
| Category | Coverage |
|----------|----------|
| API keys | OpenAI (incl. sk-proj-, sk-svcacct-), Anthropic, AWS, GitHub PAT, Stripe |
| Tokens | JWT, PEM private keys, high-entropy strings (Shannon ≥ 4.5) |
| Credentials | Env KEY=value (50+ key names), DSNs (postgres, mongo, redis, mysql, amqp), inline JSON/YAML secrets |
| PII | Email, US + E.164 phones, IPv4 |
| NER (opt-in @pratikw/detect-ner) | Person names, street addresses (US/DE), DOB (gated on co-located PII) |
Requirements
node≥ 18,npm
No account, no server, no network calls. Everything runs in-process.
Installation
One-liner:
curl -fsSL https://raw.githubusercontent.com/pratikwayal01/datacloak/master/install.sh | bashOr with npm directly:
npm install -g @pratikw/detectFrom source:
git clone https://github.com/pratikwayal01/datacloak.git && cd datacloak
npm install
npm run build --workspace packages/detect # tsc → packages/detect/dist/
npm test --workspace packages/detect # 29 tests, corpus recall gateBrowser extension (unpacked, Chrome/Edge):
npm install
npm run build --workspace packages/browser-extension # esbuild → dist/Then open chrome://extensions, enable Developer mode, click
Load unpacked, and select packages/browser-extension.
Covers claude.ai, ChatGPT, Gemini, Grok (x.ai), Perplexity, Cowork and
DeepSeek — auto-cloak on send, restore in responses, popup viewer on the
toolbar. Firefox: about:debugging → This Firefox → Load Temporary Add-on
with manifest.json (untested, expected-compatible).
Extension highlights (v0.3.0)
- Typed entities, no regex — value + type rows (Name, Employee ID, Email, Phone, Other) with same-length/case/format fakes; right-click any selection to capture it with auto-inferred kind.
- Cloak profiles — per-profile entities, detector flags, and UI prefs.
- Review mode — centered overlay with per-row Keep/Reveal, same text never asks twice; auto mode shows cloak counts on the page badge.
- Full-page tab — vault table, last-cloak side-by-side diff with one-click entity capture, Dev Tools network log with per-site origins.
- Robustness — recase-tolerant restore, copy-matches-display, confirmed global vault wipe, all-time cloaked counter, first-run tour.
Coding agents
One binary, eleven harnesses — full copy-paste steps in
docs/harnesses.md:
| Agent | Mechanism |
|---|---|
| Claude Code | UserPromptSubmit + PreToolUse/PostToolUse hooks |
| OpenAI Codex CLI | hooks.json prompt gate + tool deny/rewrite |
| Gemini CLI | BeforeAgent/BeforeTool/AfterTool hooks |
| Qwen Code | UserPromptSubmit + PreToolUse/PostToolUse hooks |
| Kilo Code | Plugin (re-exports OpenCode hooks) |
| OpenClaw | before_prompt_build / before_tool_call plugin |
| Hermes Agent | pre_llm_call / pre_tool_call / result transform |
| Pi | hooks.yaml (prompt context-only — Pi limitation) |
| DeepSeek harness | agent/pre-step + tools/pre-execute cordis plugin |
| Aider | Shell preexec + pre-commit hook (no in-harness API) |
| OpenCode | Native plugin (npm) — add @pratikw/opencode-plugin to the plugin array in opencode.json, restart |
| Anything else | datacloak install-shell preexec backstop |
Quick start
import { DataCloakEngine } from '@pratikw/detect';
const cloak = new DataCloakEngine();
// Outbound: real values → synthetics (vault remembers the mapping)
const out = cloak.cloak(
'DATABASE_URL=postgres://alice:[email protected]:5432/users'
);
// → 'DATABASE_URL=postgres://Kaelyn_Torp80:[email protected]:5432/users'
// key name preserved, protocol/port/path intact, user/pass/host faked
// Inbound: model echoes synthetics → restore originals before display
const back = cloak.restore(modelReply);
// → { text: '...db.prod.acme.com...', restored: 2 }(From source, import from './packages/detect/dist/engine.js' instead.)
Guarantees
Rules that hold on every call:
- Consistent identity — same original → same synthetic within a session.
- Service-invalid fakes — synthetic secrets carry a
SYNTHinfix: structurally valid, visually identifiable, fail authentication. - Key names preserved — env vars and DSNs keep protocol, port, path and key names; only secret values are faked.
- Safe fallback — unknown formats become opaque
[CATEGORY_XXXXXX]tokens. - Extensible — custom regex patterns with loud load-time validation.
- Local only — the vault is in-memory, never written to disk.
Testing
npm test --workspace packages/detect
# vault, patterns, entropy, synthesizers, engine — 5 suites, 29/29 green- Corpus recall: 40/40 labeled samples (100%, gate ≥ 95%) —
test/corpus.jsonl(fixtures use obviously-fake credentials likeadmin:passby design — GitHub secret-scanning hits on them are false positives) - NER corpus: 26/26 positives + 10/10 negatives —
packages/ner/test/corpus-ner.jsonl - Perf: ~9.5ms to cloak 12KB (guard < 200ms)
- Synthesis pins: phones locked to fictional
555-01/+44770090ranges, JWT encoder UTF-8-safe with NumericDate seconds
Honest gaps
Surfaced during implementation, all tracked (none hidden):
- Phones match substrings of longer digit runs — recall-oriented MVP tradeoff.
cloak()has no per-item try/catch; only null-synthesizer fallback is covered (opaqueToken), a throwing custom synthesizer would propagate.- Opaque-token fallback skips the input-collision check (negligible: random 6-char suffix).
restore().restoredcounts distinct vault entries hit, not total occurrences.- Env regex is line-anchored — mid-line
export KEY=vis missed by design. - NER is heuristic-grade: rare surnames matching street suffixes (Lane, Way) false-negative; multi-word streets partial; ONNX slot wired, model not bundled.
Architecture
packages/
├── detect/ @pratikw/detect — engine, patterns, synthesizers, vault
│ └── src/
│ ├── engine.ts # DataCloakEngine: detect(), cloak(), restore()
│ ├── patterns/ # secrets.ts, credentials.ts, pii.ts → index.ts registry
│ ├── entropy.ts # Shannon scan (≥4.5, ≥20 chars, UUID/image skips)
│ ├── synthesizers/ # pii.ts, secrets.ts, credentials.ts → index.ts registry
│ ├── tokens.ts # opaque [CATEGORY_XXXXXX] fallback
│ ├── vault.ts # bidirectional Map + LRU(2000)
│ └── types.ts # Detection, CloakResult, VaultEntry, Config
├── ner/ @pratikw/detect-ner — heuristic NER + ONNX loader (opt-in)
├── opencode-plugin/ @pratikw/opencode-plugin — cloak/block/redact/restore hooks
├── cli/ @pratikw/datacloak — binary + shell + 10 harness adapters
├── browser-extension/ MV3 extension — composer intercept, per-tab vault, popup
└── vscode-extension/ cloak/restore commands, vault tree, status barTwo-pass detection: compiled RegExp registry in priority order with
longest-match de-overlap, then an entropy sweep for anything the patterns
missed. Synthesis is per-category Faker calls; the vault maps
synthetic ↔ original in memory only — never written to disk.
Publishing
Maintainer-only. Single release train: tag vX.Y.Z publishes all four
packages (detect, datacloak, opencode-plugin, detect-ner) at that
version via publish
(repo secret NPM_TOKEN needs publish rights on @pratikw):
# bump version in all four packages/*/package.json to X.Y.Z, then:
git tag v0.2.0 && git push origin v0.2.0
# CI builds, tests, checks versions == tag, publishes with provenanceInstaller flags: install.sh --repair (reinstall + re-verify),
install.sh --uninstall (removes packages; vault files left for you to purge).
Contributing
Bug reports and feature requests live in
GitHub issues —
check the privacy policy
first if your report involves real credentials (hint: don't paste them;
use synthetic examples). Pull requests welcome: keep them focused, add
tests for behavior changes (npm test --workspace packages/<name>).
Contact
Bug reports and feature requests: https://github.com/pratikwayal01/datacloak/issues.
License
MIT — see LICENSE.
Further reading
- Documentation — install, quick start, agents, architecture, privacy
- Threat model — full PRD (vision, surfaces, roadmap, §11 limitations)
assets/— launch video (brag.mp4), poster
