ML-powered secrets detection tool
Project description
Harpocrates
ML-powered secrets detection that catches what regex can't see
AI coding tools leak secrets at 2× the rate of human-written code — 3.2% vs 1.6% of commits. 29 million secrets were exposed in 2025, up 34% year over year. One misconfigured environment variable cost a team $87k in a single night.
Regex scanners look for AWS_ACCESS_KEY_ID and GITHUB_TOKEN. They miss client_secret, ENCRYPTION_KEY, and API_SECRET — the names developers actually use.
Harpocrates catches what slips through.
The gap
| Variable name | Secret type | TruffleHog | Harpocrates |
|---|---|---|---|
client_secret |
JWT | ❌ missed | ✅ caught (0.97) |
mock_secret |
JWT | ❌ missed | ✅ caught (0.97) |
ENCRYPTION_KEY |
High-entropy key | ❌ missed | ✅ caught (0.90) |
SECRET |
AWS Access Key ID | ❌ missed | ✅ caught (0.92) |
API_SECRET |
AWS Access Key ID | ❌ missed | ✅ caught (0.80) |
On a held-out evaluation set, Harpocrates caught 1,143 lines TruffleHog missed entirely — all credentials stored under ambiguous variable names. TruffleHog caught 449 lines Harpocrates missed (live-credential API verification is its edge). They're complementary: run TruffleHog in CI, run Harpocrates before you commit.
Install
pip install harpocrates
harpocrates scan .
With ML verification (recommended — ~95% precision, ~90% recall on real-world test set):
pip install "harpocrates[ml]"
harpocrates scan . --ml
With REST API server:
pip install "harpocrates[api]"
harpocrates serve
Everything at once:
pip install "harpocrates[all]"
Usage
# Scan a directory
harpocrates scan ./my_project
# Scan a single file
harpocrates scan config.env
# Output as JSON (pipe-friendly)
harpocrates scan ./my_project --json
# Enable ML verification to suppress false positives
harpocrates scan ./my_project --ml
# Only fail CI on high or critical findings
harpocrates scan ./my_project --fail-on high
# Ignore specific patterns
harpocrates scan ./my_project --ignore "*.test.js,fixtures/*"
Pre-commit hook
repos:
- repo: https://github.com/Skipa776/Harpocrates
rev: v0.1.0
hooks:
- id: harpocrates
Add to .pre-commit-config.yaml, then run pre-commit install. Harpocrates scans every staged file before each commit.
Configuration
harpocrates scan flags
| Flag | Default | Description |
|---|---|---|
--ml |
off | Enable ML verification to reduce false positives |
--ml-threshold FLOAT |
0.19 |
ML confidence threshold 0.0–1.0. Lower = more recall, higher = more precision |
--fail-on LEVEL |
medium |
Severity that triggers exit code 1: critical | high | medium | low | info | none |
--json |
off | Output results as JSON instead of a table |
--show-secrets |
off | Print full token values instead of redacted previews |
--ignore TEXT |
— | Comma-separated glob patterns to skip (e.g. "*.test.js,fixtures/*") |
--max-size INTEGER |
10 |
Maximum file size to scan, in MB |
--recursive / --no-recursive |
--recursive |
Scan subdirectories recursively |
Exit codes
| Code | Meaning |
|---|---|
0 |
No findings at or above --fail-on severity |
1 |
One or more findings detected at or above --fail-on severity |
2 |
Error (bad argument, unreadable file, etc.) |
Other commands
harpocrates version # Print version
harpocrates serve # Start the REST API server (requires harpocrates[api])
harpocrates --help # Full command list
How it scans
Harpocrates runs a three-phase pipeline on every line of every file:
-
Regex — deterministic patterns for known credential formats (AWS, GitHub, Stripe, private keys, and more). No ML required. High-confidence, zero false positives on well-formed keys.
-
Entropy analysis — Shannon entropy flags high-randomness tokens that don't match any known pattern. Catches credentials stored under ambiguous variable names (
my_key,token,secret) that regex scanners miss entirely. -
ML verification (opt-in via
--ml) — a single-stage XGBoost classifier extracts 65 features from the token, its variable name, and the surrounding code context. It learns to distinguishapi_secret = "AKIA..."(secret) fromcommit_sha = "a1b2c..."(Git SHA) without relying on the variable name alone. Inference runs via ONNX Runtime when available, with native XGBoost as fallback.
Ships pre-trained. No user training required.
The ML model is bundled with the package. pip install "harpocrates[ml]" is all you need.
Contributing
False negatives are the highest-priority reports. If Harpocrates missed a real secret, open an issue with the false-negative label and include the variable name pattern and secret type. This is the most valuable feedback you can give.
For bugs, feature requests, and false positives, open an issue at github.com/Skipa776/Harpocrates/issues.
License
MIT — see LICENSE.
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 harpocrates-0.2.0.tar.gz.
File metadata
- Download URL: harpocrates-0.2.0.tar.gz
- Upload date:
- Size: 173.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69cd20ad012fb51ca62f0a85ce89ab7dcb3185bb6375c552e5d66c74b9f54a2d
|
|
| MD5 |
4d78c94f3a3b42e033446ae86b3773a4
|
|
| BLAKE2b-256 |
acf4041015f4d76925a06047db4392264b36f53e27af060e22b9c75280183ba5
|
Provenance
The following attestation bundles were made for harpocrates-0.2.0.tar.gz:
Publisher:
publish.yml on Skipa776/Harpocrates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
harpocrates-0.2.0.tar.gz -
Subject digest:
69cd20ad012fb51ca62f0a85ce89ab7dcb3185bb6375c552e5d66c74b9f54a2d - Sigstore transparency entry: 1392688360
- Sigstore integration time:
-
Permalink:
Skipa776/Harpocrates@cd4ec4a40378c40079a06bf548a9544fbf83bb32 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Skipa776
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cd4ec4a40378c40079a06bf548a9544fbf83bb32 -
Trigger Event:
push
-
Statement type:
File details
Details for the file harpocrates-0.2.0-py3-none-any.whl.
File metadata
- Download URL: harpocrates-0.2.0-py3-none-any.whl
- Upload date:
- Size: 169.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b4ea462fd1e2cfbabe9e3523817ee31d6f4aa3cff0b8049d12398b5a09267540
|
|
| MD5 |
46d97d3e75405747f70d703f188cbd8f
|
|
| BLAKE2b-256 |
c78b4faf888571725ada680372ab51b3a2d28bfac717bb3e5fc4f23679d94d76
|
Provenance
The following attestation bundles were made for harpocrates-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on Skipa776/Harpocrates
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
harpocrates-0.2.0-py3-none-any.whl -
Subject digest:
b4ea462fd1e2cfbabe9e3523817ee31d6f4aa3cff0b8049d12398b5a09267540 - Sigstore transparency entry: 1392688367
- Sigstore integration time:
-
Permalink:
Skipa776/Harpocrates@cd4ec4a40378c40079a06bf548a9544fbf83bb32 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Skipa776
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cd4ec4a40378c40079a06bf548a9544fbf83bb32 -
Trigger Event:
push
-
Statement type: