Files
ObsiGate/backend/tools/audit.py
T

55 lines
1.5 KiB
Python

"""Audit logging for AI tool calls.
Reuses the application audit log (``data/audit.log``, JSON lines) and adds an
``ai_tool_call`` action. Argument values that may contain sensitive payloads
(file content, prompts) are summarized rather than stored verbatim.
"""
from __future__ import annotations
from datetime import UTC, datetime
from typing import Any
from backend.audit import _write_entry
# Argument keys whose values may contain secrets or large payloads.
_SENSITIVE_ARG_KEYS = {"content", "text", "body"}
_MAX_ARG_CHARS = 200
def _sanitize_arguments(arguments: dict[str, Any] | None) -> dict[str, Any]:
"""Return a log-safe view of tool arguments."""
safe: dict[str, Any] = {}
for key, value in (arguments or {}).items():
if key in _SENSITIVE_ARG_KEYS:
safe[key] = f"<{len(str(value))} chars>"
else:
safe[key] = str(value)[:_MAX_ARG_CHARS]
return safe
def log_tool_call(
*,
username: str,
mode: str,
tool: str,
arguments: dict[str, Any] | None = None,
ok: bool = True,
vault: str | None = None,
ip: str | None = None,
error: str | None = None,
) -> None:
"""Append an ``ai_tool_call`` entry to the audit log."""
_write_entry({
"timestamp": datetime.now(UTC).isoformat(),
"action": "ai_tool_call",
"username": username,
"ip": ip or "unknown",
"mode": mode,
"tool": tool,
"vault": vault,
"ok": ok,
"error": error,
"arguments": _sanitize_arguments(arguments),
})