diff --git a/agent/redact.py b/agent/redact.py index 153a245dfd..58eef2dd39 100644 --- a/agent/redact.py +++ b/agent/redact.py @@ -159,7 +159,10 @@ _PREFIX_PATTERNS = [ r"pypi-[A-Za-z0-9_-]{10,}", # PyPI API token r"dop_v1_[A-Za-z0-9]{10,}", # DigitalOcean PAT r"doo_v1_[A-Za-z0-9]{10,}", # DigitalOcean OAuth - r"am_[a-f0-9]{32,}", # AgentMail API key (hex format, 32+ chars) + # AgentMail API key: ``am_`` / ``am_org_`` + an opaque alphanumeric body. The body has no ``_``/``-``, + # which is what separates it from ``am_example_identifier_123`` (#10983); public docs pin only the + # prefix, so the charset stays broad and the length floor does the discriminating. + r"am_(?:org_)?[A-Za-z0-9]{20,}", r"sk_[A-Za-z0-9_]{10,}", # ElevenLabs TTS key (sk_ underscore, not sk- dash) r"tvly-[A-Za-z0-9]{10,}", # Tavily search API key r"exa_[A-Za-z0-9]{10,}", # Exa search API key diff --git a/tests/agent/test_redact.py b/tests/agent/test_redact.py index b1c722a81f..3ef316e98a 100644 --- a/tests/agent/test_redact.py +++ b/tests/agent/test_redact.py @@ -63,8 +63,8 @@ class TestKnownPrefixes: """``am_`` is a common identifier prefix; only the documented hex key body is a secret (#10983).""" for benign in ["schema.am_example_identifier_123", "path/to/am_monthly_report.sql"]: assert redact_sensitive_text(benign) == benign - key = "am_" + "0123456789abcdef" * 2 - assert "0123456789abcdef" not in redact_sensitive_text(f"AGENTMAIL_API_KEY is {key}") + for key in ("am_" + "0123456789abcdef" * 2, "am_" + "Ab9" * 8, "am_org_" + "Zq7k" * 6): + assert key[-12:] not in redact_sensitive_text(f"leaked {key} in output"), key def test_slack_token(self): token = "xoxb-" + "0" * 12 + "-" + "a" * 14