Skip to main content

A simple secret/credential scanner for source code repositories.

Project description

secret-scan

PyPI version PyPI downloads CI Python License: MIT

A fast, lightweight CLI tool to detect secrets in source code. Zero dependencies — stdlib only.

secret-scan scans directories for sensitive data such as:

  • AWS Access Keys and Secret Keys
  • GitHub tokens (PAT, OAuth, App, fine-grained)
  • Slack tokens (bot, user)
  • Stripe keys (live and test)
  • Google API keys
  • OpenAI API keys
  • npm and PyPI tokens
  • Twilio and SendGrid API keys
  • Heroku and HashiCorp Vault tokens
  • Passwords, Bearer tokens, and JWTs
  • SSH/RSA/PGP private keys
  • Azure storage keys
  • Database connection strings

It skips binary files, ignores common junk directories (node_modules, .git, venv, etc.), avoids scanning large files, and supports extensible detection rules.

Installation

pip install secret-scan

To upgrade:

pip install --upgrade secret-scan

Check version:

secret-scan --version

Quick Start

# Scan current directory
secret-scan .

# Only show high-confidence findings
secret-scan . --severity error

# JSON output for scripting
secret-scan . --json

# SARIF output for GitHub/GitLab integration
secret-scan . --sarif > results.sarif

# Advisory mode (always exit 0)
secret-scan . --no-fail

CI/CD Integration

GitHub Actions

Add this to .github/workflows/secret-scan.yml:

name: Secret Scan

on: [push, pull_request]

jobs:
  secret-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install secret-scan
        run: pip install secret-scan

      - name: Scan for secrets
        run: secret-scan . --output /dev/null

The scanner exits with code 1 if secrets are found, which will fail the workflow.

GitHub Actions with SARIF (Code Scanning)

Upload results to GitHub's Security tab:

name: Secret Scan

on: [push, pull_request]

permissions:
  security-events: write

jobs:
  secret-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install secret-scan
        run: pip install secret-scan

      - name: Scan for secrets
        run: secret-scan . --sarif --no-fail --output /dev/null > results.sarif

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

GitLab CI

secret-scan:
  image: python:3.12-slim
  script:
    - pip install secret-scan
    - secret-scan . --output /dev/null

Pre-commit Hook

Add to .pre-commit-config.yaml:

repos:
  - repo: local
    hooks:
      - id: secret-scan
        name: secret-scan
        entry: secret-scan
        args: ['.', '--output', '/dev/null']
        language: python
        additional_dependencies: ['secret-scan']
        pass_filenames: false

Exit Codes

Exit Code Meaning
0 No secrets found
1 Secrets were found

Use --no-fail to always exit with 0 (advisory mode):

secret-scan . --no-fail

Severity Filter

Each finding has a severity: error (high confidence), warning (medium), or note (low).

Filter to only show high-confidence findings:

secret-scan . --severity error

Show errors and warnings (exclude notes):

secret-scan . --severity warning

JSON Output

Generate JSON output (useful for CI pipelines):

secret-scan . --json

Example output:

[
  {
    "file": "config/settings.py",
    "line": 20,
    "match": "AWS_ACCESS_KEY_ID=AKIA1234567890ABCD12",
    "rule_id": "aws-access-key-assignment",
    "rule_name": "AWS Access Key Assignment",
    "severity": "error",
    "column": 0,
    "end_column": 42
  }
]

SARIF Output

Generate SARIF v2.1.0 output for integration with GitHub Code Scanning, GitLab SAST, and other security tools:

secret-scan . --sarif

Suppressing False Positives

.secretscanignore

Create a .secretscanignore file in your project root to suppress known false positives:

