Zum Inhalt springen

MCP

Auditierung von Claude Code und MCP-Servern in selbstgehosteten Umgebungen

Von Olivares AI 6 min Lesezeit

Ein Plattform-Team rollt Claude Code für ein Dutzend Engineers aus. Damit es nützlich wird, verdrahten sie es mit ein paar MCP-Servern: einer liest das Monorepo, einer fragt ein Reporting-Replica ab, einer legt Tickets an. Innerhalb einer Woche liest ein Agent Quellcode, greift auf eine Datenbank zu und ruft interne Tools auf — und niemand kann die Frage beantworten, die ein Auditor irgendwann stellen wird: welcher Agent hat was getan, mit welcher Ressource, und können Sie beweisen, dass es danach nicht verändert wurde?

Das ist keine hypothetische Lücke. Unabhängige Branchenforschung (CSA/Token, n=418) hat ergeben, dass rund 82 % der Organisationen KI-Agenten betreiben, von denen sie nichts wissen, während nur etwa 21 % ein Echtzeit-Inventar davon führen. Claude Code und MCP sind genau die Art von Fähigkeit, die schnell ankommt und der Audit-Geschichte davonläuft. Die gute Nachricht: Ein belastbarer Trail lässt sich vollständig innerhalb Ihres eigenen Perimeters realisieren, ohne dass Payloads oder Secrets es verlassen.

Warum das naheliegende Setup ein Audit nicht besteht

Das übliche erste Deployment teilt sich eine einzige Credential. Jede Claude-Code-Instanz authentifiziert sich gegenüber der MCP-Ebene und gegenüber nachgelagerten Datenbanken als derselbe Service-Account — mcp-runner, ci-bot, irgendetwas Generisches. Es funktioniert, und es zerstört im Stillen die Zuordnung.

Wenn zehn Agenten als ein einziger Principal agieren, zeigt das Datenbank-Audit-Log zehn Schreibvorgänge von mcp-runner und sonst nichts. Sie können nicht erkennen, aus welcher Engineer-Session das UPDATE kam, ob es aus einem interaktiven Claude-Code-Prompt oder aus einem unbeaufsichtigten Job stammte, oder welches MCP-Tool im Pfad lag. Unabhängige Forschung (Optro) beziffert den Anteil der Organisationen, die die Aktion eines Agenten auf eine Person zurückführen können, auf rund 28 %. Ein gemeinsam genutzter Service-Account ist ein struktureller Grund, warum die Zuordnung zusammenbricht: Das Audit-Log kann zeigen, was passiert ist, aber niemals, welcher Agent es getan hat.

Das zweite Versagen ist die Integrität. Selbst Teams, die pro Aktion loggen, schreiben üblicherweise in einen veränderbaren Speicher. Wenn die Logs in demselben System liegen, das ein Angreifer (oder ein fehlerhafter Agent) erreichen kann, ist „wir haben Logs” nicht dasselbe wie „wir haben Beweise”. Ein Auditor unterscheidet beides scharf.

Identität pro Agent ist das Fundament

Alles Nachgelagerte hängt von der Zuordnung ab, also beheben Sie zuerst die Identität. Statt eines einzelnen gemeinsamen Tokens vergeben Sie eine eigene, kurzlebige Identität pro Agent — idealerweise pro Session. Die Identität reist mit der Anfrage in den MCP-Server und in jede Ressource mit, die der Agent erreicht, sodass der an der Datenbank protokollierte Principal der Agent ist und nicht ein generischer Runner.

Erst das macht Least-Privilege bedeutsam. Ein Reporting-Agent lässt sich auf dem Reporting-Replica auf nur lesenden Zugriff festnageln; ein Release-Agent erhält Schreibzugriff nur auf die Artefakte, die ihm gehören. Jetzt ist ein einzelner beobachteter Schreibvorgang außerhalb dieser Hülle ein präzises, zuordenbares Signal statt Rauschen in einem gemeinsamen Account. Als Policy ausgedrückt, ist die Absicht unmissverständlich:

agent "reporting-assistant" {
  # Claude Code session via the reporting MCP server
  resource "prod-postgres/reporting_replica" {
    access     = "read"      # SELECT only
    deny       = ["write", "ddl"]
  }
  resource "s3://billing-exports" {
    access = "read"
  }
  on_violation {
    action = "block_and_alert"   # refuse at access time, not just log
  }
}

