{"_id":"@sanity-labs/secret-scan","_rev":"18-16d7538abbd6c4daeedc0d5705c42693","name":"@sanity-labs/secret-scan","dist-tags":{"latest":"1.1.0"},"versions":{"0.1.0":{"name":"@sanity-labs/secret-scan","version":"0.1.0","keywords":["secret","scan","detect","redact","gitleaks","security"],"license":"MIT","_id":"@sanity-labs/secret-scan@0.1.0","maintainers":[{"name":"simen.svale","email":"simen@sanity.io"},{"name":"joshbrand","email":"josh@homph.co"},{"name":"kmelve","email":"knut.melvaer@gmail.com"},{"name":"rostimelk","email":"hello@rosti.no"},{"name":"jw-sanity","email":"jack.wilson@sanity.io"}],"homepage":"https://github.com/sanity-labs/secret-scan#readme","bugs":{"url":"https://github.com/sanity-labs/secret-scan/issues"},"dist":{"shasum":"ab0b09e2e18e54d9c2de8e9faefa95c088fc01fa","tarball":"https://registry.npmjs.org/@sanity-labs/secret-scan/-/secret-scan-0.1.0.tgz","fileCount":9,"integrity":"sha512-turU40UkscT7GxYOX6Yuyuk9Obl+K4cMq3Z72bxCc4wI18LdZJSD3DYlBg/Niypmosyk/vm8QAUKisllmE2THg==","signatures":[{"sig":"MEQCIC/Ym/M6EGm2ZC9ckN26cwqkjLxVX7wtQVK3WcVS8IqLAiAvUM4J1psCte/4R+Y2MRLSZjAunp3Fsmb4XZ8/PKUKBQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":506558},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"9871ccd5d451a6c976101870008a839146549473","scripts":{"test":"vitest run","build":"tsup","test:watch":"vitest","update-rules":"tsx scripts/update-rules.ts","prepublishOnly":"npm run build"},"_npmUser":{"name":"simen.svale","email":"simen@sanity.io"},"repository":{"url":"git+https://github.com/sanity-labs/secret-scan.git","type":"git"},"_npmVersion":"10.8.2","description":"Secret detection library based on gitleaks rules","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","tsup":"^8.0.0","vitest":"^3.0.0","typescript":"^5.7.0","@iarna/toml":"^2.2.5"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.1.0_1771195660622_0.6291271873043225","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@sanity-labs/secret-scan","version":"0.2.0","keywords":["secret","scan","detect","redact","gitleaks","security"],"license":"MIT","_id":"@sanity-labs/secret-scan@0.2.0","maintainers":[{"name":"simen.svale","email":"simen@sanity.io"},{"name":"joshbrand","email":"josh@homph.co"},{"name":"kmelve","email":"knut.melvaer@gmail.com"},{"name":"rostimelk","email":"hello@rosti.no"},{"name":"jw-sanity","email":"jack.wilson@sanity.io"}],"homepage":"https://github.com/sanity-labs/secret-scan#readme","bugs":{"url":"https://github.com/sanity-labs/secret-scan/issues"},"dist":{"shasum":"10757b8c1086e96e6495b4be60efa62e66c9249d","tarball":"https://registry.npmjs.org/@sanity-labs/secret-scan/-/secret-scan-0.2.0.tgz","fileCount":9,"integrity":"sha512-iIQdCZLpXJLgvkV4p69bsIR439Zv5bXi5uh7NX0kQMJCt5tJ2uFpDHTank4WWiR/X0hGvHSaPUj+xl025EXt5A==","signatures":[{"sig":"MEUCIBw90RNX0r69ZHeQbC/D9cP5gxRQkmIiv56BAymyz4hmAiEA9D2C5iYzpbhCjDIxR/ecpfAH4RrlbiEd2+x7LuKuU4U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":506617},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"28a380022531fc3269e1d5f2754298c0548afc36","scripts":{"test":"vitest run","build":"tsup","test:watch":"vitest","update-rules":"tsx scripts/update-rules.ts","prepublishOnly":"npm run build","update-fixtures":"bash scripts/extract-fixtures.sh"},"_npmUser":{"name":"simen.svale","email":"simen@sanity.io"},"repository":{"url":"git+https://github.com/sanity-labs/secret-scan.git","type":"git"},"_npmVersion":"10.8.2","description":"Secret detection library based on gitleaks rules","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","tsup":"^8.0.0","vitest":"^3.0.0","typescript":"^5.7.0","@iarna/toml":"^2.2.5"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_0.2.0_1771198370306_0.919889023654082","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@sanity-labs/secret-scan","version":"1.0.0","keywords":["secret","scan","detect","redact","trufflehog","security","chat"],"license":"MIT","_id":"@sanity-labs/secret-scan@1.0.0","maintainers":[{"name":"simen.svale","email":"simen@sanity.io"},{"name":"joshbrand","email":"josh@homph.co"},{"name":"kmelve","email":"knut.melvaer@gmail.com"},{"name":"rostimelk","email":"hello@rosti.no"},{"name":"jw-sanity","email":"jack.wilson@sanity.io"}],"homepage":"https://github.com/sanity-labs/secret-scan#readme","bugs":{"url":"https://github.com/sanity-labs/secret-scan/issues"},"dist":{"shasum":"50d0834e0665e1b9752178fbf478cd2b4bb14ed5","tarball":"https://registry.npmjs.org/@sanity-labs/secret-scan/-/secret-scan-1.0.0.tgz","fileCount":9,"integrity":"sha512-mqooJ2414vN38WsZBSjhDv3+pF+YoNfMI6SlTkt8kIaAMn8sTIlbm70AZ0jNxT0oIs9xSEOKyd7g3uBSwTDo/w==","signatures":[{"sig":"MEUCIQDVFozZt8Z3qo2kH8CJJTVpm0emdOXAyO5tsVNSJL6zVQIgNxpF6LhiUu/h9hKvgIlWerStr45y5SN3AjMUhOjl4fw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1084812},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"54d0b3580c9fca2eb7cdd8c928f8875c8870ba05","scripts":{"test":"vitest run","build":"tsup","test:watch":"vitest","update-rules":"tsx scripts/update-rules.ts","prepublishOnly":"npm run build"},"_npmUser":{"name":"simen.svale","email":"simen@sanity.io"},"repository":{"url":"git+https://github.com/sanity-labs/secret-scan.git","type":"git"},"_npmVersion":"10.8.2","description":"Secret detection library for chat and paste contexts. 1,100+ rules from TruffleHog detectors.","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","tsup":"^8.0.0","vitest":"^3.0.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_1.0.0_1771213351968_0.3696815550181616","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@sanity-labs/secret-scan","version":"1.1.0","keywords":["secret","scan","detect","redact","trufflehog","security","chat"],"license":"MIT","_id":"@sanity-labs/secret-scan@1.1.0","maintainers":[{"name":"simen.svale","email":"simen@sanity.io"},{"name":"joshbrand","email":"josh@homph.co"},{"name":"kmelve","email":"knut.melvaer@gmail.com"},{"name":"rostimelk","email":"hello@rosti.no"},{"name":"jw-sanity","email":"jack.wilson@sanity.io"}],"homepage":"https://github.com/sanity-labs/secret-scan#readme","bugs":{"url":"https://github.com/sanity-labs/secret-scan/issues"},"dist":{"shasum":"b04c8da5a34613f26defc9b860b4c702fc1506e3","tarball":"https://registry.npmjs.org/@sanity-labs/secret-scan/-/secret-scan-1.1.0.tgz","fileCount":9,"integrity":"sha512-hL1NgR9ClU+sMR5FTIa9mBeIhQLQmYasHW9w70xl+DRJB6zDStx6aJL2YGFcUs+bg9Jg3aUIz/i63W95Jo2p1A==","signatures":[{"sig":"MEQCIGv4e1K02U0T+CQnuEv+aqLmyLDmgQIjBAOkFm9/2dSvAiBbv2yixmMEk25ZoYUtvC6zte2fukBKXHPdNM1knxEubQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1106300},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"5a87ee83e97c532c515aa98a794bf0bd8f26407d","scripts":{"test":"vitest run","build":"tsup","test:watch":"vitest","update-rules":"tsx scripts/update-rules.ts","prepublishOnly":"npm run build"},"_npmUser":{"name":"simen.svale","email":"simen@sanity.io"},"repository":{"url":"git+https://github.com/sanity-labs/secret-scan.git","type":"git"},"_npmVersion":"10.8.2","description":"Secret detection library for chat and paste contexts. 1,100+ rules from TruffleHog detectors.","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.0.0","tsup":"^8.0.0","vitest":"^3.0.0","typescript":"^5.7.0"},"_npmOperationalInternal":{"tmp":"tmp/secret-scan_1.1.0_1771215446795_0.32187459826687137","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-02-15T22:47:40.456Z","modified":"2026-09-03T12:55:35.857Z","0.1.0":"2026-02-15T22:47:40.752Z","0.2.0":"2026-02-15T23:32:50.482Z","1.0.0":"2026-02-16T03:42:32.120Z","1.1.0":"2026-02-16T04:17:27.009Z"},"bugs":{"url":"https://github.com/sanity-labs/secret-scan/issues"},"license":"MIT","homepage":"https://github.com/sanity-labs/secret-scan#readme","keywords":["secret","scan","detect","redact","trufflehog","security","chat"],"repository":{"url":"git+https://github.com/sanity-labs/secret-scan.git","type":"git"},"description":"Secret detection library for chat and paste contexts. 1,100+ rules from TruffleHog detectors.","maintainers":[{"email":"simen@sanity.io","name":"simen.svale"},{"email":"matthew.dent@sanity.io","name":"mttdnt-sanity"},{"email":"stipsan@gmail.com","name":"stipsan"},{"email":"josh@homph.co","name":"joshbrand"},{"email":"herman@sanity.io","name":"hermanw"},{"email":"cole.peters@sanity.io","name":"colepeters-sanity"},{"email":"studio@mariuslundgard.com","name":"mariuslundgard"},{"email":"lauren.ashpole@sanity.io","name":"laurenashpolesanity"},{"email":"robin.pyon@gmail.com","name":"robinpyon"},{"email":"sam.hemingway@sanity.io","name":"samhem"},{"email":"sergei@sanity.io","name":"sergeisarviro"},{"email":"espen@hovlandsdal.com","name":"rexxars"},{"email":"snorre.e.brekke@gmail.com","name":"snorreeb"},{"email":"nicholas@sanity.io","name":"nicholasklem"},{"email":"tbeseda@gmail.com","name":"tbeseda"},{"email":"knut.melvaer@gmail.com","name":"kmelve"},{"email":"hello@rosti.no","name":"rostimelk"},{"email":"jack.wilson@sanity.io","name":"jw-sanity"},{"email":"james.woods@sanity.io","name":"jwoods-sanity"}],"readme":"# @sanity-labs/secret-scan\n\nDetect and redact secrets in strings. Designed for **chat and paste contexts** where secrets appear without surrounding code context.\n\n- **1,100+ detection rules** extracted from [TruffleHog](https://github.com/trufflesecurity/trufflehog) detectors\n- **Zero runtime dependencies** — works in browser and Node.js\n- **Fast** — keyword pre-filtering means most rules are skipped for any given input (~0.15ms for short messages)\n- **Two functions** — `scan(input)` finds secrets, `redact(input, replacer)` replaces them\n\n## Install\n\n```bash\nnpm install @sanity-labs/secret-scan\n```\n\n## Usage\n\n```typescript\nimport { scan, redact } from '@sanity-labs/secret-scan'\n\n// Find secrets\nconst secrets = scan('my key is ghp_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh1234')\n// [{ rule: 'github-v2', label: 'Github V2', text: 'ghp_...', confidence: 'high', start: 10, end: 50 }]\n\n// Redact secrets\nconst safe = redact(input, (secret, index) => `[secret:${index}]`)\n// 'my key is [secret:0]'\n```\n\n## What it detects\n\nBare paste (no surrounding context needed):\n\n| Provider | Prefix/Pattern | Rule ID |\n|----------|---------------|---------|\n| OpenAI | `sk-proj-...T3BlbkFJ...` | `openai` |\n| Anthropic | `sk-ant-api03-...` | `anthropic` |\n| AWS | `AKIA...` | `aws-access_keys` |\n| GitHub | `ghp_`, `gho_`, `github_pat_` | `github-v2` |\n| Stripe | `sk_live_`, `rk_live_` | `stripe` |\n| Slack | `xoxb-`, `xoxp-` | `slack` |\n| Groq | `gsk_` | `groq` |\n| Replicate | `r8_` | `replicate` |\n| SendGrid | `SG.` | `sendgrid` |\n| JWT | `eyJ...` | `jwt` |\n| GitLab | `glpat-` | `gitlab-v2` |\n| NPM | `npm_` | `npmtokenv2` |\n| Linear | `lin_api_` | `linearapi` |\n| Supabase | `sbp_` | `supabasetoken` |\n| Postman | `PMAK-` | `postman` |\n\nPlus 850+ more providers. Connection strings (postgres://, mongodb://, redis://) and Bearer tokens are also detected.\n\n## How it works\n\nRules 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.\n\nA 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+.\n\n### Updating rules\n\n```bash\nnpm run update-rules\n```\n\nThis clones/updates TruffleHog, parses all detector Go files, converts Go regex to JS, and regenerates `src/rules.ts`.\n\n## API\n\n### `scan(input: string): Secret[]`\n\nReturns all secrets found in the input string.\n\n```typescript\ninterface Secret {\n  rule: string        // Rule ID (e.g., 'openai')\n  label: string       // Human-readable label\n  text: string        // The matched secret value\n  confidence: 'high' | 'medium'\n  start: number       // Start index in input\n  end: number         // End index (exclusive)\n}\n```\n\n### `redact(input: string, replacer: (secret: Secret) => string): string`\n\nFinds and replaces all secrets. Replacements applied right-to-left to preserve indices.\n\n### `shannonEntropy(s: string): number`\n\nCalculate Shannon entropy of a string. Used internally for entropy-based filtering.\n\n## License\n\nMIT. Rules derived from [TruffleHog](https://github.com/trufflesecurity/trufflehog) (Apache 2.0).\n","readmeFilename":"README.md"}