Skip to main content

hush 🤫

A zero-dependency, git-aware secret scanner. Keep your keys hushed.

hush finds leaked credentials — API keys, tokens, private keys — in your code, your staged changes, and your git history, before they end up in a public repo. It's a single pure-Python package with no runtime dependencies: nothing to compile, no supply chain to trust, pip install and go.

CRITICAL src/config.py:12
         AWS Access Key ID [aws-access-key-id]
         AKIA****************  (entropy 3.68)

CRITICAL src/config.py:13
         GitHub Personal Access / OAuth / App Token [github-token]
         ghp_****************************aaaa  (entropy 4.90)

Found 2 potential secret(s): 2 critical

Why another secret scanner?

There are great tools out there (gitleaks, trufflehog, detect-secrets). hush makes a few deliberate trade-offs:

  • Zero dependencies. Pure Python standard library. The whole tool is a few hundred readable lines — audit it in an afternoon, extend it in a minute.
  • Two detectors, not one. Curated regex rules catch known secret shapes (AWS, GitHub, Stripe, Slack, …); a Shannon-entropy detector catches the random blobs no vendor pattern knows about. They de-duplicate against each other so you never get the same leak reported twice.
  • Baselines that are reviewable. Accept existing/false-positive findings into a .hush-baseline.json that stores redacted context — you can see what was accepted in code review, and hush only ever reports what's new.
  • Git-native. Scan the index (--staged) for a pre-commit gate, or sweep the whole history (--history) to find secrets that were "removed" but are still sitting in old commits (and therefore still compromised).
  • CI-friendly exit codes. 0 clean, 1 secrets found, 2 error.

Install

From PyPI (once published):

pip install hush-scan

From source:

git clone https://github.com/netizen-labs/hush
cd hush
pip install -e .

Requires Python 3.9+. No other runtime dependencies.

Usage

Scan files or directories

hush scan                 # scan the current directory
hush scan src/ config/    # scan specific paths
hush scan --format json   # machine-readable output

Secrets are redacted by default. Pass --reveal if you really want the raw values (e.g. to rotate them).

Pre-commit gate (scan staged changes)

hush scan --staged

This reads the index version of each staged file — exactly what's about to be committed — not your working tree. Wire it up automatically with pre-commit:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/netizen-labs/hush
    rev: v0.1.0
    hooks:
      - id: hush

Scan git history

hush scan --history                  # every commit
hush scan --history --max-commits 50 # last 50 commits

Findings are labelled <short-sha>:<path> so you can trace the leak.

Baselines (accept known findings)

On an existing codebase you'll have test fixtures and example values. Snapshot them once:

hush baseline src/ tests/ -o .hush-baseline.json

Then every future scan only surfaces new secrets:

hush scan --baseline .hush-baseline.json

Commit .hush-baseline.json to your repo. It contains fingerprints and redacted context only — never a raw secret.

Useful flags

Flag Description
--no-entropy Disable the high-entropy detector (regex rules only).
--min-severity {low,medium,high,critical} Ignore findings below this level.
--baseline FILE Suppress findings listed in a baseline.
--format {text,json} Output format.
--reveal Show full secrets instead of redacting.
--staged Scan git staged files.
--history [--max-commits N] Scan git commit history.

Use as a library

from hush import Scanner

scanner = Scanner(use_entropy=True, min_severity="medium")
findings = scanner.scan_path("src/")

for f in findings:
    print(f.severity, f.source, f.line, f.redacted())

Add your own rule without forking:

import re
from hush import Scanner, Rule
from hush.rules import DEFAULT_RULES

acme = Rule(
    id="acme-token",
    description="ACME internal token",
    regex=re.compile(r"(?P<secret>acme_[A-Za-z0-9]{32})"),
    severity="high",
    keywords=("acme_",),
)

scanner = Scanner(rules=[*DEFAULT_RULES, acme])

What it detects

Built-in rules cover AWS keys, GitHub/GitLab tokens, Slack tokens and webhooks, Stripe keys, Google API keys and OAuth IDs, OpenAI/Anthropic keys, JWTs, PEM private-key blocks, Twilio, SendGrid, npm tokens, and generic high-entropy secret = "..." assignments — plus the entropy detector for everything else.

Note: hush is a safety net, not a vault. A clean scan is not a guarantee. If a secret has ever been committed, rotate it — deletion doesn't un-leak it.

GitHub Actions

name: secret-scan
on: [push, pull_request]
jobs:
  hush:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.12" }
      - run: pip install hush-scan
      - run: hush scan --baseline .hush-baseline.json

Development

pip install -e ".[dev]"
pytest                 # run the suite
pytest --cov=hush      # with coverage

License

MIT © Lucas Gabriel Ramos Aguiar. See LICENSE.

Release files for hush-scan 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hush-scan 0.1.0
File Size Uploaded
hush_scan-0.1.0.tar.gz 21.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hush-scan 0.1.0
File Interpreter ABI Platform
hush_scan-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 40.0 kB

Release files / hush_scan-0.1.0.tar.gz

Download URL hush_scan-0.1.0.tar.gz
Size 21.7 kB
Tags Source
SHA-256 checksum
How to use checksums
94b4d3b799206eef0def90577723d3f9f9c1ddeedcba317d0b56efa2cdd079fd
BLAKE2b-256 checksum
How to use checksums
f41388fc21fdb098fd5ce8cba3b4fbc1d33df8a556a813af8eda8810ee08545e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / hush_scan-0.1.0-py3-none-any.whl

Download URL hush_scan-0.1.0-py3-none-any.whl
Size 18.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b87ad94d1a3dbf1971324305725c0a946aa76c5c0c1a75360b07e1cfc14c9520
BLAKE2b-256 checksum
How to use checksums
5f32772f7ad2bcd0e41e68744a82e8b5d4c6cf6380a4721cd2f59531bc0ba5d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page