npm package · MIT · Node ≥ 18

bundle-secret-guard

Fail the build when secrets ship to the browser.

Scans your built frontend (dist/, build/, out/, .next/static), including source maps, for provider keys like AWS, Stripe, GitHub, OpenAI, Anthropic and Supabase service_role, and for any server-only .env value that got inlined. Every finding is redacted and comes with a specific fix.

npm i -D bundle-secret-guard
~/project — zsh
$ npx bundle-secret-guard -e .env dist/assets/index-DMZFQv-v.js  ✖ error Stripe secret/restricted live key [stripe-secret-key]          dist/assets/index-DMZFQv-v.js:1:720  sk_l…(36 chars)          fix: Rotate the key immediately (Stripe Dashboard → Developers → API keys → Roll key)  ✖ error Server-only env value found in bundle [env-leak]          Value of STRIPE_SECRET (from .env) appears literally in the bundle.          fix: Move the call that needs this key to a server/API route dist/assets/index-DMZFQv-v.js.map  ⚠ warn  Source map shipped [source-map]          fix: Vite: build.sourcemap = false or "hidden" and don't deploy *.map. 3 file(s) scanned: 4 error(s), 1 warning(s)
Sample output from the bundle-secret-guard README.

The problem

One import from the wrong file, or a secret in a VITE_ / NEXT_PUBLIC_ variable, and your Stripe or OpenAI key is sitting in a public JavaScript bundle. Repository secret scanners never see it, because the leak only exists in build output.

bundle-secret-guard scans what you actually deploy, cross-checks it against your .env files, and fails the build before the key goes live.

Features

Provider patterns

AWS, Stripe, GitHub, Slack, OpenAI, Anthropic, Google, Twilio, SendGrid, Mailgun, npm, private keys, database URLs and more.

.env cross-check

Any non-public .env value that appears literally in the bundle is an error; secret-looking public-prefix vars are flagged too.

Source maps scanned

Shipped .map files are flagged and their sourcesContent is scanned as well.

gitleaks rules

Import your existing gitleaks TOML rules with --gitleaks.

Entropy + baseline

Optional high-entropy detection, with a detect-secrets style baseline stored as SHA-256 hashes only.

Opt-in live verification

--verify checks supported tokens against only that provider's own API. Off by default.

Redacted output

Secrets are never printed in full: only the first 4 characters and the length.

Plugins & SARIF

Vite and webpack plugins, JSON and SARIF output, zero runtime dependencies.

Usage

# Scan after building

 npx bundle-secret-guard dist

# Cross-check .env files

 npx bundle-secret-guard dist -e .env -e .env.production

# Use gitleaks rules

 npx bundle-secret-guard dist --gitleaks .gitleaks.toml

# Next.js build script

 next build && bundle-secret-guard .next/static -e .env -e .env.production

CI / GitHub Action

# .github/workflows/bundle-secrets.yml
name: Bundle secrets
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    permissions: { contents: read, security-events: write }
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20 }
      - run: npm ci && npm run build
      - uses: MrLouisWright/bundle-secret-guard@v1
        with:
          dirs: dist
          env-files: .env.production
          sarif: bundle-secrets.sarif
      - if: always()
        uses: github/codeql-action/upload-sarif@v3
        with: { sarif_file: bundle-secrets.sarif }

Options & flags

FlagDescription
[dir...]Build directories (default: auto-detect dist, build, out, .next/static, .output/public, .svelte-kit/output/client)
-e, --env-file <file>.env file to cross-check (repeatable)
-c, --config <file>JSON config (default: .envleakrc.json / .bundlesecretguardrc.json / bundle-secret-guard.config.json)
--fail-on <level>error | warn | none (default: error)
--jsonPrint JSON results
--sarif [file]Print SARIF 2.1.0 (or write to file)
--max-file-size <n>Skip files bigger than n bytes (default 5mb; accepts 500kb, 10mb)
--public-prefix <p>Extra public env prefix (repeatable)
--gitleaks <file>gitleaks TOML rules (repeatable)
--baseline <file>Baseline JSON (suppress known hashed findings)
--update-baselineWrite new findings to the baseline (hashes only)
--entropy-scanExtra high-entropy string detection
--verifyOpt-in live-key check via each provider's API (off by default)
--no-infoHide info-level findings

Full reference, config file format and API in the README.

Support this project

Support open-source security tools

I build free, open-source tools that help developers ship safer websites. Every coffee helps keep them maintained, documented and free for everyone.

Buy me a coffee (opens Stripe in a new tab)

Secure checkout by Stripe

Portrait of Louis Wright

About the author

Louis Wright

Cyber security researcher and software engineer based in the UK.

More tools by Louis Wright

58 tools

Sentinels security scanners & CI gates · 20