Detect-secrets - Baseline-Aware Scanning
Learn to use Yelp detect-secrets for secrets detection with baseline management and plugin-based architecture.
Detect-secrets is an open-source tool from Yelp for detecting secrets in codebases. Its key differentiator is the baseline-aware approach—it tracks known secrets and only alerts on new ones.
Why Detect-secrets?
Detect-secrets excels in these scenarios:
- Legacy codebases - Baseline files let you adopt gradually
- Plugin architecture - Easy to add custom detectors
- Audit trail - Track when secrets were introduced
- Python ecosystem - Native integration with Python tools
Installation
# Using pip
pip install detect-secrets
# Verify installation
detect-secrets --version
# detect-secrets 1.4.0
Basic Usage
Scan for secrets:
# Scan all files in current directory
detect-secrets scan
# Scan specific files
detect-secrets scan src/config.py src/auth.py
# Scan and output to baseline file
detect-secrets scan > .secrets.baseline
The Baseline Workflow
Detect-secrets uses a baseline file (.secrets.baseline) to track known secrets:
Baseline Workflow
-----------------
1. Initial scan -> Create baseline with existing findings
2. Review baseline -> Mark false positives, plan remediation
3. Enable hook -> Block commits with NEW secrets
4. Remediate -> Fix old secrets, update baseline
Step 1: Create Initial Baseline
# Scan repository and create baseline
detect-secrets scan > .secrets.baseline
# View what was found
cat .secrets.baseline
The baseline is a JSON file:
{
"version": "1.4.0",
"plugins_used": [
{"name": "AWSKeyDetector"},
{"name": "BasicAuthDetector"},
{"name": "HighEntropyString", "limit": 3.5}
],
"results": {
"config/settings.py": [
{
"type": "AWS Access Key",
"line_number": 42,
"hashed_secret": "abc123..." // Hashed, not plaintext
}
]
}
}
Step 2: Audit the Baseline
Review findings interactively:
detect-secrets audit .secrets.baseline
This opens an interactive prompt:
Secret: 1 of 5
Filename: config/settings.py
Secret Type: AWS Access Key
----------
40: # AWS Configuration
41: aws_region = "us-west-2"
42: aws_access_key = "AKIAIOSFODNN7EXAMPLE"
43: aws_secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
44:
----------
Is this a valid secret? (y)es, (n)o, (s)kip, (q)uit:
Mark each finding:
- y - Real secret (needs remediation)
- n - False positive (will be ignored)
- s - Skip for now
Step 3: Enable Pre-commit Hook
# .pre-commit-config.yaml
repos:
- repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
Now commits are blocked if they introduce NEW secrets not in the baseline.
Step 4: Update Baseline After Remediation
After fixing secrets, regenerate the baseline:
# Regenerate baseline
detect-secrets scan > .secrets.baseline
# Or update existing baseline (preserves audit results)
detect-secrets scan --baseline .secrets.baseline
Plugins (Detectors)
Detect-secrets uses plugins to detect different secret types:
| Plugin | Detects |
|---|---|
| AWSKeyDetector | AWS access key IDs |
| ArtifactoryDetector | Artifactory tokens |
| AzureStorageKeyDetector | Azure storage keys |
| BasicAuthDetector | Basic auth in URLs |
| CloudantDetector | Cloudant credentials |
| DiscordBotTokenDetector | Discord bot tokens |
| GitHubTokenDetector | GitHub personal access tokens |
| HighEntropyString | Generic high-entropy strings |
| IbmCloudIamDetector | IBM Cloud IAM keys |
| IbmCosHmacDetector | IBM COS HMAC credentials |
| JwtTokenDetector | JWT tokens |
| KeywordDetector | Secrets near keywords like "password" |
| MailchimpDetector | Mailchimp API keys |
| NpmDetector | npm tokens |
| PrivateKeyDetector | PEM private keys |
| SendGridDetector | SendGrid API keys |
| SlackDetector | Slack tokens and webhooks |
| SoftlayerDetector | Softlayer credentials |
| SquareOAuthDetector | Square OAuth tokens |
| StripeDetector | Stripe API keys |
| TwilioKeyDetector | Twilio API keys |
Configuring Plugins
Specify which plugins to use:
# Use only specific plugins
detect-secrets scan --list-all-plugins
# Disable a plugin
detect-secrets scan --disable-plugin KeywordDetector
# Adjust high entropy threshold
detect-secrets scan --base64-limit 4.5 --hex-limit 3.0
Custom Plugins
Create custom detectors for organization-specific secrets:
# my_detector.py
import re
from detect_secrets.plugins.base import RegexBasedDetector
class MyCompanyTokenDetector(RegexBasedDetector):
"""Detect MyCompany API tokens."""
secret_type = 'MyCompany Token'
denylist = [
# Pattern: myco_live_xxxx or myco_test_xxxx
re.compile(r'myco_(live|test)_[a-zA-Z0-9]{32}'),
]
Use the custom plugin:
detect-secrets scan --plugin my_detector.MyCompanyTokenDetector
Allowlisting
Inline Comments
Mark specific lines as safe:
# This is an example key, not real
EXAMPLE_KEY = "AKIAIOSFODNN7EXAMPLE" # pragma: allowlist secret
File-level Allowlist
In the baseline, you can mark entire files:
# Exclude files from scanning
detect-secrets scan --exclude-files '\.git/.*' --exclude-files 'tests/fixtures/.*'
Regex Allowlist
Exclude patterns across all files:
detect-secrets scan --exclude-secrets 'EXAMPLE[A-Z0-9]+'
CI/CD Integration
GitHub Actions
# .github/workflows/detect-secrets.yml
name: Detect Secrets
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
detect-secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install detect-secrets
run: pip install detect-secrets
- name: Run detect-secrets
run: |
detect-secrets scan --baseline .secrets.baseline
detect-secrets audit --report --baseline .secrets.baseline
Reporting
Generate audit reports:
# Text report
detect-secrets audit --report .secrets.baseline
# JSON report
detect-secrets audit --json --report .secrets.baseline
Gitleaks vs Detect-secrets
Both tools are excellent. Here's when to choose each:
| Feature | Gitleaks | Detect-secrets |
|---|---|---|
| Speed | Faster (Go) | Slower (Python) |
| Git history scanning | Excellent | Limited |
| Baseline management | Basic | Comprehensive |
| Custom rules | TOML config | Python plugins |
| Interactive audit | No | Yes |
| Best for | New repos, CI | Legacy repos, Python shops |
Recommendation:
- Use gitleaks for speed and git history scanning
- Use detect-secrets for baseline management and gradual adoption
- Use both in different stages (detect-secrets locally, gitleaks in CI)
Best Practices
- Commit your baseline - It's safe (secrets are hashed) and needed by teammates
- Audit regularly - Review findings monthly and update baseline
- Don't ignore forever - False positives today might be real secrets tomorrow
- Combine with gitleaks - Use both for defense in depth
- Document exceptions - Add comments explaining why secrets are allowlisted
Found an issue?