Warn when a short secret value skips redaction
Resolve silently dropped values under 8 bytes from the redaction map,
which is the worst failure mode for a security feature: an operator
declares a 6-char API key, sees it appear in CI logs unmodified, and
has no signal that the threshold is what stopped it. Emit a
WARN-level trace event so the skip is visible.
Assisted-by: Claude Opus 4.7 (1M context)
diff --git a/src/ci/redact.rs b/src/ci/redact.rs
index 9c6fd35..21cee12 100644
--- a/src/ci/redact.rs
+++ b/src/ci/redact.rs
@@ -62,9 +62,11 @@ impl SecretRegistry {
/// for redaction. Returns `Err` if the name isn't declared or
/// the source can't be read.
///
- /// Values shorter than 8 characters are cached for lookup but
- /// not registered for redaction (high false-positive rate on
- /// common short strings like "set", "yes", "true", "no").
+ /// Values shorter than 8 characters are returned to the caller
+ /// but not registered for redaction — the false-positive rate on
+ /// common short strings like "true" or "yes" is too high. A warn
+ /// is emitted so an operator can see why a short token is showing
+ /// up unredacted in CI output.
pub fn resolve(&mut self, name: &str) -> super::error::Result<String> {
let secret = self
.declared
@@ -74,6 +76,12 @@ impl SecretRegistry {
if value.len() >= 8 {
self.revealed
.insert(name.to_string(), Revealed::new(value.clone()));
+ } else {
+ tracing::warn!(
+ secret = %name,
+ length = value.len(),
+ "secret value is shorter than the 8-byte minimum and will not be redacted from CI output"
+ );
}
Ok(value)
}