secret-guard
Zero-dependency secret scanning for Python, CI/CD, and pre-commit hooks.
Detect hardcoded credentials — AWS keys, GitHub and Slack tokens, private keys, and dozens of other secrets — before they reach your repository history.
Overview
secret-guard scans source files for hardcoded credentials using 30 regex rules combined with Shannon-entropy detection, and reports each finding with a severity level and a masked value. By default, secret values are never printed.
| Category | Detection rules |
|---|---|
| Cloud / SaaS | AWS Access Key IDs, AWS temporary/assigned keys, AWS dashed keys, Google API Keys, Stripe secret keys, SendGrid and Twilio API keys |
| Tokens | GitHub PATs (classic and fine-grained), Slack tokens and webhooks, OpenAI, Anthropic, Discord, Square, HubSpot, GitLab, Hugging Face, npm, PyPI, DigitalOcean tokens |
| Databases | PostgreSQL and MongoDB connection URIs with embedded credentials |
| Key material | RSA / EC / DSA / OpenSSH / PGP private keys (critical severity) |
| Heuristics | Generic secret keys, credential assignments, JWT tokens, high-entropy strings |
In addition to pattern matching, secret-guard identifies .env files that
assign values to secret-looking variable names (.env, .env.local,
prod.env, and similar). It reports the key name and severity but never the
value.
Features
- Zero runtime dependencies — pure Python, no network calls, no build step.
- Masked by default — secret values are redacted in both console and JSON
output;
--show-valueis an explicit opt-in for recovery and rotation work. - Git-aware staged scanning (
--staged) — reads the git index blob rather than the working tree, so secrets that are staged but already deleted from disk are still detected. - gitignore-aware — skips
.git,node_modules,venv, and anything your.gitignorealready covers; repeatable--excludehandles the rest. - Entropy detection — flags high-entropy strings even when no rule matches.
- Configurable — command-line flags, a checked-in
secret-guard.jsonconfig, custom rule manifests, baselines, and severity thresholds. - Fast, single-file deployment — works in CI with a single
pip install.
Installation
pip install secret-guard-scan
The command-line tool is secret-guard. The package can also be run directly
(Python 3.8+) without installation:
python -m secretguard
Quick start
# Scan the current directory
secret-guard scan
# Scan a specific path
secret-guard scan ./src
# Scan several files and directories at once
secret-guard scan ./src ./tests config.py
# JSON output for CI and tooling
secret-guard scan --json
# Read content from stdin
cat config.py | secret-guard scan --stdin --filename config.py
# Scan only files staged for commit (reads the git index)
secret-guard scan --staged
# Enforce a severity threshold before failing the scan
secret-guard scan . --severity high
# Guard every future commit with a git pre-commit hook
secret-guard install-hook
# Initialize a starter configuration file
secret-guard init
Example output
config.py:12 [HIGH ] GitHub Token: ghp_**************
.env:4 [CRITICAL] Private Key: -----BEGIN [REDACTED]-----
app.py:40 [MEDIUM ] Credential Assignment: password = 'hunter 2'
1 critical, 1 high, 1 medium, 0 low - 3 total
Values are masked by default. Use --show-value only when the full string is
genuinely required — for example, to rotate a key that was just found.
GitHub Action
The fastest way to add secret scanning to CI, with no Docker or Python setup:
- uses: taksh1507/secret-guard@v1
A detected leak fails the job. The scanner and its Python runtime are installed by the action itself.
| Input | Default | Description |
|---|---|---|
path |
. |
File or directory to scan |
exclude |
(empty) | Directory names to skip, one per line |
json |
false |
Emit findings as JSON (values still masked) |
no-entropy |
false |
Disable high-entropy string detection |
Add it to an existing workflow:
steps:
- uses: actions/checkout@v4
- uses: taksh1507/secret-guard@v1
with:
path: .
json: true
exclude: |
tests
.venv
Docker
Run secret-guard in a container without installing Python:
docker run --rm -v "${PWD}:/code" ghcr.io/taksh1507/secret-guard:latest scan /code
The image runs as a non-root user by default. Mount your project directory to
/code and pass any normal secret-guard scan flags after the path:
docker run --rm -v "${PWD}:/code" ghcr.io/taksh1507/secret-guard:latest scan /code --no-entropy
Usage
secret-guard scan [paths...] [options]
positional arguments:
paths Files or directories to scan (default: .). Repeatable
(e.g. `secret-guard scan src/ tests/ config.py`).
options:
--exclude DIR Additional directory names to skip (repeatable)
--no-entropy Disable high-entropy string detection
--json Output findings as JSON
--csv Output findings as CSV
--show-value Print full secret values (default masks them)
--no-color Disable colored console output
--quiet Suppress all scan output; only the exit code is set
--staged Scan only files staged in git
--baseline FILE Suppress findings listed in a baseline file
--severity LEVEL Minimum severity to fail the scan (low, medium, high, critical)
--max-findings N Cap the number of findings printed to N; the scan still
reports the full summary and exits non-zero when secrets
are found
--skip-rule RULE Never run the given rule id (repeatable)
--only-rule RULE Run only the given rule id (repeatable)
--rules-path FILE Add custom rules from a JSON manifest
--list-rules List every available rule id and exit
--stdin Read content to scan from stdin
--filename NAME Reported path for --stdin input (default: stdin)
Taming false positives
Rule-based scanners are only useful when reviewers trust them. Use
--skip-rule and --only-rule to scope a scan to the rules that matter:
# Ignore a noisy rule entirely
secret-guard scan . --skip-rule generic-secret-key
# Enforce only the secrets that matter on a given path
secret-guard scan ./infra --only-rule aws-access-key-id --only-rule github-token
# See every rule id a scan can run
secret-guard scan --list-rules
Passing an unknown rule id fails the scan with exit code 2, so a typo in
--skip-rule can never silently disable detection.
Configuration file (secret-guard.json)
Prefer a checked-in configuration over repeating flags in CI. secret-guard
discovers secret-guard.json in the scanned directory or any parent directory:
{
"exclude": ["tests", ".venv"],
"no_entropy": false,
"skip_rules": ["generic-secret-key"],
"only_rules": [],
"rules": [],
"baseline": [],
"severity": "low"
}
Command-line flags override configuration values. Scaffold a starter file with:
secret-guard init
Custom rule manifests
Teams can register their own regex detections without forking the project. A
manifest is a JSON object with a rules array; each rule requires a name and
a pattern, with optional severity (low/medium/high/critical,
default medium) and description:
{
"rules": [
{
"name": "Acme API Token",
"pattern": "acme_tok_[a-f0-9]{20,}",
"severity": "high",
"description": "Acme platform API token."
}
]
}
Point a scan at a manifest with --rules-path, or commit rules under the
rules key of secret-guard.json (discovered automatically). Custom rules flow
through the same pipeline as built-ins: they respect
--skip-rule/--only-rule (by their slugified id, for example
acme-api-token), honor severity thresholds, and mask matched values by
default. A ready-to-copy manifest lives in
examples/rules.json.
Manifests fail fast rather than silently: a duplicate rule name, an unreadable
regex, an invalid severity, or a missing or malformed file exits with code 2
and an actionable message, so a broken manifest can never quietly disable
detection.
Baselines / allowlists
A baseline acknowledges known, intentional findings so CI stays green while new leaks still fail. A baseline file is a JSON document:
{
"baseline": [
{ "path": "config/rules.json", "rule_id": "generic-secret-key" }
]
}
A path and rule_id pair suppresses all matching findings; an optional
hash (SHA-256 of the secret value) suppresses only that exact value. Load it
with --baseline baseline.json or through the baseline key of
secret-guard.json. Scanned values are hashed client-side, so the baseline
never needs to contain the secret itself.
Severity and exit codes
0— no secrets found, or all findings are below the--severitythreshold (or--help/--versionwas used).1— at least one secret meeting or exceeding the--severitythreshold was detected (or a runtime error occurred).2— CLI invocation error or configuration validation failure.
Severity levels
The scanner assigns a severity to every finding:
critical— private cryptographic keys.high— cloud API keys, SaaS tokens, OAuth tokens, and.envfile credentials.medium— variable assignments named like credentials, and generic secret keys.low— high-entropy string detections.
By default the severity threshold is low, so any finding fails the scan (exit
code 1). To fail only on high or critical findings:
secret-guard scan . --severity high
Or set it in secret-guard.json:
{
"severity": "high"
}
Scanning staged changes
secret-guard scan --staged
This reads each staged file directly from the git index (git show :<path>).
When a secret is added, staged, and then deleted from the working tree, a
working-tree-only scan would miss it; the staged version caught by secret-guard
is exactly what would otherwise be committed.
Local development
python -m unittest discover -s tests
python -m ruff check secretguard tests
python -m secretguard scan . --exclude tests --no-entropy
The repository enforces these in CI (tests on Python 3.9 / 3.11 / 3.13, linting, and a self-scan job) and runs GitGuardian on every pull request.
Contributing
Contributions of any size are welcome — new detection rules, false-positive reports, documentation, and editor integrations. Start with CONTRIBUTING, review the Contributors list, and read the Code of Conduct. Please report security issues according to the Security Policy.
License
Metadata
Release files for secret-guard-scan 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| secret_guard_scan-0.9.0.tar.gz | 32.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| secret_guard_scan-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.1 kB
Release files / secret_guard_scan-0.9.0.tar.gz
| Download URL | secret_guard_scan-0.9.0.tar.gz |
|---|---|
| Size | 32.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b28383ec0f0f4cd9970bd14c0ad6b56ca97b1b0e1f0bc55bb736765b52400295
|
|
BLAKE2b-256 checksum How to use checksums |
f469c6c0eea0111e0fa9c973fff6a9c77b3078234daa72cf6d8b1359155934d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency logRelease files / secret_guard_scan-0.9.0-py3-none-any.whl
| Download URL | secret_guard_scan-0.9.0-py3-none-any.whl |
|---|---|
| Size | 22.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
22024838e09b92401ad9da5138c21c69d94402428aef5cbbc5e7d095612033c6
|
|
BLAKE2b-256 checksum How to use checksums |
635165f92228213e962db7314a3333a5c1dfc27f675aeb25f60c1c62c4596499
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.
Transparency log