3838 re .compile (r"sk-ant-[a-zA-Z0-9_\-]{32,}" , re .IGNORECASE ),
3939 re .compile (r"Bearer\s+[a-zA-Z0-9_\-\.=]{20,}" , re .IGNORECASE ),
4040 re .compile (r"x-api-key:\s*[^\s,;]{20,}" , re .IGNORECASE ),
41+ re .compile (
42+ r"\b(api[_-]?key|auth[_-]?token|credential|password|private[_-]?key|secret|token)\s*[:=]\s*([\"']?)[^\"'\s,;]{8,}([\"']?)" ,
43+ re .IGNORECASE ,
44+ ),
4145]
4246
4347
@@ -130,7 +134,10 @@ def _sanitize_user_input(value: Any, *, max_length: int = SANITIZE_MAX_FIELD_LEN
130134def _scrub_api_key_from_text (text : str ) -> str :
131135 """Replace API key-like patterns in error messages with '[REDACTED]'."""
132136 for pattern in _API_KEY_SCRUB_PATTERNS :
133- text = pattern .sub ("[REDACTED]" , text )
137+ text = pattern .sub (
138+ lambda match : f"{ match .group (1 )} =[REDACTED]" if match .lastindex == 3 else "[REDACTED]" ,
139+ text ,
140+ )
134141 return text
135142
136143
@@ -362,7 +369,7 @@ def _call() -> str:
362369 detail = _scrub_api_key_from_text (detail )
363370 raise AiAuditError (f"HTTP { exc .code } : { detail } " ) from exc
364371 except (urllib .error .URLError , OSError , ValueError ) as exc :
365- raise AiAuditError (f"network or encoding error: { exc } " ) from exc
372+ raise AiAuditError (f"network or encoding error: { _scrub_api_key_from_text ( str ( exc )) } " ) from exc
366373
367374 payload = json .loads (response_body )
368375 choices = payload .get ("choices" ) if isinstance (payload , Mapping ) else None
@@ -430,7 +437,7 @@ def _call() -> str:
430437 detail = _scrub_api_key_from_text (detail )
431438 raise AiAuditError (f"HTTP { exc .code } : { detail } " ) from exc
432439 except (urllib .error .URLError , OSError , ValueError ) as exc :
433- raise AiAuditError (f"network or encoding error: { exc } " ) from exc
440+ raise AiAuditError (f"network or encoding error: { _scrub_api_key_from_text ( str ( exc )) } " ) from exc
434441
435442 payload = json .loads (response_body )
436443 content = payload .get ("content" ) if isinstance (payload , Mapping ) else None
@@ -488,7 +495,10 @@ def _codex_via_gateway(prompt: str, model: str, timeout_seconds: float) -> str:
488495 except ImportError :
489496 return _codex_exec_direct (prompt , timeout_seconds )
490497 except Exception as exc :
491- _logger .warning ("ai_audit gateway codex call failed: %s; falling back to direct" , exc )
498+ _logger .warning (
499+ "ai_audit gateway codex call failed: %s; falling back to direct" ,
500+ _scrub_api_key_from_text (str (exc )),
501+ )
492502 return _codex_exec_direct (prompt , timeout_seconds )
493503
494504
@@ -505,7 +515,10 @@ def _llm_via_gateway(prompt: str, model: str, provider: str, timeout_seconds: fl
505515 except ImportError :
506516 return _llm_direct (prompt , model , provider , timeout_seconds )
507517 except Exception as exc :
508- _logger .warning ("ai_audit gateway analyze call failed: %s; falling back to direct" , exc )
518+ _logger .warning (
519+ "ai_audit gateway analyze call failed: %s; falling back to direct" ,
520+ _scrub_api_key_from_text (str (exc )),
521+ )
509522 return _llm_direct (prompt , model , provider , timeout_seconds )
510523
511524
@@ -755,7 +768,7 @@ def _build_taco_audit_messages(taco_payload: Mapping[str, Any]) -> tuple[Mapping
755768
756769
757770def _failure_text (exc : BaseException ) -> str :
758- return _bounded_text (f"{ type (exc ).__name__ } : { exc } " , limit = 300 )
771+ return _bounded_text (_scrub_api_key_from_text ( f"{ type (exc ).__name__ } : { exc } " ) , limit = 300 )
759772
760773
761774def _report_shadow_disagreement (
0 commit comments