Es geht nicht um die Syntax — es geht darum, dass die Policy den Agenten benennt, die Ressource benennt und Lesen von Lesen/Schreiben trennt. Diese Trennung ist das Entscheidende.

MCP-Annotationen als nicht vertrauenswürdige Signale behandeln

MCP-Tools können sich selbst mit Annotationen wie readOnlyHint und destructiveHint beschreiben. Für die Triage sind sie tatsächlich nützlich — ein Tool, das sich selbst als destruktiv deklariert, verdient eine strengere Policy. Doch die MCP-Spezifikation ist eindeutig, dass es sich um Hinweise handelt, und Clients dürfen sich für Sicherheitsentscheidungen nicht darauf verlassen. Sie stammen vom Server, und genau den auditieren Sie. Ein Tool kann readOnlyHint: true deklarieren und trotzdem einen Schreibvorgang ausführen — sei es durch einen Bug, eine Fehlkonfiguration oder bewusste Umgehung.

Die korrekte Haltung ist daher Bestätigung, nicht Vertrauen. Nehmen Sie die Annotation als Behauptung und prüfen Sie sie gegen die Grundwahrheit aus einer Ebene, die das Tool nicht kontrolliert:

  • Datenbank-Audit-Logs (zum Beispiel PostgreSQL pgAudit) verraten Ihnen, ob ein SELECT oder ein UPDATE tatsächlich ausgeführt wurde.
  • OpenTelemetry-Spans vom MCP-Server und von nachgelagerten Diensten zeigen den Aufrufgraphen und die durchgeführten Operationen.
  • eBPF-Kernel-Signale sind die Absicherung gegen Umgehung: Ein Schreib-Syscall auf eine Datei oder einen Socket ist auf Kernel-Ebene beobachtbar, unabhängig davon, was das Tool im User Space behauptet hat.

Wenn die Annotation „nur lesend” sagt und der Kernel einen Schreibvorgang gesehen hat, ist dieser Widerspruch der zentrale Befund — ein Tool mit readOnlyHint, das auf prod-postgres geschrieben hat, ist genau die Least-Privilege-Abweichung, für die es sich lohnt, jemanden zu wecken. Die Differenz zwischen dem, was die Policy erlaubt hat, und dem, was die Collectors beobachtet haben, ist der Ort, an dem das echte Risiko liegt.

Das Ledger, das ein Auditor akzeptieren wird

Ein Trail ist nur dann ein Beweis, wenn er manipulationssicher ist. Schreiben Sie jedes Ereignis in ein append-only, hash-verkettetes Ledger: Jeder Datensatz enthält den Hash des vorherigen, sodass jede nachgelagerte Änderung oder Löschung die Kette bricht und erkennbar wird. Jede Zeile ordnet die Aktion dem konkreten Agenten zu, benennt die Ressource, hält Lesen versus Lesen/Schreiben fest und trägt ein Konfidenzniveau — attributed, wenn Identität und Ergebnis beide bestätigt sind, approximate, wenn etwas abgeleitet werden musste. Die Konfidenz wird ehrlich ausgewiesen; ein approximativer Treffer wird niemals als belegter Treffer aufgehübscht.

ts=2026-06-08T09:14:02Z agent=reporting-assistant@s3f1 tool=sql-read     resource=prod-postgres/reporting_replica  op=R   outcome=allow   conf=attributed   prev=8a1c…
ts=2026-06-08T09:14:05Z agent=reporting-assistant@s3f1 tool=export-writer resource=s3://billing-exports          op=R   outcome=allow   conf=attributed   prev=2f90…
ts=2026-06-08T09:17:48Z agent=data-export-job@b22e     tool=sql-write     resource=prod-postgres/customers          op=RW  outcome=DENY    conf=attributed   prev=c7d3…  policy=read_only_violation

Diese dritte Zeile ist die, die einen Auditor interessiert: ein Schreibversuch auf eine Tabelle, für die der Agent keine Schreibberechtigung hatte, zum Zugriffszeitpunkt abgelehnt, einem benannten Agenten zugeordnet und in der Kette verankert. Weil die Policy durchgesetzt wird, wenn der Zugriff passiert — und nicht bloß im Nachhinein geloggt — ist die Ablehnung eine Kontrolle, kein Post-Mortem.

