fix: write-ahead audit entry so calls stop when the audit log stops accepting writes (SEC-03)

This commit is contained in:
Latte committed 2026-10-14 17:11:53 +02:00
1 parent 5b622e64e2
commit 43eebd3089
8 files changed
+134 -15

No files matched your search

+15
View File
@@ -162,6 +162,21 @@ class AuditLogger:
payload["error"] = error
return self._append_entry("tool_invocation", payload)
def log_tool_call_started(
self, tool_name: str, correlation_id: str, domain: str | None = None
) -> str:
"""Write the write-ahead entry of a call that is about to run.
The dispatcher writes it before executing a known tool and refuses the call
when it cannot be written, so an audit log that stopped accepting writes
after startup (full disk, revoked mount) stops the calls instead of letting
them run unrecorded. The final ``tool_invocation`` entry carries the result.
"""
payload: dict[str, Any] = {"correlation_id": correlation_id, "tool_name": tool_name}
if domain is not None:
payload["domain"] = domain
return self._append_entry("tool_call_started", payload)
def log_access_denied(
self,
tool_name: str,
+13
View File
@@ -430,6 +430,19 @@ class _Dispatcher:
record.outcome = "unknown_tool"
raise MCPError(types.INVALID_PARAMS, f"Unknown tool: {record.tool}")
record.domain = entry.domain
# Write-ahead entry: a call whose start cannot be recorded does not run.
try:
audit.log_tool_call_started(entry.tool.name, request_id, entry.domain)
except Exception as exc:
logger.error("audit log write failed, refusing the call: %s", type(exc).__name__)
record.outcome = "audit_unavailable"
return _result(
_error_payload(
"audit_unavailable",
"The audit log is not writable, so the call was not executed",
),
is_error=True,
)
try:
return await self._dispatch(entry, arguments, record)
except Exception as exc: