pub struct ScanConfig {Show 22 fields
pub min_confidence: f64,
pub max_decode_depth: usize,
pub entropy_enabled: bool,
pub entropy_in_source_files: bool,
pub entropy_ml_authoritative: bool,
pub generic_keyword_low_entropy: bool,
pub entropy_threshold: f64,
pub entropy_bpe_max_bytes_per_token: f64,
pub min_secret_len: usize,
pub max_file_size: u64,
pub dedup: DedupScope,
pub ml_enabled: bool,
pub ml_weight: f64,
pub unicode_normalization: bool,
pub validate_decode: bool,
pub max_decode_bytes: usize,
pub max_matches_per_chunk: usize,
pub scan_comments: bool,
pub known_prefixes: Vec<String>,
pub secret_keywords: Vec<String>,
pub test_keywords: Vec<String>,
pub placeholder_keywords: Vec<String>,
}Expand description
Configuration for a scan run.
Fields§
§min_confidence: f64Minimum confidence (0.0 to 1.0) required to report a finding.
max_decode_depth: usizeMaximum recursive decoding depth (e.g. Base64(Hex(URL(secret)))).
entropy_enabled: boolWhether to enable Shannon entropy analysis for unknown high-entropy strings.
entropy_in_source_files: boolWhether to enable entropy analysis even in standard source code files.
Global enable for detector-owned entropy ML policy. Each entropy owner
still chooses disabled, lift, blend, or authoritative in its TOML;
this switch can only disable those compiled modes for a scan. Opt out
with --no-entropy-ml-scoring. No-op when entropy or ML is disabled.
generic_keyword_low_entropy: boolWhen the generic keyword bridge (PASSWORD=, *_PASS=, secret:,
api_key= …) extracts a value, admit it on a far lower entropy floor
(the generic-keyword-secret base, ~1.5 bits) than the bare
generic-secret path (2.8/3.2/3.5). The credential KEYWORD in the key is
the evidence; precision is carried by the MoE + shape filters, not by
entropy. Default on: this is what lets keyhog surface the real-world
low-entropy credentials (config passwords, *_PASS= values) that pin
CredData recall near zero when gated on entropy alone. Opt out with
--no-keyword-low-entropy to restore the high-entropy-only generic gate.
No-op unless the keyword bridge fires.
entropy_threshold: f64Shannon entropy threshold (typical secrets are 4.5+).
entropy_bpe_max_bytes_per_token: f64BPE “rare-not-random” precision bound: a surviving entropy / generic
candidate whose cl100k_base bytes-per-token is STRICTLY GREATER than
this is treated as word-like (a probable false positive, dotted API
paths, prose, XML) and suppressed. Lower = more aggressive suppression
(higher precision, lower recall); higher = looser (a very large value
effectively disables the gate). The compiled default is
DEFAULT_ENTROPY_BPE_MAX_BYTES_PER_TOKEN. Operators trade precision
for recall per corpus via the [scan] TOML key or --entropy-bpe-max-bytes-per-token.
A #[serde(default)] keeps configs that predate the field on the shipped
bound instead of f64’s 0.0: which would suppress EVERY candidate
(bytes-per-token is always > 0), a silent recall wipeout. No-op unless the
entropy feature is compiled and the gate is reached.
min_secret_len: usizeMinimum credential length for entropy-based secret detection.
Named detectors keep their own shape-specific lengths; this floor is
consumed by the scanner’s entropy fallback (--min-secret-len /
min_secret_len in .keyhog.toml).
max_file_size: u64Maximum file size to scan (bytes). Large files are skipped or sampled.
NOTE: not read here on the live path. The effective cap is set
at the source walker (FilesystemSource::with_max_file_size,
fed from ScanArgs.max_file_size); this field is retained for
the canonical config surface but is not carried into
ScannerConfig.
dedup: DedupScopeDeduplication strategy.
NOTE: not read here on the live path. The effective scope comes
from ScanArgs.dedup and is applied by the verifier via
DedupScope; this field is not carried into ScannerConfig.
ml_enabled: boolWhether to enable ML-based probabilistic gating.
ml_weight: f64Weight given to the ML score (0.0 to 1.0).
unicode_normalization: boolWhether to normalize Unicode characters before scanning.
validate_decode: boolWhether to validate decoded strings (e.g. that decoded base64 is UTF-8) before recursing into them.
max_decode_bytes: usizeMaximum bytes allowed from recursive decoding. Same field name on
ScannerConfig so From<ScanConfig> is a 1:1 carry, not a rename.
max_matches_per_chunk: usizeMaximum matches allowed per chunk to prevent OOM.
scan_comments: boolWhen true, credentials inside source-code comments
(//, #, /* */, ) get the same confidence treatment as
credentials in regular code. Default false - comment context
downgrades confidence on the theory that examples are the
common case. CLI exposes this as --scan-comments; opt-in
because the rate of EXAMPLE secrets pasted into doc comments
vastly outweighs the rate of real ones.
known_prefixes: Vec<String>List of common secret prefixes to prioritize.
secret_keywords: Vec<String>List of keywords that strongly indicate a secret.
test_keywords: Vec<String>Keywords used in test environments.
placeholder_keywords: Vec<String>Keywords for placeholders and documentation.
Implementations§
Source§impl ScanConfig
impl ScanConfig
Sourcepub fn validate(&self) -> Result<(), ConfigError>
pub fn validate(&self) -> Result<(), ConfigError>
Validate the configuration parameters, failing closed on any value that
would silently break scanning. This is the “separate later step” the
deserialize path deliberately omits (see the regression_scan_config_fields
contract): ScanConfig::from_toml_str composes deserialize + this into
one validated load, and a library consumer who builds a ScanConfig by
hand calls it directly before handing the config to the engine.
Every check is NaN-safe: RangeInclusive::contains is false for NaN
(so a NaN bound is rejected, not silently admitted), and the entropy
checks reject non-finite values explicitly.
Sourcepub fn from_toml_str(raw: &str) -> Result<Self, ConfigError>
pub fn from_toml_str(raw: &str) -> Result<Self, ConfigError>
Deserialize a ScanConfig from a TOML string and validate it, failing
closed on either a parse error or an out-of-range value.
This is the public, fail-closed loader for the published keyhog-core
config surface. ScanConfig derives Deserialize, so a consumer can
always toml::from_str it directly, but that path is UNVALIDATED by
design (validation is a separate step). from_toml_str is the ONE place
that composes both, so an external min_confidence = 5.0 / ml_weight = 2.0 / entropy_bpe_max_bytes_per_token = 0.0 is rejected here exactly as
the CLI rejects it, instead of being silently honored and zeroing recall
downstream. Callers that already hold a ScanConfig (e.g. built field by
field) should call ScanConfig::validate directly.
Trait Implementations§
Source§impl Clone for ScanConfig
impl Clone for ScanConfig
Source§fn clone(&self) -> ScanConfig
fn clone(&self) -> ScanConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ScanConfig
impl Debug for ScanConfig
Source§impl Default for ScanConfig
impl Default for ScanConfig
Source§impl<'de> Deserialize<'de> for ScanConfig
impl<'de> Deserialize<'de> for ScanConfig
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for ScanConfig
impl RefUnwindSafe for ScanConfig
impl Send for ScanConfig
impl Sync for ScanConfig
impl Unpin for ScanConfig
impl UnsafeUnpin for ScanConfig
impl UnwindSafe for ScanConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more