@sanity-labs/secret-scan 0.2.0 → 1.1.0

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/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # @sanity-labs/secret-scan
2
2
 
3
- Detect and redact secrets in strings. Works in browser and Node.js. Zero runtime dependencies.
3
+ Detect and redact secrets in strings. Designed for **chat and paste contexts** where secrets appear without surrounding code context.
4
4
 
5
- Rules derived from [gitleaks](https://github.com/gitleaks/gitleaks) (MIT licensed) — 221 rules covering API keys, tokens, passwords, and credentials from 100+ providers.
5
+ - **1,100+ detection rules** extracted from [TruffleHog](https://github.com/trufflesecurity/trufflehog) detectors
6
+ - **Zero runtime dependencies** — works in browser and Node.js
7
+ - **Fast** — keyword pre-filtering means most rules are skipped for any given input (~0.15ms for short messages)
8
+ - **Two functions** — `scan(input)` finds secrets, `redact(input, replacer)` replaces them
6
9
 
7
10
  ## Install
8
11
 
@@ -12,114 +15,81 @@ npm install @sanity-labs/secret-scan
12
15
 
13
16
  ## Usage
14
17
 
15
- ### `scan` — find secrets
16
-
17
18
  ```typescript
18
- import { scan } from '@sanity-labs/secret-scan'
19
-
20
- const secrets = scan('OPENAI_API_KEY=sk-proj-abc123...\nMODE=production')
21
- // [
22
- // {
23
- // rule: 'openai-api-key',
24
- // label: 'OpenAI API Key',
25
- // text: 'sk-proj-abc123...',
26
- // confidence: 'high',
27
- // start: 15,
28
- // end: 32
29
- // }
30
- // ]
19
+ import { scan, redact } from '@sanity-labs/secret-scan'
20
+
21
+ // Find secrets
22
+ const secrets = scan('my key is ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh1234')
23
+ // [{ rule: 'github-v2', label: 'Github V2', text: 'ghp_...', confidence: 'high', start: 10, end: 50 }]
24
+
25
+ // Redact secrets
26
+ const safe = redact(input, (secret, index) => `[secret:${index}]`)
27
+ // 'my key is [secret:0]'
31
28
  ```
32
29
 
33
- ### `redact` find and replace secrets
30
+ ## What it detects
31
+
32
+ Bare paste (no surrounding context needed):
33
+
34
+ | Provider | Prefix/Pattern | Rule ID |
35
+ |----------|---------------|---------|
36
+ | OpenAI | `sk-proj-...T3BlbkFJ...` | `openai` |
37
+ | Anthropic | `sk-ant-api03-...` | `anthropic` |
38
+ | AWS | `AKIA...` | `aws-access_keys` |
39
+ | GitHub | `ghp_`, `gho_`, `github_pat_` | `github-v2` |
40
+ | Stripe | `sk_live_`, `rk_live_` | `stripe` |
41
+ | Slack | `xoxb-`, `xoxp-` | `slack` |
42
+ | Groq | `gsk_` | `groq` |
43
+ | Replicate | `r8_` | `replicate` |
44
+ | SendGrid | `SG.` | `sendgrid` |
45
+ | JWT | `eyJ...` | `jwt` |
46
+ | GitLab | `glpat-` | `gitlab-v2` |
47
+ | NPM | `npm_` | `npmtokenv2` |
48
+ | Linear | `lin_api_` | `linearapi` |
49
+ | Supabase | `sbp_` | `supabasetoken` |
50
+ | Postman | `PMAK-` | `postman` |
51
+
52
+ Plus 850+ more providers. Connection strings (postgres://, mongodb://, redis://) and Bearer tokens are also detected.
34
53
 
35
- ```typescript
36
- import { redact } from '@sanity-labs/secret-scan'
54
+ ## How it works
37
55
 
38
- const secrets = new Map()
39
- let nextId = 0
56
+ Rules are extracted from [TruffleHog's Go detectors](https://github.com/trufflesecurity/trufflehog/tree/main/pkg/detectors) and compiled to JavaScript RegExp. TruffleHog's keyword pre-filter uses strings from the **secret itself** (prefixes like `gsk_`, `T3BlbkFJ`), not surrounding context — this is why it works for bare paste in chat.
40
57
 
41
- const redacted = redact(pastedText, (secret) => {
42
- const key = `[secret:${nextId++}]`
43
- secrets.set(key, secret)
44
- return key
45
- })
58
+ A keyword index maps each keyword to its rules. For any input, only rules whose keywords appear in the input are tested — typically <10 rules out of 1,100+.
46
59
 
47
- // redacted: "OPENAI_API_KEY=[secret:0]\nSTRIPE_KEY=[secret:1]"
48
- // secrets: Map { '[secret:0]' => { text: 'sk-proj-...' }, ... }
60
+ ### Updating rules
61
+
62
+ ```bash
63
+ npm run update-rules
49
64
  ```
50
65
 
66
+ This clones/updates TruffleHog, parses all detector Go files, converts Go regex to JS, and regenerates `src/rules.ts`.
67
+
51
68
  ## API
52
69
 
53
70
  ### `scan(input: string): Secret[]`
54
71
 
55
- Returns an array of every secret found in the input.
56
-
57
- ### `redact(input: string, replacer: (secret: Secret) => string): string`
58
-
59
- Calls `replacer` for each detected secret. The return value replaces the secret in the output string. The caller owns all state — `redact` just does string replacement.
60
-
61
- ### `Secret`
72
+ Returns all secrets found in the input string.
62
73
 
63
74
  ```typescript
64
75
  interface Secret {
65
- rule: string // gitleaks rule ID, e.g. 'openai-api-key'
66
- label: string // human-readable, e.g. 'OpenAI API Key'
67
- text: string // the matched secret value
68
- confidence: 'high' | 'medium' // provider pattern vs entropy-based
69
- start: number // start index in input
70
- end: number // end index (exclusive) in input
76
+ rule: string // Rule ID (e.g., 'openai')
77
+ label: string // Human-readable label
78
+ text: string // The matched secret value
79
+ confidence: 'high' | 'medium'
80
+ start: number // Start index in input
81
+ end: number // End index (exclusive)
71
82
  }
72
83
  ```
73
84
 
74
- ### `shannonEntropy(s: string): number`
75
-
76
- Shannon entropy calculation. Exported for advanced use cases.
77
-
78
- ## How it works
79
-
80
- 1. **Keyword pre-filter** — Each rule has keywords. Before running a regex, we check if the input contains any of its keywords (case-insensitive). This keeps scanning fast with 221 rules — most regexes are skipped for any given input.
81
-
82
- 2. **Regex matching** — Rules are compiled from [gitleaks.toml](https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.toml) with Go→JS regex conversion (named groups, inline flags, dotall).
83
-
84
- 3. **Entropy filtering** — Many rules have Shannon entropy thresholds. Low-entropy matches (like `KEY=aaaaaaa`) are filtered out.
85
-
86
- 4. **Allowlist filtering** — Global and per-rule allowlists filter false positives. Includes 1,446 stopwords for the generic-api-key rule.
87
-
88
- ## Updating rules
89
-
90
- ```bash
91
- npm run update-rules
92
- ```
93
-
94
- Fetches the latest `gitleaks.toml` from GitHub, converts Go regex → JS regex, and writes `src/rules.ts`. Run this whenever gitleaks updates their rules.
95
-
96
- ### Go → JS regex conversion
97
-
98
- | Go pattern | JS equivalent | Notes |
99
- |---|---|---|
100
- | `(?P<name>...)` | `(?<name>...)` | Named groups |
101
- | `(?i)` at start | `i` flag | Case-insensitive |
102
- | `(?i:...)` mid-pattern | `(?:...)` + `i` flag | Promoted to global flag |
103
- | `(?-i:...)` | `(?:...)` | Groups already enumerate cases |
104
- | `(?s:.)` | `[\s\S]` | Dotall |
105
- | `\z` | `$` | End of string |
106
-
107
- ## Rules coverage
85
+ ### `redact(input: string, replacer: (secret: Secret) => string): string`
108
86
 
109
- 221 rules from gitleaks covering:
87
+ Finds and replaces all secrets. Replacements applied right-to-left to preserve indices.
110
88
 
111
- - **Cloud providers**: AWS, GCP, Azure, DigitalOcean, Heroku, Fly.io, etc.
112
- - **AI/ML**: OpenAI, Anthropic, Cohere, HuggingFace, Perplexity
113
- - **Payment**: Stripe, Square, Plaid, Coinbase, Flutterwave
114
- - **DevOps**: GitHub, GitLab, Bitbucket, CircleCI, Travis CI, Jenkins
115
- - **Communication**: Slack, Discord, Telegram, Twilio, SendGrid
116
- - **Databases**: PlanetScale, MongoDB Atlas, ClickHouse
117
- - **And 80+ more providers**
89
+ ### `shannonEntropy(s: string): number`
118
90
 
119
- Plus the `generic-api-key` rule which catches `KEY=value` patterns with entropy thresholds and 1,446 stopwords.
91
+ Calculate Shannon entropy of a string. Used internally for entropy-based filtering.
120
92
 
121
93
  ## License
122
94
 
123
- MIT includes gitleaks copyright notice per their license terms.
124
-
125
- This package uses rules derived from [gitleaks](https://github.com/gitleaks/gitleaks), which is also MIT licensed. Copyright (c) 2019 Zachary Rice.
95
+ MIT. Rules derived from [TruffleHog](https://github.com/trufflesecurity/trufflehog) (Apache 2.0).