feat(brain-mcp): audit-log every tools/call with principal and scope

brain_query and brain_read left no record of who read what; only capture
and governance edits reached the audit sink (OWASP MCP08).

One slog record per call: tool, principal, origin (static/jwt/unknown),
wing/hall when given, outcome, duration. Content is reduced to
content_bytes so the audit line never copies brain content.

Refs #144

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 20:44:21 +02:00
co-authored by Claude Opus 5.5
parent f21be1aef6
commit a9a9eebe26
3 changed files with 139 additions and 0 deletions
+3
View File
@@ -16,6 +16,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/mathiasbq/hyperguild/ingestion/internal/brainstore"
"github.com/mathiasbq/hyperguild/ingestion/internal/capture"
@@ -229,7 +230,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx = withPrincipal(ctx, principal, viaStatic)
}
}
start := time.Now()
out, err := s.handleCall(ctx, p.Name, p.Arguments)
logToolCall(ctx, p.Name, p.Arguments, start, err)
if err != nil {
rpcErr = &rpcError{Code: -32000, Message: err.Error()}
break