So funktioniert die Abschottung
Das Sicherheitsmodell der codegestützten KI-Triage – warum die Netzwerkgrenze außerhalb des Agenten liegt und wie Sie einen GitLab Runner abschotten.
Diese Übersetzung ist möglicherweise veraltet. Die englische Version wurde seit der letzten Übersetzung dieser Seite aktualisiert. Auf Englisch ansehen →
Warum das zählt
Die codegestützte KI-Triage gibt einem KI-Agenten gleichzeitig Zugriff auf Ihren Quellcode und den von Angreifern kontrollierten Meldungstext. Das ist ein Ziel für Prompt-Injection. Ein böswilliger Forscher könnte im Text Anweisungen verstecken, mit denen der Agent Geheimnisse lesen und an einen externen Host senden soll.
Die Abwehr besteht nicht darin, den Agenten freundlich darum zu bitten, dies zu unterlassen. Entscheidend ist: Selbst ein vollständig übernommener Agent kann Daten nirgendwohin senden. Die Netzwerkgrenze wird außerhalb des Agenten auf Umgebungsebene erzwungen. Diese Seite erklärt die Grenze und ihre Einrichtung.
Danger
Behandeln Sie jeden Meldungstext als feindlich. Der Triage-Prompt schließt Felder in Trennzeichen ein und weist das Modell an, enthaltene Anweisungen nie auszuführen. Diese Trennung bietet zusätzliche Sicherheit, ist aber nicht die Grenze. Die Grenze ist die unten beschriebene vollständige Egress-Sperre.
Das Grundprinzip: Begrenzung auf Umgebungsebene
Der wichtigste Entwurfsgrundsatz lautet: Der Agent darf nicht seine eigene Begrenzung durchsetzen.
Tool-Allowlist, System-Prompt, Claude-Code-Sandbox und Docker-Container helfen, reichen allein aber nicht:
- Modell-Ausgaben sind nicht vertrauenswürdig. Ein erfolgreicher Prompt-Injection-Angriff kann den Agenten dazu bringen, erlaubte Werkzeuge anders zu verwenden als vorgesehen.
- Sandbox-Escape-Sicherheitslücken gibt es. Halten Sie Versionen aktuell, verlassen Sie sich aber nicht allein auf die Allowlist.
- Erlaubte Domains können Unter-APIs zur Ausschleusung enthalten. Wenn Sie die Domain Ihres LLM-Anbieters freigeben, können dort auch Datei-Uploads oder Speicher-APIs liegen – perfekte Kanäle für Datenabfluss, die eine reine Host-Regel zulässt.
Die deterministische Garantie „kann nichts ausschleusen“ muss daher außerhalb des Agenten in Netzwerk- und Runner-Konfiguration liegen.
Die Grenze: Egress vollständig sperren und zwei Ziele zulassen
Die Abschottung besteht aus vier Kontrollen auf Umgebungsebene. Das Beispiel-Repository zeigt sie in .gitlab-ci.yml und im Verzeichnis infra/.
1. Selbst verwalteter GitLab Runner
Sie müssen einen selbst verwalteten Runner verwenden. Bei gemeinsam genutzten GitLab.com-SaaS-Runnern können Sie das Host-Netzwerk nicht selbst isolieren und die Egress-Grenze daher nicht erzwingen. Die README des Beispiel-Repositories nennt dies als Voraussetzung.
2. Docker Executor ohne Privilegien
| Einstellung | Wert | Warum |
|---|---|---|
privileged |
false |
Privilegierter Modus entspricht praktisch Root auf dem Host und ist bei nicht vertrauenswürdigen Meldungen ausgeschlossen. |
| Ausführung als | Nicht-Root |
SETUID/SETGID entfernen; keine unnötigen Capabilities. |
| Docker-Socket | Nicht eingehängt | Ein eingehängter Socket ermöglicht die Übernahme des Hosts. |
| Host-Volumes | Keine | Keine Bind-Mounts in den Job. |
FF_NETWORK_PER_BUILD |
1 |
GitLab erstellt pro Job ein eigenes Bridge-Netzwerk und entfernt es danach. Das macht das Job-Netzwerk isoliert und reproduzierbar. |
# config.toml on your self-managed runner
[[runners]]
executor = "docker"
environment = ["FF_NETWORK_PER_BUILD=1"]
[runners.docker]
privileged = false
3. Egress auf Host-Ebene standardmäßig sperren
Warning
GitLab Runner besitzt keine native Egress-Allowlist. Eine eingebaute Einstellung „Jobs dürfen nur diese Hosts erreichen“ ist vorgeschlagen, aber nicht verfügbar. Die Egress-Grenze muss auf Host- oder Namespace-Ebene erzwungen werden.
Wenden Sie mit iptables/nftables eine Egress-Richtlinie mit standardmäßigem DROP auf das Job-Netzwerk an oder führen Sie den Job in einem Netzwerk-Namespace ohne Route in Ihr Intranet aus. Ausgehender Verkehr ist zunächst vollständig gesperrt. Danach öffnen Sie ausschließlich die beiden folgenden Ziele – sonst nichts, auch nicht Ihr internes Netzwerk.
4. TLS-terminierender Egress-Proxy mit Token-Prüfung
Der einzige Weg nach außen führt über einen Proxy, der genau zwei Ziele zulässt:
- Ihren LLM-Inferenzendpunkt, etwa
https://api.deepseek.com/anthropic. - Den begrenzten MCP-Host von Kit, um die Meldung zu lesen und die Triage zurückzusenden.
Der Proxy beschränkt nicht nur die Hosts. Er:
- erlaubt ausschließlich Inferenz- und MCP-Pfade. Datei- und Speicher-APIs des LLM-Anbieters bleiben gesperrt, selbst wenn sie auf demselben Host liegen.
- prüft das Sitzungstoken des jeweiligen Laufs. Selbst wenn ein Angreifer einen eigenen API-Schlüssel in den Agenten einschleust, kann er ihn nicht verwenden, weil der Proxy nur das für diesen Lauf ausgestellte Token akzeptiert.
Das ähnelt dem MITM-Proxy innerhalb einer VM, den Anthropic zur Begrenzung eigener Agenten verwendet. Ein Egress-Filter nach Art von harden-runner ist ein passendes konzeptionelles Vorbild.
Maskierung ist Hygiene, kein Schutz
Übergeben Sie das begrenzte MCP-Token und Ihren Modellschlüssel als maskierte und geschützte CI-Variablen. So landen Geheimnisse nicht in Job-Protokollen. Die Grenze bleibt jedoch:
Important
Maskierung verhindert nur, dass ein Wert im Protokoll erscheint ([MASKED]). Ein übernommener Job kann den Wert zur Laufzeit weiterhin lesen. Laut GitLab ist Maskierung selbst keine narrensichere Sicherheitsmaßnahme. Den Abfluss eines gelesenen Tokens verhindert die vollständige Egress-Sperre, nicht die Maskierung.
Deshalb ist das begrenzte Token wichtig: Selbst wenn ein übernommener Job es liest, gilt es nur für eine Meldung, eine Stunde und eine Verwendung auf der Schreibseite. Es kann keine anderen Meldungen lesen, keinen Status ändern, keine Nachrichten senden und keine Prämie genehmigen.
Nachweis mit der Injection Canary
Das Beispiel-Repository enthält in examples/sample-report eine Injection Canary – Meldungstext, der versucht, per curl einen externen Host aufzurufen. Führen Sie die Pipeline damit aus und bestätigen Sie, dass die Egress-Grenze den Aufruf blockiert. Gelingt der Aufruf, ist die Umgebung nicht abgeschottet. Korrigieren Sie die Host-Firewall, bevor Sie Kit verbinden.
Verantwortung für Datenresidenz und Modell
Sie wählen das Modell und tragen auch dessen Risiko. Wenn Sie Quellcode und nicht vertrauenswürdige Meldungen an einen gehosteten Endpunkt senden, standardmäßig an die DeepSeek-API, treffen Sie eine Entscheidung über Datenresidenz und Vertrauen. Genau das bedeutet „Ihre KI, Ihr Netzwerk“. Wo es sinnvoll ist, verwenden Sie einen selbst gehosteten Endpunkt wie lokales vLLM oder einen Ollama-Anthropic-Proxy, damit die Inferenz Ihren Sicherheitsbereich nie verlässt. SECURITY.md im Beispiel-Repository weist ebenfalls darauf hin.
Kurz-Check
- Selbst verwalteter GitLab Runner, kein gemeinsam genutzter SaaS-Runner
-
Docker Executor mit
privileged = false, Nicht-Root, ohne Docker-Socket und Host-Volumes -
FF_NETWORK_PER_BUILD=1zur Netzwerkisolierung pro Job -
Egress auf Host-Ebene mit standardmäßigem
DROP, über iptables/nftables oder einen Netzwerk-Namespace - Egress-Proxy, der genau zwei Hosts und Pfade erlaubt: Ihren LLM-Endpunkt und den MCP-Host von Kit
- Proxy prüft das Token des jeweiligen Laufs und sperrt Speicher-Unter-APIs des LLM-Anbieters
- Begrenztes Token als Ein-Meldung-/Ein-Stunde-/Einmal-Schreib-Token behandeln; Maskierung ist nur Hygiene
- Injection Canary ausführen und bestätigen, dass der Ausschleusungsversuch blockiert wird
- Aktuelle Version von Claude Code und Sandbox-Laufzeit festschreiben – als zusätzliche Sicherheit, nicht als Grenze
Wie geht es weiter
- Abgeschotteten Triage-Agenten einrichten – der geführte Ablauf zum Verbinden Ihres Forks
- Prompt und Modell des Triage-Agenten anpassen – Modellwechsel, Prompt-Hygiene und Ausgabeschema
- Codegestützte KI-Triage – Ergebnisse und Darstellung der Triage