# Ignore entire files or directories
tests/fixtures/*.json
docs/**

# Ignore a specific rule for a specific file
config/settings.py:generic-secret

# Ignore matches containing specific text
!match:EXAMPLE_KEY_DO_NOT_USE

Inline suppression

Add # nosecret to any line to suppress detection on that line:

DEFAULT_KEY = "sk-placeholder-not-real"  # nosecret

Use --no-ignore to bypass all suppression rules:

secret-scan . --no-ignore

Command-Line Options

Flag Description
-v, --version Show version and exit
-o, --output <file> Save text results (default: docsCred.txt)
--skip-ext .log Skip specific file extensions
--skip-dir <dir> Skip specific directories
--max-size-mb N Scan only files smaller than N MB
--severity <level> Minimum severity: error, warning, or note
--json Print JSON results to stdout
--sarif Print SARIF v2.1.0 results to stdout
--no-fail Always exit 0 even if secrets are found
--no-ignore Do not read .secretscanignore file

What It Detects

Each detection rule has a unique rule_id and a severity level (error, warning, or note).

Cloud Providers

Provider What Severity
AWS Access Key IDs (AKIA...), Secret Access Keys error
Azure Storage account keys, Account keys error
Google API keys (AIza...) error
Heroku API key assignments error
HashiCorp Vault Service tokens (hvs.) error

SaaS / API Platforms

Provider What Severity
GitHub PAT, OAuth, App, Refresh, Fine-grained tokens error
Slack Bot tokens (xoxb-), User tokens (xoxp-) error
Stripe Live secret/publishable/restricted keys error/warning
Stripe Test keys note
OpenAI API keys (sk-) error
Twilio API keys (SK...) error
SendGrid API keys (SG.) error
npm Access tokens error
PyPI API tokens error

Generic Patterns

What Severity
Password assignments (password=, passwd=, pwd=) warning
Bearer tokens error
JWT tokens warning
API key/token assignments warning
Private key blocks (PEM headers) error
SSH RSA public keys note
Database connection strings warning
Generic secret assignments warning

Automatic Skips

The scanner automatically ignores:

  • .git, .hg, .svn
  • node_modules
  • Python virtual environments (venv, .venv, env)
  • IDE directories (.idea, .vscode)
  • Binary files (null-byte detection)
  • Large files (over 5 MB by default)
  • Common non-text extensions (images, archives, executables)

Extending Detection Patterns

Detection patterns are defined as SecretPattern dataclass instances in:

src/secret_scanner/patterns.py

Each pattern has a rule_id, name, severity, pattern (regex), and description. You can add new patterns by appending to the PATTERNS list.

Programmatic Usage

from pathlib import Path
from secret_scanner import scan_directory

matches = scan_directory(Path("."), output_path=None)
for m in matches:
    print(f"[{m['severity']}] {m['rule_name']}: {m['file']}:{m['line']}")

Running Tests

PYTHONPATH=src pytest tests/ -q

Contributing

Contributions are welcome.

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Open a pull request

License

This project is licensed under the MIT License. See the LICENSE file for full details.

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

secret_scan-0.2.1.tar.gz (19.9 kB view details)

Uploaded Source

Built Distribution

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

secret_scan-0.2.1-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file secret_scan-0.2.1.tar.gz.

File metadata

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

File hashes

Hashes for secret_scan-0.2.1.tar.gz
Algorithm Hash digest
SHA256 7733046e1c8dc6d6fa0037a160b0ba0d8d14af362bcbf40429f81097bd91a91d
MD5 a0f8d9ec43c8d22c39d4ee22c8425d5b
BLAKE2b-256 fc7438d36832529cf0e545c397e3999979de0e309c65727f359c22cd341c4eb9

See more details on using hashes here.

Provenance

The following attestation bundles were made for secret_scan-0.2.1.tar.gz:

Publisher: publish.yml on harshahemanth/secret-scan

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

File details

Details for the file secret_scan-0.2.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for secret_scan-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a59461e893e8daee6168dc429fa6ea2ecffe833eedca7e062aa2e0e503cbd929
MD5 2b62a745011cd2069da7f27edc613a2c
BLAKE2b-256 674eebd3d2336b6aaa7962bb9ba07eba69cc72c18406f8b304ed78ab9d3f21c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for secret_scan-0.2.1-py3-none-any.whl:

Publisher: publish.yml on harshahemanth/secret-scan

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