Secrets detection
Vulkro detects hardcoded API keys, tokens, passwords, connection strings, and private keys across:
.env*files (always scanned, even with--scope src)- Source code (Python, JS/TS, Go)
- Config files (
*.yaml,*.yml,*.toml,*.json) - IaC (Terraform, Helm)
- Kubernetes manifests
- Git history (last 500 commits, up to 2 years)
Provider-format escalation
Generic patterns (api_key = "...") start at Medium confidence. When the
detected value matches a known provider format, confidence is bumped to
High automatically:
| Format | Provider |
|---|---|
sk_live_* | Stripe live key |
AKIA* | AWS access key |
ghp_*, gho_*, ghu_*, ghs_* | GitHub token |
xoxb-*, xoxa-*, xoxp-* | Slack token |
SG.* | SendGrid |
hf_* | Hugging Face |
glpat-* | GitLab personal access token |
The full list ships with Vulkro and is growing.
Live validation (opt-in)
vulkro scan . --validate-secrets
Each detected secret is probed against the matching provider's "whoami" / "verify" endpoint. Results tag the finding:
[live]- credential is currently valid.[dormant]- credential format matches but the API call returned 401/403, suggesting the key was rotated.[unknown]- provider doesn't expose a no-op verification endpoint, or network call failed.
[live] findings are bumped to Critical. The probe is rate-limited and
sequential to avoid tripping abuse detection.
Git-history audit
Even after you remove a secret from the working tree, it lives in git log. Vulkro walks the last 500 commits (or 2 years, whichever is
shorter):
SECRETS 19 in git history
| a1b2c3d feat: integrate Stripe sk_live_... (3 occurrences)
| 4e5f6g7 setup CI AKIA...
The audit honours .gitignore for the current tree (so you don't get
spammed by old vendored dirs) but not for historical commits - secrets
committed and later .gitignored are still surfaced.
Suppression
# vulkro-disable-next-line HardcodedSecret
TEST_API_KEY = "sk_test_FAKE"
Inline pragmas work the same way as for OWASP findings. See
vulkro scan.