Stage 5 · Platform
Supply-Chain Security
Secret Scanning
Blocking leaked credentials with GitHub secret scanning, gitleaks, trufflehog, and push protection.
Secret Leak Risks
Accidentally committing secrets to Git is one of the most common security incidents. API keys, database credentials, private keys, and tokens end up in repositories through developer mistakes. Once committed, the secret is in the Git history forever — even if removed in a subsequent commit.
Automated secret scanning catches leaked credentials before they are pushed to the remote repository. It scans commits, pull requests, and the full Git history for patterns that match known secret formats.
GitHub Secret Scanning
# .github/secret-scanning.yml
# Custom patterns for organization-specific secrets
custom-patterns:
- name: Internal API Key
pattern: |
(?i)(api[_-]?key|apikey)[\s]*[=:][\s]*['"]?(?<secret>[a-zA-Z0-9]{32,64})['"]?
confidence: high
- name: Database Connection String
pattern: |
(?i)(db[_-]?url|database[_-]?url|connection[_-]?string)[\s]*[=:][\s]*['"]?(?<secret>postgres(ql)?://[^'"]+)['"]?
confidence: high
# Push protection settings
push_protection_enabled: true
# Review required for secret scanning alerts
reviewer: myorg/security-teamGitHub secret scanning detects known secret formats from over 200 partner patterns. Custom patterns catch organization-specific secrets. Push protection blocks pushes that contain detected secrets.
Gitleaks
jobs:
secret-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Custom .gitleaks.toml configuration
- name: Run Gitleaks with custom config
uses: gitleaks/gitleaks-action@v2
with:
args: detect --config .gitleaks.toml --source . --report-path gitleaks-report.json
- name: Upload scan results
uses: actions/upload-artifact@v4
if: always()
with:
name: gitleaks-report
path: gitleaks-report.jsonGitleaks scans the entire Git history for secrets. The action uses the GITHUB_TOKEN to avoid rate limiting. A custom .gitleaks.toml configures which rules to use and which paths to ignore.
[[rules]]
id = "custom-api-key"
description = "Custom API key pattern"
regex = '''(?i)(api[_-]?key|apikey)[s]*[=:][s]*['"]?([a-zA-Z0-9]{32,64})['"]?'''
tags = ["key", "api"]
[[rules]]
id = "connection-string"
description = "Database connection string"
regex = '''(?i)(db[_-]?url|database[_-]?url)[s]*[=:][s]*['"]?(postgres(ql)?://[^s'"]+)['"]?'''
tags = ["database", "connection"]
[[rules]]
id = "jwt-token"
description = "JSON Web Token"
regex = '''eyJ[a-zA-Z0-9_-]*.eyJ[a-zA-Z0-9_-]*.[a-zA-Z0-9_-]*'''
tags = ["jwt", "token"]
[allowlist]
description = "Global allowlist"
paths = [
'''vendor/''',
'''node_modules/''',
'''*.test.ts''',
'''*.spec.ts''',
]Custom Gitleaks rules define regex patterns for organization-specific secrets. The allowlist excludes paths that commonly contain false positives. Gitleaks reports findings as SARIF for GitHub integration.
TruffleHog
jobs:
trufflehog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: TruffleHog scan
uses: trufflesecurity/trufflehog@main
with:
extra_args: --only-verified --json
# Scan specific repository
- name: Scan GitHub repo
run: |
trufflehog github \
--repo=https://github.com/myorg/myrepo \
--token=${{ secrets.GITHUB_TOKEN }} \
--only-verified \
--json > trufflehog-results.json
# Scan S3 bucket
- name: Scan S3
run: |
trufflehog s3 \
--bucket=my-secrets-bucket \
--only-verifiedTruffleHog scans Git repositories, S3 buckets, filesystems, and more. --only-verified confirms detected secrets are still valid. This reduces false positives significantly. TruffleHog supports over 700 secret detectors.
Push Protection
Push protection is a pre-receive hook that blocks pushes containing detected secrets. GitHub, GitLab, and custom Git hooks can implement push protection. It is the last line of defense before secrets reach the remote repository.
# Enable in repository settings or via API
# Repository > Settings > Code security and analysis > Push protection
# Via API
curl -X PUT \
https://api.github.com/repos/myorg/myrepo \
-H "Authorization: token ${GITHUB_TOKEN}" \
-d '{
"security_and_analysis": {
"secret_scanning": {
"status": "enabled"
},
"secret_scanning_push_protection": {
"status": "enabled"
}
}
}'Push protection blocks the push and provides a link to the detected secret. Developers can remove the secret and retry the push. If the secret is a false positive, it can be bypassed with admin approval.
Remediation Steps
- Revoke the secret immediately — rotate the credential in the provider's dashboard.
- Remove from Git history — use git filter-branch or BFG Repo-Cleaner to purge the secret.
- Update all systems — any system that used the old secret must be updated.
- Enable push protection — prevent future leaks with pre-receive scanning.
- Audit access logs — check if the leaked secret was accessed by unauthorized parties.
- Notify the team — inform stakeholders about the incident and remediation steps.
Even if you remove a secret from Git history, it may have been cloned, cached, or accessed. Always revoke and rotate leaked secrets. Do not rely on Git history cleanup as the sole remediation.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.