event redaction: document content-only vs exact-match entry points

build_redacted_event_payload and redacted_event_json apply only the content-based pass; redacted_run_event additionally applies the per-run exact-match SecretRedactor. The names didn't signal that difference, so a caller holding a run redactor could silently pick a content-only path. Document each entry point and steer such callers to redacted_run_event.

Also drop a no-op guard in the node_label branch: the redacted value was already computed, so the conditional assignment saved nothing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Scott Werner 2026-07-07 16:53:24 -04:00
parent 4242d2e71f
commit 78cf3faf1c

View file

@ -5,6 +5,11 @@ use fabro_store::EventPayload;
use fabro_util::json::normalize_json_value;
use serde_json::Value;
/// Build a stored event payload with **content-based** redaction only.
///
/// This does not apply the per-run exact-match [`SecretRedactor`]; on any
/// surface that has the run's redactor, use [`redacted_run_event`] instead so
/// declared low-entropy secrets are removed as well.
pub fn build_redacted_event_payload(event: &RunEvent, run_id: &RunId) -> Result<EventPayload> {
EventPayload::new(redacted_event_value(event)?, run_id).map_err(anyhow::Error::from)
}
@ -22,6 +27,11 @@ pub fn redacted_run_event(event: &RunEvent, redactor: &SecretRedactor) -> Result
RunEvent::try_from(&payload).map_err(anyhow::Error::from)
}
/// Serialize an event to JSON with **content-based** redaction only.
///
/// Like [`build_redacted_event_payload`], this applies the content pass but not
/// the per-run exact-match [`SecretRedactor`]. Prefer [`redacted_run_event`]
/// wherever the run redactor is available.
pub fn redacted_event_json(event: &RunEvent) -> Result<String> {
serde_json::to_string(&redacted_event_value(event)?).map_err(anyhow::Error::from)
}
@ -42,10 +52,7 @@ fn redact_event_payload_secrets(value: &mut Value, redactor: &SecretRedactor) {
redact_redactable_event_properties(properties, redactor);
}
if let Some(Value::String(label)) = value.get_mut("node_label") {
let redacted = redactor.redact_into(label);
if redacted != *label {
*label = redacted;
}
*label = redactor.redact_into(label);
}
}