# awoooi utils: generic secret redactor | 2026-04-20 @ Asia/Taipei """把字串/dict/list 內 secret pattern 遮罩為 。 符合 feedback_secrets_leak_incidents_2026-04-18.md — 任何進 PG/TG/log 前都該過這層。""" from __future__ import annotations import re from typing import Any # 順序:specific 在前,generic 在後(sk-or-v1 / sk-ant 排 sk- 之前) _PATTERNS: list[tuple[re.Pattern[str], str]] = [ (re.compile(r"sk-or-v1-[A-Za-z0-9]{36,}"), "openrouter"), (re.compile(r"sk-ant-api\d{2}-[A-Za-z0-9_\-]{12,}"), "anthropic"), (re.compile(r"sk-[A-Za-z0-9]{40,}"), "openai"), (re.compile(r"ghp_[A-Za-z0-9]{36}"), "github"), (re.compile(r"AIza[0-9A-Za-z_\-]{35}"), "google"), (re.compile(r"\b\d{8,10}:[A-Za-z0-9_\-]{35}\b"), "telegram"), (re.compile(r"AKIA[0-9A-Z]{16}"), "aws"), ] def redact(obj: Any) -> Any: """遮罩字串/dict/list 內 secret,其他型別原值回傳。""" if isinstance(obj, str): s = obj for pat, kind in _PATTERNS: s = pat.sub(f"", s) return s if isinstance(obj, dict): return {k: redact(v) for k, v in obj.items()} if isinstance(obj, list): return [redact(x) for x in obj] return obj