Zwei weitere Eigenschaften machen den Trail belastbar. Privilegierte Ansichten werden selbst auditiert: Der Blick auf die Access Map wird festgehalten, sodass „wer hat was gesehen” beantwortbar ist. Und der Beweisexport ist manipulationssicher — Sie übergeben einem Auditor einen signierten Ausschnitt der Kette, den er unabhängig verifizieren kann, statt einer CSV, der er auf Treu und Glauben vertrauen muss.

EigenschaftGemeinsamer Service-AccountIdentität pro Agent + hash-verkettetes Ledger
ZuordnungEin Principal für alle AgentenAktion an den konkreten Agenten/die Session gebunden
Lesen vs. SchreibenVermischtGetrennt und policy-geprüft
IntegritätVeränderbare LogsAppend-only, Kette bricht bei Änderung
Auditfähiger ExportCSV auf Treu und GlaubenSignierter, unabhängig verifizierbarer Ausschnitt

Warum Self-Hosting hier zählt

All das funktioniert, ohne dass irgendetwas Ihr Netzwerk verlässt. Der Collector beobachtet — Logs, OpenTelemetry, eBPF als Absicherung auf Kernel-Ebene — statt im Datenpfad des Agenten zu sitzen, sodass er, wenn er ausfällt, niemals den Agenten oder die dahinterliegende Produktionsanfrage bricht. Das Ledger speichert Zugriffs-Beziehungen, keine Payloads: Es hält fest, dass reporting-assistant reporting_replica gelesen hat, nicht die zurückgegebenen Zeilen. Eingaben, die Secrets oder PII enthalten könnten, werden redigiert und auf Secrets gescannt, bevor irgendetwas geschrieben wird. Für air-gapped, DSGVO-gebundene oder durch Datenresidenz beschränkte Umgebungen ist das der Unterschied zwischen einer Audit-Geschichte, die Sie verteidigen können, und einer, die Sie nicht verteidigen können: Nichts an Ihrer Nutzung von Claude Code und MCP funkt nach Hause, weil das System die Daten von vornherein nie sieht.

Claude Code und MCP sind es wert, ausgerollt zu werden. Sie brauchen nur einen Audit-Trail, der genauso gebaut ist, wie Sie ihn für jede andere privilegierte Automatisierung bauen würden — Identität zuerst, Ergebnisse bestätigt, Beweise verankert. Wenn Sie sehen möchten, wie die Access Map und das manipulationssichere Ledger zusammenpassen, gehen das Sicherheitsmodell und der Produktüberblick bei jedem davon tiefer.

Häufige Fragen

Kann ich dem readOnlyHint eines MCP-Tools vertrauen, um zu belegen, dass eine Aktion nur lesend war?

Nein. Die MCP-Spezifikation legt fest, dass Tool-Annotationen wie readOnlyHint und destructiveHint Hinweise sind und als nicht vertrauenswürdig behandelt werden müssen, da sie vom Server stammen und nicht von einer Durchsetzungsebene. Nutzen Sie sie zur Triage und um Widersprüche zu kennzeichnen, belegen Sie das tatsächliche Lese-/Schreibergebnis aber mit Telemetrie oder Signalen auf Kernel-Ebene (OpenTelemetry-Spans, Datenbank-Audit-Logs, eBPF). Vertrauen Sie dem bestätigten Ergebnis, nicht der Annotation.

Wie ordne ich eine Claude-Code-Aktion einem bestimmten Agenten statt einem gemeinsam genutzten Service-Account zu?

Vergeben Sie eine eigene, kurzlebige Identität pro Agent oder pro Session statt eines einzelnen gemeinsamen Tokens. Wenn der Agent eine Datenbank oder einen MCP-Server erreicht, reist diese Identität mit der Anfrage mit, sodass das Audit-Ledger festhält, welcher Agent was getan hat. Ein gemeinsam genutzter Service-Account fasst jeden Agenten zu einem einzigen Principal zusammen und macht Least-Privilege pro Agent sowie eine manipulationssichere Zuordnung im Nachhinein unmöglich.

Sehen Sie, worauf Ihre Agenten zugreifen können

Olivares AI ist die offene, selbstgehostete Plattform für Ihre KI-Landschaft. Betreiben Sie sie auf Ihrer eigenen Infrastruktur und erhalten Sie die Zugriffskarte, nach der Ihre Security- und Platform-Teams seit Langem fragen.