Scan for hardcoded secrets before they reach your repository
Project description
nosecrets
Scan for hardcoded secrets before they reach your repository.
Zero runtime dependencies. Runs as a pre-commit hook or standalone CLI. Designed for developers who want a lightweight, auditable secrets scanner without pulling in a 20MB Go binary or a heavy Python dependency tree.
$ secrets scan
[CRITICAL] src/config.py:14
AWS Access Key ID: AKIA************MPLE
[HIGH] deploy/docker-compose.yml:8
Database Connection String: postg****alhost
Found 2 potential secret(s): 1 CRITICAL, 1 HIGH
To suppress a finding:
Inline: add # nosecrets at end of line
Global: add path to .secretsignore
Install
pip install nosecrets
Requires Python 3.12+.
Usage
# Scan current directory
secrets scan
# Scan a specific path
secrets scan src/
# Scan only staged files (pre-commit)
secrets scan --staged
# JSON output for CI
secrets scan --json
# Only report HIGH and above
secrets scan --severity high
# Install pre-commit hook
secrets init
# Remove hook
secrets uninstall
Pre-commit hook
secrets init
Installs a git hook that runs secrets scan --staged before every commit. If a CRITICAL or HIGH secret is found, the commit is blocked.
To remove:
secrets uninstall
What it detects
| Severity | Pattern |
|---|---|
| CRITICAL | RSA / EC / OpenSSH private keys |
| CRITICAL | AWS Access Key ID (AKIA...) |
| CRITICAL | AWS Secret Access Key (with keyword context) |
| CRITICAL | Azure Storage connection string (DefaultEndpointsProtocol=...) |
| CRITICAL | Azure Storage Account Key (with keyword context) |
| CRITICAL | OpenAI API Key (sk-..., sk-proj-...) |
| CRITICAL | Anthropic API Key (sk-ant-...) |
| CRITICAL | Stripe Live Secret Key (sk_live_...) |
| HIGH | GitHub Tokens (ghp_, github_pat_, gho_, ghs_, ghr_) |
| HIGH | GitLab Personal Access Token (glpat-...) |
| HIGH | npm Access Token (npm_...) |
| HIGH | Google API Key (AIza...) |
| HIGH | Slack Bot / User / Webhook tokens |
| HIGH | SendGrid API Key (SG....) |
| HIGH | Twilio Account SID (AC...) |
| HIGH | Database connection strings with credentials |
| MEDIUM | JSON Web Tokens (hardcoded) |
| MEDIUM | Generic secrets (high-entropy api_key, password, token values) |
False positive prevention
Two-layer defence against false positives:
1. Placeholder detection — values like "changeme", "your_api_key_here", ${SECRET}, {{token}} are never flagged regardless of pattern match.
2. Shannon entropy filter — generic patterns (password, api_key, token) only trigger when the value has sufficient entropy. password = "test123" is ignored. password = "X7#mK9$pL2@nQ8!" is flagged.
High-confidence patterns (AWS AKIA..., GitHub ghp_..., etc.) skip entropy filtering because their fixed prefix already guarantees low false positive rate.
Suppression
Inline — suppress a single line:
api_key = "AKIAIOSFODNN7EXAMPLE" # nosecrets
File/directory — .secretsignore:
# gitignore-style syntax
tests/fixtures/
*.example
legacy_config.py
Copy .secretsignore.example from the repo as a starting point.
Exit codes
| Code | Meaning |
|---|---|
0 |
No findings at or above --fail-on threshold |
1 |
One or more findings at or above threshold |
Default --fail-on is high. Change with --fail-on critical to only block on critical findings.
CI integration
# GitHub Actions example
- name: Scan for secrets
run: |
pip install nosecrets
secrets scan --json --severity medium
Philosophy
"A secrets scanner that leaks its own secrets is not a secrets scanner."
- Zero runtime dependencies — stdlib only, fully auditable
- Staged scanning reads from the git index (
git show :<path>), not the working tree — you scan exactly what will be committed - Secrets are never printed in full — output always redacts the middle portion
- Pattern quality over quantity — 20 well-tested patterns beat 500 noisy ones
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nosecrets-0.2.0.tar.gz.
File metadata
- Download URL: nosecrets-0.2.0.tar.gz
- Upload date:
- Size: 15.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
239dc5e6857abdd9fe639b784bf8c2542e3fb6de6b65f74f480b4180923b19de
|
|
| MD5 |
d3ed40064da0c19617283b7f389018b1
|
|
| BLAKE2b-256 |
320bba8678c54e490186a797968b9aba447b0c2da6e492652cca5bbac4d741a1
|
File details
Details for the file nosecrets-0.2.0-py3-none-any.whl.
File metadata
- Download URL: nosecrets-0.2.0-py3-none-any.whl
- Upload date:
- Size: 14.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93a78a1edcf3682fdfae21bc1805a180aa1c0779248877ab24a2e0b013b0e304
|
|
| MD5 |
0eb03ffedbfc8c7105b7f958e8416cab
|
|
| BLAKE2b-256 |
234bd23b8fffef713107d17fd35b3d79dc1242aef36c84f51d9a25a110babe0f
|