Skip to main content

A CLI tool to detect leaked secrets in Git repositories

Project description

secretleak

A production-quality CLI tool to detect leaked secrets (API keys, tokens, private keys) in Git repositories.

Features

  • Regex rules — 30+ built-in patterns covering AWS, GitHub, Stripe, Google, Slack, Twilio, SendGrid, npm, PyPI, private keys, connection strings, and more
  • Shannon entropy heuristic — catches high-entropy strings that don't match a known pattern
  • Three scan modes — working tree, staged diff (git diff --staged), commit range
  • Three output formats — Rich console table, JSON report, SARIF 2.1.0 (GitHub Code Scanning compatible)
  • False-positive suppression — allowlist patterns, ignore paths, baseline file
  • Git hook — auto-generates a pre-commit hook that blocks commits on findings
  • Secret masking — secrets are never printed or stored in full (prefix/suffix only)

Installation

From PyPI

pip install secretleak

From source (development)

git clone https://github.com/Mo-Shakib/secretleak.git
cd secretleak
pip install -e ".[dev]"

Using secretleak in Another Project

Option 1 — Install globally and scan manually

Install once, then point it at any repo:

pip install secretleak
secretleak scan /path/to/your-project

Option 2 — Add as a dev dependency

In your project's pyproject.toml:

[project.optional-dependencies]
dev = [
    "secretleak",
]

Then install and scan:

pip install -e ".[dev]"
secretleak scan .

Or reference a local checkout before it is published to PyPI:

dev = [
    "secretleak @ file:///path/to/secretleak",
]

Option 3 — Pre-commit hook (recommended for teams)

Run once inside the target repo. Every developer on the team is protected automatically — no changes to their workflow required.

cd /path/to/your-project
secretleak install-hook .

From that point on, every git commit scans the staged files and blocks if secrets are found:

[secretleak] Scanning staged files for secrets...
🔴 CRITICAL  AWS Access Key ID — config.py:12 — AKIA****MPLE

[secretleak] !! Commit BLOCKED: secrets detected in staged files.

Remove the hook at any time:

secretleak uninstall-hook .

Option 4 — GitHub Actions (CI/CD)

Create .github/workflows/secret-scan.yml in your project:

name: Secret Scan

