feat(utils): generic secret_redactor (7 patterns)
Some checks failed
run-migration / migrate (push) Failing after 12s
CD Pipeline / build-and-deploy (push) Failing after 1m36s

This commit is contained in:
Your Name
2026-04-20 04:04:09 +08:00
parent 60b06ac54c
commit 0db4534133
3 changed files with 68 additions and 0 deletions

View File

View File

@@ -0,0 +1,31 @@
# awoooi utils: generic secret redactor | 2026-04-20 @ Asia/Taipei
"""把字串/dict/list 內 secret pattern 遮罩為 <redacted:kind>。
符合 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"<redacted:{kind}>", 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

View File

@@ -0,0 +1,37 @@
# 2026-04-20 @ Asia/Taipei
from apps.api.src.utils.secret_redactor import redact
def test_openrouter_key_redacted():
assert "<redacted:openrouter>" in redact("sk-or-v1-abcdef0123456789ABCDEFghijklmnopqrstuv")
def test_anthropic_key_redacted():
assert "<redacted:anthropic>" in redact("sk-ant-api03-abcDEF_123-xyz")
def test_github_token_redacted():
assert "<redacted:github>" in redact("ghp_abcdef0123456789ABCDEFghijklmnopqrst")
def test_google_key_redacted():
assert "<redacted:google>" in redact("AIzaSyABCDEFGHIJKLMNOPQRSTUVWXYZ1234567")
def test_telegram_bot_token_redacted():
assert "<redacted:telegram>" in redact("8474499448:AAFqu_i4-PN4zGFOK5ea8o0Ud56qqEtCMeI")
def test_aws_key_redacted():
assert "<redacted:aws>" in redact("key=AKIAIOSFODNN7EXAMPLE")
def test_clean_passthrough():
assert redact("normal text here") == "normal text here"
def test_nested_dict():
d = {"a": "ghp_abcdef0123456789ABCDEFghijklmnopqrst", "b": {"c": "AIzaSyABCDEFGHIJKLMNOPQRSTUVWXYZ1234567"}}
out = redact(d)
assert "ghp_abc" not in str(out)
assert "AIzaSy" not in str(out)