Expand description
Live credential verification: confirms whether detected secrets are actually
active by making HTTP requests to the service’s API endpoint as specified in
each detector’s [detector.verify] configuration.
§keyhog-verifier
Live credential verification for the KeyHog secret scanner. Takes deduplicated matches, asks the owning service whether each credential is still active, and returns a typed verdict per finding. Also owns the shared SSRF classifier, the per-service rate limiter, and AWS SigV4 request signing that the source crates delegate to rather than forking.
Part of the KeyHog secret scanner.
use keyhog_verifier::ssrf::is_private_url;
use keyhog_verifier::VerifyConfig;
// One SSRF classifier for the whole fleet. Sources call this instead of
// carrying a local copy, so a loopback or link-local target is refused in
// exactly one place.
assert!(is_private_url("http://169.254.169.254/latest/meta-data/"));
assert!(is_private_url("http://127.0.0.1:8080/"));
assert!(!is_private_url("https://api.github.com/user"));
// Verification is opt in and configured, never ambient.
let config = VerifyConfig::default();
let _ = config;§Public entry points
VerificationEngineholds the shared HTTP client, the response cache, and the global and per-service concurrency limits. Build one and reuse it; constructing several defeats the cache and the rate limits.VerificationEngine::verify_alltakesVec<DedupedMatch>and returns oneVerifiedFindingper input group.VerifyConfigcarries every knob that changes network behavior, including TLS posture and proxy handling.proxy_is_activereports the resolved state.ssrf::is_private_urlandis_private_ip_addrare the canonical private and link-local classifiers.rate_limit::get_rate_limiteris the shared limiter.sigv4signs AWS requests.
§Failure behavior
A credential that cannot be checked is never reported as inactive. Network failure, rate limiting, and an unreachable service each produce their own verdict, distinct from a service answering that the credential is dead. That distinction is the whole point of the crate: treating an unreachable service as a revoked credential would hide a live secret.
§Features
default = ["live"]. Building without live removes the network verification
path; the SSRF, rate limiting, and signing helpers stay available. Verification
never runs unless the caller asks for it.
§Documentation
- Verification describes the verdicts and what each one means.
- Hardening and data handling describes what leaves the process during verification.
- API documentation is on docs.rs.
Modules§
- oob
- Out-of-band (OOB) callback verification via an embedded interactsh client.
- rate_
limit - Per-service rate limiting for verification requests.
- sigv4
- ssrf
- SSRF protection for live verification.
Structs§
- Verification
Engine - Live-verification engine with shared client, cache, and concurrency limits.
- Verify
Config - Runtime configuration for live verification.
Enums§
- Dedup
Scope - Deduplication scope for grouping findings.
- Verify
Error - Errors returned while constructing or executing live verification.
Functions§
- dedup_
matches - Deduplicate raw matches according to the given
DedupScope. - proxy_
is_ active - Returns true iff an explicit proxy is configured (and not a disable
sentinel). No environment variable is consulted, neither the old keyhog
proxy env var nor reqwest’s ambient proxy-env vars, because those are
neutralized via
.no_proxy()and can never route verifier traffic. This is the signalresolved_client_for_url()uses to decide whether to apply DNS pinning: with no proxy active it pins (SSRF / DNS-rebinding protection on the direct connection); with an explicit proxy the proxy resolves DNS, so pinning is skipped. Because an ambient proxy is now impossible, the old hazard of a pinned rebuild silently dropping an env-proxy (and connecting direct, past the operator’s interception) cannot occur.