on: [push, pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    steps:
      - uses: actions/checkout@v4

      - name: Scan for secrets
        run: |
          pip install secretleak
          secretleak scan . --format sarif --output results.sarif --no-fail

      - name: Upload to GitHub Code Scanning
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

Findings appear in your repo's Security → Code Scanning tab with file locations and line numbers.

Option 5 — Suppress false positives in your project

cd /path/to/your-project

# 1. Generate a baseline to silence already-known findings
secretleak generate-baseline .
git add .secretleak-baseline.json
git commit -m "chore: add secretleak baseline"

# 2. Add project-specific config
cat > .secretleak.yaml << 'EOF'
allowlist:
  patterns:
    - '^EXAMPLE_'        # placeholder values in docs
    - 'your-key-here'    # obvious dummy values
  paths:
    - tests/fixtures/**  # test data with fake secrets
    - docs/**
baseline_file: .secretleak-baseline.json
EOF

Future scans will skip anything in the baseline and anything matching the allowlist.


Quick reference

Goal Command
Scan a project secretleak scan /path/to/project
Scan staged files only secretleak scan --staged
Scan a commit range secretleak scan --commit-range HEAD~10..HEAD
Block commits automatically secretleak install-hook . (run once)
CI pipeline (SARIF) secretleak scan . --format sarif --no-fail
JSON report secretleak scan . --format json -o report.json
Suppress known findings secretleak generate-baseline .
List active rules secretleak rules

Quick Start

# Scan current directory
secretleak scan .

# Scan only staged files (before committing)
secretleak scan --staged

# Scan a commit range
secretleak scan --commit-range HEAD~10..HEAD

# JSON output
secretleak scan . --format json --output report.json

# SARIF output (GitHub Code Scanning)
secretleak scan . --format sarif --output results.sarif

# Install pre-commit hook
secretleak install-hook .

# Generate baseline to suppress existing findings
secretleak generate-baseline .

# List active rules
secretleak rules

Configuration

Create .secretleak.yaml in your repo root:

# Override entropy settings
entropy:
  enabled: true
  threshold: 4.5
  min_length: 20

# Add custom rules
rules:
  - id: my-internal-token
    name: Internal Service Token
    pattern: 'myapp_[a-z0-9]{32}'
    severity: high
    description: Internal service authentication token

# Allowlist – suppress known false positives
allowlist:
  patterns:
    - '^EXAMPLE'          # example values in docs
    - 'placeholder'        # obvious placeholders
  paths:
    - tests/fixtures/**   # test data
    - '**/*.md'           # documentation

# Additional paths to skip
ignore_paths:
  - vendor/**
  - node_modules/**

# Point at a baseline file
baseline_file: .secretleak-baseline.json

False Positive Handling

Allowlist patterns

allowlist:
  patterns:
    - '^fake_'
    - 'example\.com'

Baseline suppression

Generate a baseline from the current state of your repo, commit it, and future scans will ignore already-known findings:

secretleak generate-baseline .
git add .secretleak-baseline.json
git commit -m "chore: add secretleak baseline"

Ignore paths

ignore_paths:
  - docs/**
  - tests/fixtures/**
  - '**/*.lock'

CI Integration

# .github/workflows/secret-scan.yml
- name: Scan for secrets
  run: |
    pip install secretleak
    secretleak scan . --format sarif --output results.sarif --no-fail

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

Git Hook

# Install
secretleak install-hook .

# Force-overwrite an existing hook
secretleak install-hook . --force

# Uninstall
secretleak uninstall-hook .

The hook runs secretleak scan --staged and blocks the commit if any secrets are found.

Output Formats

Console (default)

Rich table with severity icons, file paths, line numbers, and masked secrets.

JSON

{
  "version": "0.1.0",
  "generated_at": "2026-03-09T12:00:00Z",
  "scan_mode": "working_tree",
  "summary": { "total": 2, "critical": 1, "high": 1 },
  "findings": [
    {
      "fingerprint": "a3b4c5d6e7f8a1b2",
      "rule_id": "aws-access-key-id",
      "severity": "critical",
      "file_path": "config.py",
      "line_number": 12,
      "secret_masked": "AKIA****MPLE",
      ...
    }
  ]
}

SARIF 2.1.0

Compatible with GitHub Code Scanning. Upload via github/codeql-action/upload-sarif.

Exit Codes

Code Meaning
0 No findings
1 Findings detected (--no-fail to suppress)
2 Error (bad args, git failure, config error)

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=secretleak --cov-report=term-missing

# Lint
ruff check src/ tests/
ruff format src/ tests/

# Type check
mypy src/

Security Notes

  • Secrets are never stored or logged in full. Only a masked form (prefix****suffix) appears in output.
  • The JSON and SARIF outputs are safe to store and share — they contain only masked values.
  • The baseline file contains only fingerprints (SHA-256 hashes), not secret values.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

secretleak-0.2.0.tar.gz (26.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

secretleak-0.2.0-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

Details for the file secretleak-0.2.0.tar.gz.

File metadata

  • Download URL: secretleak-0.2.0.tar.gz
  • Upload date:
  • Size: 26.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for secretleak-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e136375fc7b532ed3080416afd005ba9d96b4c2ce05e55bb63c762f985307435
MD5 e3b6a3b52d27fec83d5330be17b2f3d2
BLAKE2b-256 1a36b6423a23f7ed0ca1cde68dc7573ad742110d29b65ede04ced9e795d30c9f

See more details on using hashes here.

Provenance

The following attestation bundles were made for secretleak-0.2.0.tar.gz:

Publisher: publish.yml on Mo-Shakib/secretleak

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file secretleak-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: secretleak-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 25.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for secretleak-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 857b5cc6ef2a7b19f9916922f8aaa352656d1331d6023fd24f35fd80c365d619
MD5 9b600dd43c58877e1e3afa1ff27c9b66
BLAKE2b-256 ab1ab8fd430d66534376e525bea8fcc9a0a0c0c72b457118036327d5ec91369b

See more details on using hashes here.

Provenance

The following attestation bundles were made for secretleak-0.2.0-py3-none-any.whl:

Publisher: publish.yml on Mo-Shakib/secretleak

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page