hermes-agent/tests/monitoring/test_export_redaction.py
Victor Kyriazakos 87a15733c0 fix(monitoring): address review — persist install_id, drop dead config, single redaction path
- Cut the leftover telemetry.* DEFAULT_CONFIG block (nothing reads it) and
  the legacy telemetry-key fallback in policy.py.
- install_id: persist the minted UUID back to config.yaml on first use so
  service.instance.id survives gateway restarts (fail-open when the write
  is not possible); regression test covers the restart path.
- Remove the no-op gateway_health_export.redaction config keys. Redaction
  is always-on by design and deliberately not configurable; status output
  now says so.
- Collapse redaction to one unconditional secrets+PII scrub: drop the
  none/pii content modes (they served the dropped trajectories plane) and
  fold gateway_health.py's duplicate bearer/token/email/phone regex layer
  into agent/monitoring/redaction.py.
2026-07-24 18:54:45 +00:00

69 lines
2.1 KiB
Python

"""Export redaction tests — the security-critical layer.
Invariants:
* One unconditional scrub: secrets AND PII, no modes, no knobs.
* Fails CLOSED: if the redactor can't run, the raw string is never emitted.
* Structure (subsystem names, error codes) survives; free-text PII does not.
"""
from __future__ import annotations
from unittest import mock
import agent.monitoring.redaction as R
def test_secret_key_always_stripped():
fake_key = "sk-ant-api03-" + "A" * 24 # constructed to dodge literal-scrubbers
out = R.redact_for_export(f"calling with key {fake_key} and moving on")
assert out is not None
assert fake_key not in out
def test_token_shapes_stripped():
ghp = "ghp_" + "0123456789abcdef" * 2 + "0123"
slack = "xoxb-" + "123456789012-abcdefABCDEF"
out = R.redact_for_export(f"token {ghp} and {slack} leaked")
assert out is not None
assert ghp not in out
assert slack not in out
assert "[redacted]" in out
def test_bearer_header_stripped():
out = R.redact_for_export("Authorization: Bearer abc.def-ghi_jkl")
assert out is not None
assert "abc.def-ghi_jkl" not in out
def test_none_passthrough():
assert R.redact_for_export(None) is None
def test_pii_always_stripped():
text = ("reach alice@example.com or +1 415 555 0100, "
"install 123e4567-e89b-12d3-a456-426614174000")
out = R.redact_for_export(text)
assert out is not None
assert "alice@example.com" not in out
assert "426614174000" not in out
assert "[email]" in out
assert "[id]" in out
assert "[phone]" in out
def test_ordinary_words_survive():
assert R.redact_for_export("just ordinary words") == "just ordinary words"
def test_structure_preserved():
out = R.redact_for_export("platform.slack entered fatal after auth_failed")
assert out is not None
assert "platform.slack" in out
assert "auth_failed" in out
def test_fails_closed_when_redactor_unavailable():
with mock.patch("agent.redact.redact_sensitive_text", side_effect=RuntimeError):
out = R.redact_for_export("secret sauce sk-live-key")
assert out == "[redaction-unavailable]"