Skip to content

Secrets in LLM Logs

LLMs like to quote user input in their responses. If a user accidentally (or intentionally) sends their OPENAI_API_KEY — it will end up in your logs. That’s a compliance incident, plain and simple.

The simplest detector to run over any payload:

import re, os, requests
PATTERNS = [
r"sk-[A-Za-z0-9]{20,}", # OpenAI / Anthropic style
r"AKIA[0-9A-Z]{16}", # AWS Access Key
r"ghp_[A-Za-z0-9]{30,}", # GitHub PAT
r"xox[baprs]-[A-Za-z0-9-]{10,}", # Slack
r"AIza[0-9A-Za-z\-_]{35}", # Google API key
r"eyJ[A-Za-z0-9_\-]{20,}\.[A-Za-z0-9_\-]{20,}\.[A-Za-z0-9_\-]{20,}", # JWT
]
RX = re.compile("|".join(PATTERNS))
def scan(text: str, where: str):
m = RX.search(text or "")
if m:
token = m.group(0)
push(f"🔑 LEАК в {where}",
f"Похожий на секрет токен: {token[:6]}{token[-4:]}\n"
f"Длина: {len(token)} символов\n\n"
"Немедленно ротируйте ключ и удалите запись из логов.",
priority=10)
return True
return False
def push(t, m, p):
requests.post(f"{os.environ['NOTIFLY_URL']}/message",
params={"token": os.environ["NOTIFLY_TOKEN"]},
json={"title": t, "message": m, "priority": p}, timeout=5)

Run scan() on the user-input before sending it to the LLM (reject), and on the model output before writing it to logs (mask + alert).