@pratikw/detect 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/package.json +8 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DataCloak contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# DataCloak — swap real secrets for fakes before AI ever sees them
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
**DataCloak** is a local-first sensitive-data protection layer for AI prompts.
|
|
13
|
+
Paste a `.env`, a DSN, or an API key into your agent — DataCloak swaps every
|
|
14
|
+
secret and PII value for a **realistic synthetic fake** (same shape, same
|
|
15
|
+
meaning, zero real data) before it reaches the model, then swaps the
|
|
16
|
+
originals back into the response. The model reasons over a structurally
|
|
17
|
+
identical prompt and its answers come back with your real values restored —
|
|
18
|
+
result quality never compromised.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
cloak('contact john.doe@acme.com, key sk-abcdefghij1234567890')
|
|
22
|
+
// → 'contact Nigel_Lebsack@hotmail.com, key sk-SYNTHQ4j985lvvRXTkYUwtqW8'
|
|
23
|
+
restore(/* model reply with synthetics */)
|
|
24
|
+
// → originals back, byte-identical
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Contents
|
|
28
|
+
|
|
29
|
+
- [Status](#status) · [What it detects](#what-it-detects) · [Requirements](#requirements)
|
|
30
|
+
- [Installation](#installation) · [Quick start](#quick-start) · [Guarantees](#guarantees)
|
|
31
|
+
- [Testing](#testing) · [Honest gaps](#honest-gaps) · [Architecture](#architecture)
|
|
32
|
+
- [Publishing](#publishing) · [Contributing](#contributing) · [License](#license)
|
|
33
|
+
- [Further reading](#further-reading)
|
|
34
|
+
|
|
35
|
+
## Status
|
|
36
|
+
|
|
37
|
+
| Phase | Description | Status |
|
|
38
|
+
|-------|-------------|--------|
|
|
39
|
+
| 1 | `@pratikw/detect` — detection engine, Faker synthesis, vault, `detect/cloak/restore` | ✅ Done |
|
|
40
|
+
| 2 | OpenCode plugin — 5 hooks, `/datacloak` command, JSON config | ⬜ Next |
|
|
41
|
+
| 3 | Browser extension — Chrome/Edge MV3, auto-cloak, session vault, response restore | ⬜ Planned |
|
|
42
|
+
| 4 | NER (`detect-ner`, ONNX) — names, addresses, DOB | ⬜ Planned |
|
|
43
|
+
| 5 | Teams + CI (`datacloak scan`, shared config, VS Code) | ⬜ Planned |
|
|
44
|
+
|
|
45
|
+
## What it detects
|
|
46
|
+
|
|
47
|
+
| Category | Coverage |
|
|
48
|
+
|----------|----------|
|
|
49
|
+
| API keys | OpenAI, Anthropic, AWS, GitHub PAT, Stripe |
|
|
50
|
+
| Tokens | JWT, PEM private keys, high-entropy strings (Shannon ≥ 4.5) |
|
|
51
|
+
| Credentials | Env `KEY=value` (50+ key names), DSNs (postgres, mongo, redis, mysql, amqp), inline JSON/YAML secrets |
|
|
52
|
+
| PII | Email, US + E.164 phones, IPv4 |
|
|
53
|
+
|
|
54
|
+
## Requirements
|
|
55
|
+
|
|
56
|
+
- `node` ≥ 18, `npm`
|
|
57
|
+
|
|
58
|
+
No account, no server, no network calls. Everything runs in-process.
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
One-liner:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
curl -fsSL https://raw.githubusercontent.com/pratikwayal01/datacloak/master/install.sh | bash
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or with npm directly:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm install -g @pratikw/detect
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
From source:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git clone https://github.com/pratikwayal01/datacloak.git && cd datacloak
|
|
78
|
+
npm install
|
|
79
|
+
npm run build --workspace packages/detect # tsc → packages/detect/dist/
|
|
80
|
+
npm test --workspace packages/detect # 28 tests
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Quick start
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import { DataCloakEngine } from '@pratikw/detect';
|
|
87
|
+
|
|
88
|
+
const cloak = new DataCloakEngine();
|
|
89
|
+
|
|
90
|
+
// Outbound: real values → synthetics (vault remembers the mapping)
|
|
91
|
+
const out = cloak.cloak(
|
|
92
|
+
'DATABASE_URL=postgres://alice:s3cr3t@db.prod.acme.com:5432/users'
|
|
93
|
+
);
|
|
94
|
+
// → 'DATABASE_URL=postgres://Kaelyn_Torp80:SYNTHpw53@hefty-curl.com:5432/users'
|
|
95
|
+
// key name preserved, protocol/port/path intact, user/pass/host faked
|
|
96
|
+
|
|
97
|
+
// Inbound: model echoes synthetics → restore originals before display
|
|
98
|
+
const back = cloak.restore(modelReply);
|
|
99
|
+
// → { text: '...db.prod.acme.com...', restored: 2 }
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
(From source, import from `'./packages/detect/dist/engine.js'` instead.)
|
|
103
|
+
|
|
104
|
+
## Guarantees
|
|
105
|
+
|
|
106
|
+
Rules that hold on every call:
|
|
107
|
+
|
|
108
|
+
- **Consistent identity** — same original → same synthetic within a session.
|
|
109
|
+
- **Service-invalid fakes** — synthetic secrets carry a `SYNTH` infix:
|
|
110
|
+
structurally valid, visually identifiable, fail authentication.
|
|
111
|
+
- **Key names preserved** — env vars and DSNs keep protocol, port, path
|
|
112
|
+
and key names; only secret values are faked.
|
|
113
|
+
- **Safe fallback** — unknown formats become opaque `[CATEGORY_XXXXXX]` tokens.
|
|
114
|
+
- **Extensible** — custom regex patterns with loud load-time validation.
|
|
115
|
+
- **Local only** — the vault is in-memory, never written to disk.
|
|
116
|
+
|
|
117
|
+
## Testing
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npm test --workspace packages/detect
|
|
121
|
+
# vault, patterns, entropy, synthesizers, engine — 5 suites, 28/28 green
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- Corpus recall: 39/39 labeled samples (100%, gate ≥ 95%) — `test/corpus.jsonl`
|
|
125
|
+
- Perf: ~9.5ms to cloak 12KB (guard < 200ms)
|
|
126
|
+
- Synthesis pins: phones locked to fictional `555-01` / `+44770090` ranges,
|
|
127
|
+
JWT encoder UTF-8-safe with NumericDate seconds
|
|
128
|
+
|
|
129
|
+
## Honest gaps
|
|
130
|
+
|
|
131
|
+
Surfaced during implementation, all tracked (none hidden):
|
|
132
|
+
|
|
133
|
+
- Phones match substrings of longer digit runs — recall-oriented MVP tradeoff.
|
|
134
|
+
- `cloak()` has no per-item try/catch; only null-synthesizer fallback is
|
|
135
|
+
covered (`opaqueToken`), a throwing custom synthesizer would propagate.
|
|
136
|
+
- Opaque-token fallback skips the input-collision check (negligible: random 6-char suffix).
|
|
137
|
+
- `restore().restored` counts distinct vault entries hit, not total occurrences.
|
|
138
|
+
- Env regex is line-anchored — mid-line `export KEY=v` is missed by design.
|
|
139
|
+
- Corpus is 39 samples, not the 500+ planned for Phase 1 full.
|
|
140
|
+
- No NER yet: names, street addresses, DOB need co-located signals or wait for Phase 4.
|
|
141
|
+
|
|
142
|
+
## Architecture
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
packages/detect/src/
|
|
146
|
+
├── engine.ts # DataCloakEngine: detect(), cloak(), restore()
|
|
147
|
+
├── patterns/ # secrets.ts, credentials.ts, pii.ts → index.ts registry
|
|
148
|
+
├── entropy.ts # Shannon scan (≥4.5, ≥20 chars, UUID/image skips)
|
|
149
|
+
├── synthesizers/ # pii.ts, secrets.ts, credentials.ts → index.ts registry
|
|
150
|
+
├── tokens.ts # opaque [CATEGORY_XXXXXX] fallback
|
|
151
|
+
├── vault.ts # bidirectional Map + LRU(2000)
|
|
152
|
+
└── types.ts # Detection, CloakResult, VaultEntry, Config
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Two-pass detection: compiled RegExp registry in priority order with
|
|
156
|
+
longest-match de-overlap, then an entropy sweep for anything the patterns
|
|
157
|
+
missed. Synthesis is per-category Faker calls; the vault maps
|
|
158
|
+
`synthetic ↔ original` in memory only — never written to disk.
|
|
159
|
+
|
|
160
|
+
## Publishing
|
|
161
|
+
|
|
162
|
+
Maintainer-only. Releases go out via the
|
|
163
|
+
[`publish-detect`](.github/workflows/publish.yml) workflow
|
|
164
|
+
(repo secret `NPM_TOKEN` needs publish rights on the `@pratikw` scope):
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# bump version in packages/detect/package.json, then:
|
|
168
|
+
git tag detect-v0.1.1 && git push origin detect-v0.1.1
|
|
169
|
+
# CI builds, tests, checks tag == package version, publishes with provenance
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Contributing
|
|
173
|
+
|
|
174
|
+
Design-then-plan-then-build: spec docs live in `docs/superpowers/specs/`,
|
|
175
|
+
implementation plans in `docs/superpowers/plans/` — one written plan per
|
|
176
|
+
slice before code. Per-task review (spec + quality) gates every change.
|
|
177
|
+
Threat model → `.opencode/datacloak-prd.md` §11 (read it before touching
|
|
178
|
+
detection semantics).
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT — see [LICENSE](LICENSE).
|
|
183
|
+
|
|
184
|
+
## Further reading
|
|
185
|
+
|
|
186
|
+
- [`.opencode/datacloak-prd.md`](https://github.com/pratikwayal01/datacloak/blob/master/.opencode/datacloak-prd.md) — full PRD (vision, both surfaces, roadmap)
|
|
187
|
+
- [`docs/superpowers/specs/2026-09-24-detect-engine-mvp-design.md`](https://github.com/pratikwayal01/datacloak/blob/master/docs/superpowers/specs/2026-09-24-detect-engine-mvp-design.md) — engine design
|
|
188
|
+
- [`docs/superpowers/plans/2026-09-24-detect-engine-mvp.md`](https://github.com/pratikwayal01/datacloak/blob/master/docs/superpowers/plans/2026-09-24-detect-engine-mvp.md) — implementation plan
|
|
189
|
+
- `assets/` — launch video (`brag.mp4`), poster
|
package/package.json
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pratikw/detect",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/engine.js",
|
|
6
6
|
"types": "dist/engine.d.ts",
|
|
7
|
-
"
|
|
7
|
+
"description": "Local-first cloak for AI prompts: secrets/PII become realistic fakes before the model, originals restored on return.",
|
|
8
|
+
"files": ["dist", "README.md", "LICENSE"],
|
|
8
9
|
"publishConfig": { "access": "public" },
|
|
9
10
|
"repository": {
|
|
10
11
|
"type": "git",
|
|
11
12
|
"url": "git+https://github.com/pratikwayal01/datacloak.git",
|
|
12
13
|
"directory": "packages/detect"
|
|
13
14
|
},
|
|
14
|
-
"scripts": {
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"prepublishOnly": "cp ../../README.md ./README.md && cp ../../LICENSE ./LICENSE && sed -i -e 's#](assets/#](https://raw.githubusercontent.com/pratikwayal01/datacloak/master/assets/#g' -e 's#](docs/#](https://github.com/pratikwayal01/datacloak/blob/master/docs/#g' -e 's#](.opencode/#](https://github.com/pratikwayal01/datacloak/blob/master/.opencode/#g' ./README.md && npm run build && npm test"
|
|
19
|
+
},
|
|
15
20
|
"dependencies": { "@faker-js/faker": "^10.6.0" },
|
|
16
21
|
"devDependencies": { "typescript": "~5.6.3", "vitest": "^3.0.0" }
|
|
17
22
|
}
|