From 605f6a3e608cbc78b41c9b39d4cd90aa40bbee8d Mon Sep 17 00:00:00 2001 From: Richard Date: Tue, 22 Sep 2026 11:23:23 +0200 Subject: [PATCH] Security-Konzept: Zugangsdatenverwaltung (#703), Datei erstmals versioniert Der Agent schickt Platzhalter, ClawdDotNet setzt sie im Werkzeug ein. Der Ansatz ist richtig, loest aber weniger als er verspricht - die sieben Luecken dazwischen sind die Arbeit. Die beiden wichtigsten: Ersetzt wird an benannten Stellen je Werkzeug, nie als Suchen-und-Ersetzen ueber alle Argumente; und jedes Geheimnis wird an ein Ziel gebunden, sonst schuetzt der Platzhalter den Wert vor dem Modell und liefert ihn an den Angreifer. Die Datei lag bisher unversioniert im Arbeitsbaum, obwohl fuenf Items (#651-#659) ueber doc_anchor auf sie verweisen. Damit war die Begruendung fuer niemanden ausserhalb dieses Rechners lesbar - genau das, was die Regeln in CLAUDE.md verhindern sollen. Co-Authored-By: Claude Opus 5 --- docs/Security-Konzept.md | 425 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 docs/Security-Konzept.md diff --git a/docs/Security-Konzept.md b/docs/Security-Konzept.md new file mode 100644 index 0000000..6b93239 --- /dev/null +++ b/docs/Security-Konzept.md @@ -0,0 +1,425 @@ +# Security-Konzept: Einschließen, Regeln, Überwachen + +> **Rolle:** Bauplan. Stand 2026-09-19, entstanden aus dem Orchestrator-Vergleich +> (OpenClaw, Grok Bot, Claude Code/Codex, OpenHands, LlamaFirewall, CaMeL) und der +> Abstimmung mit dem Nutzer. Reihenfolge und Status stehen im Deploymentcenter, nicht +> hier. + +## 1 — Das Ziel in einem Satz + +**Ein bösartiger Agent — auch einer, der durch eingeschleusten Text übernommen wurde — +darf seinen Workspace nicht verlassen und nichts Schädliches tun.** Das muss auch dann +gelten, wenn Agenten eigene Skripte schreiben und ausführen. + +## 2 — Der Grundsatz: das Modell ist nie die Grenze + +Ein Überwachungsagent kann einen Ausbruch nicht verhindern, nur hinterher bemerken. Und +er ist selbst angreifbar: Er liest genau die Verläufe, in denen der eingeschleuste Text +steht. Deshalb vier Schichten, nach Kosten sortiert — die unteren drei sind +deterministisch und kosten keine Tokens, erst die oberste fragt ein Modell: + +| Schicht | Was | Kosten | Verhindert / erkennt | +|---|---|---|---| +| 0 Einschließen | Sandbox-Runner für jede Codeausführung | keine Tokens | verhindert | +| 1 Regeln vor dem Aufruf | PermissionGate, Staging, Herkunftsregel, Netzprofil | keine Tokens | verhindert | +| 2 Regelbasierte Überwachung | Detektoren über das Audit, Köderwerte | keine Tokens | erkennt sofort | +| 3 Security-Agent | Einschätzung auf Anlass, Skriptprüfung, Stichprobe | gedeckelt | erkennt, bewertet | + +So machen es die Systeme, die tragen: Claude Code und Codex setzen die Grenze im +Betriebssystem (bubblewrap bzw. Landlock + seccomp) und prüfen mit einem Modell nur +zusätzlich. OpenClaw zeigt die Gegenseite — dort ist die Sandbox *optional*, und die +Vorfälle mit ClawHub kamen genau daher. + +### Warum das jetzt dran ist + +Heute laufen alle Agenten **in einem Prozess unter einem Linux-Benutzer**. Die +Workspace-Grenze ist C#-Code in den Werkzeugen (`PathBoundary`); #373 hat gezeigt, wie +leicht sie bricht. Das trägt, solange Agenten keinen eigenen Code ausführen. Ein +Python-Skript fragt `PathBoundary` nicht — `open('/home/...')` geht am Werkzeug vorbei. +Und der Hauptprozess hält den entsperrten Hauptschlüssel. + +**Regel, nicht verhandelbar: Fremder Code läuft nie im Hauptprozess.** Kein Skript, +keine Shell, kein MCP-stdio-Server ohne den Runner aus Schicht 0. + +### Das Bedrohungsmodell wird um eine Klasse erweitert + +Bisher: rein interner Betrieb; Schutz gegen Ordner-Kopieren und gegen Schadsoftware, die +nach Zugangsdaten sucht. Das bleibt. Neu: **Der Angreifer ist Inhalt, keine Person** — +eine Webseite, eine Mail, eine Chatnachricht, ein Tool-Ergebnis, das einen Agenten +umsteuert. Interner Betrieb schützt davor nicht, weil die Agenten Fremdinhalt lesen, +sobald sie ihre Arbeit tun. + +## 3 — Schicht 0: Sandbox-Runner + +Ein gemeinsamer Runner für alles, was Code ausführt: Shell (#196), freigegebene Skripte +(Abschnitt 7), MCP-stdio-Server (#197) und die heutigen `yt-dlp`/`ffmpeg`-Aufrufe des +`SocialMediaManagerTool`. + +Garantien, jede mit einem Test, der den Ausbruch versucht: + +- **Dateisystem:** Nur der Workspace des Agenten ist beschreibbar und sichtbar; System + schreibgeschützt, `$HOME`, Instanzverzeichnis, Schlüsselbund und die Workspaces anderer + Agenten sind nicht vorhanden (eigener Mount-Namespace, nicht bloß gesperrt). +- **Erbe:** Keine Umgebungsvariablen, keine offenen Dateideskriptoren, keine Secrets des + Hauptprozesses. Was ein Skript braucht, bekommt es ausdrücklich übergeben. +- **Netz:** Standardmäßig kein Netz (eigener Netz-Namespace). Freigabe nur über den + Egress-Proxy, siehe Abschnitt 5. +- **Grenzen:** Laufzeit, Speicher, Prozesszahl, Ausgabegröße; seccomp-Filter; kein + Rechteerwerb (`no_new_privs`). +- **Umsetzung:** `bwrap` unter Linux. Ein eigener Linux-Benutzer je Agent ist die + spätere Stufe, falls die Namespace-Trennung einmal nicht reicht. + +- **Nichts, was der Hauptprozess liest, ist in der Sandbox beschreibbar.** Task-Dateien, + Skills, Identity/Soul, Skript-Manifeste, Gedächtnis-Importe und jede Konfiguration + liegen außerhalb des beschreibbaren Bereichs oder sind dort schreibgeschützt + eingebunden. Das ist die Lehre aus CVE-2026-25725 bei Claude Code: Code in der Sandbox + legte Hooks an, die beim nächsten Start mit vollen Rechten liefen. Eine Sandbox, die + Dateien schreiben darf, die draußen ausgeführt oder als Anweisung gelesen werden, ist + keine Grenze, sondern ein verzögerter Ausbruch. Ein Test gehört dazu: Die Sandbox + versucht jede dieser Dateien zu schreiben. + +Unter Windows gibt es keinen Runner und damit **keine Codeausführung** — die Funktion +fehlt dort, statt schwächer zu sein. + +## 4 — Schicht 1: Regeln vor dem Aufruf + +Vorhanden: PermissionGate (Werkzeug je Agent), Staging mit Plan-Freeze, `PathBoundary`, +`UrlGuard`, `SqlGuard`. Neu: + +### 4.1 Herkunftsregel + +Vorbild CaMeL, in der einfachsten Form. Sobald ein Lauf **Fremdinhalt** gelesen hat — +WebFetch, Mail, Chat, eine Datei, die nicht der Agent selbst geschrieben hat, das +Ergebnis eines MCP-Servers —, gilt der Lauf als *belastet*. Ab dann ist jede Aktion mit +**Außenwirkung** freigabepflichtig, egal was die Policy sonst sagt: Mail senden, posten, +FTP-Upload, Schreiben in die Datenbank, Nachricht an andere Agenten, Task an andere +Agenten. + +Das kostet nichts und nimmt einer übernommenen Anweisung genau die Wirkung, um die es +geht: Sie kann lesen und vorschlagen, aber nicht handeln. Welche Werkzeuge Fremdinhalt +liefern und welche Außenwirkung haben, erklärt jedes Werkzeug selbst (wie +`StagingAktion` seit #609). Die Freigabe-Nachricht (#644) nennt die Quelle, die den Lauf +belastet hat. + +**Freigabemüdigkeit ist der eigentliche Gegner dieser Regel.** Der Sicherheitsvergleich +vom 2026-09-19 hat sie als realistischstes Einfallstor ausgemacht: Fast jeder Agent liest +Fremdinhalt, fast jeder Lauf wird belastet, und wer 40 Freigaben am Tag abnickt, ist +selbst der Umgehungsweg. Deshalb gehört zur Regel: + +- **Feste Ziele sind ausgenommen.** Außenwirkung an Ziele, die ein Mensch vorab + eingerichtet hat — die eigenen Kanäle, `@human`, fest hinterlegte Empfänger je Agent — + bleibt ohne Freigabe. Eine Injection kann dorthin schreiben, aber niemanden erreichen, + den der Betreiber nicht selbst ausgewählt hat. +- **Muster-Freigabe auf Zeit.** Ein wiederkehrender Aufruf (gleicher Agent, gleiches + Werkzeug, gleiches Ziel) kann für eine begrenzte Frist freigegeben werden, statt jeden + Einzelfall zu bestätigen. Nie für hohe Risiken, nie ohne Ablauf. +- **Die Freigabequote wird sichtbar** (Abschnitt 10). Wer 100 % durchwinkt, hat keine + Kontrolle mehr, sondern eine Verzögerung — das soll man sehen, nicht vermuten. +- **Die Vorschau zeigt Herkunft.** Argumente, die Daten aus sensiblen Quellen tragen + (Gedächtnis, Datenbank, Dateien außerhalb von `out/`), werden in der Freigabe + hervorgehoben — sonst geht ein Abfluss, versteckt in einem langen Argument, durch die + Freigabe hindurch. + +### 4.2 Schutz vor Amoklauf + +Rate-Limits je Werkzeug und Agent, Circuit-Breaker bei gehäuften Fehlern oder +Ablehnungen — der Übergang zur Quarantäne (Abschnitt 6). Aus dem +[Erweiterungskonzept](Orchestrator-Erweiterungskonzept-2026.md). + +### 4.3 Belastung wandert mit + +Die Lücke, die der Vergleich aufgedeckt hat und die kein anderes Konzept schließt: Ein +belasteter Lauf schreibt einen Gedächtniseintrag, einen Skill-Entwurf oder einen Task. +Ein *späterer, unbelasteter* Lauf lädt ihn — und die eingeschleuste Anweisung wirkt +jetzt ohne Herkunftsmarke. Die Herkunftsregel wäre über einen Umweg ausgehebelt. + +Deshalb: **Was ein belasteter Lauf hinterlässt, trägt die Marke weiter** — Gedächtnis, +Skill-Entwürfe, Tasks und Task-Kommentare, Dateien im SharedWorkspace. Die Engine +stempelt sie, nicht der Agent. **Wer einen markierten Eintrag lädt, wird selbst +belastet.** Ein Mensch kann einen Eintrag nach Prüfung entlasten; das steht im Audit. +Skill-Entwürfe aus belasteten Läufen sind in der Freigabe (#198) ausdrücklich markiert. + +## 5 — Netzprofil je Agent + +Ein Agent hat **drei getrennte Wege ins Netz**. Sie werden oft in einen Topf geworfen, +sind aber verschieden gefährlich und brauchen eigene Schalter. + +| Weg | Wer ruft auf | Wer wählt das Ziel | Heute | Einstellung | +|---|---|---|---|---| +| **Modell** | die Engine, zu OpenRouter | niemand — immer OpenRouter | fest | Modell-Netzprofil (5.1) | +| **Werkzeuge** | der Hauptprozess (WebFetch, Mail, MCP …) | der Agent, im Rahmen der Allowlist | WebFetch mit Domain-Allowlist, muss je Agent freigegeben werden | bleibt je Werkzeug | +| **Sandbox** | ein Skript oder Shell-Befehl | der Code | gibt es noch nicht | aus; Freigabe je Skript (5.2) | + +Der Weg zu OpenRouter ist **kein** Internetzugang des Agenten: Die Engine spricht mit +genau einem Ziel, der Agent kann weder Adresse noch Inhalt der Verbindung bestimmen. Er +wird aber dann zum Internetzugang, wenn das *Modell selbst* suchen darf. + +### 5.1 Modell-Netzprofil (je Agent, in den Modelleinstellungen) + +- **Websuche des Modells:** OpenRouter kann dem Modell eine eigene Websuche geben (Plugin + `web` oder das Suffix `:online` am Modellnamen). Das ist ein Netzweg, an dem weder + Staging noch Audit vorbeikommen. **Voreinstellung aus**; ein Modellname mit `:online` + wird abgelehnt, solange der Schalter aus ist. +- **Datennutzung beim Anbieter:** `data_collection: deny` als Voreinstellung (das Feld + ist in `ProviderPreferences` schon vorhanden, wird aber noch nicht gesetzt); optional + nur Anbieter ohne Datenspeicherung. +- **Anbieter-Allowlist und Ausweichen:** Welche Anbieter ein Agent nutzen darf, ob auf + andere ausgewichen werden darf (`allow_fallbacks`). +- `require_parameters` bleibt an (#550). + +### 5.2 Sandbox-Netz + +Standard: kein Netz. Braucht ein Skript Netz, **deklariert es die Ziele in seinem +Manifest** (Abschnitt 7), und die Freigabe des Skripts umfasst diese Ziele. Durchgesetzt +wird es vom Egress-Proxy: nur die deklarierten Domains, nur HTTPS, jeder Abruf im Audit. +Ein Skript, das etwas anderes erreichen will, scheitert und erzeugt einen Befund. + +## 6 — Befunde und Quarantäne + +### 6.1 Zwei Stufen + +| Stufe | Beispiele | Reaktion | Aufheben | +|---|---|---|---| +| **Niedrig** | gehäufte Ablehnungen, Kostensprung, neue Zieldomain, Änderung an Identity/Soul | Nachricht über den Kanal (#644) mit Quarantäne-**Vorschlag** — per Button bestätigen oder verwerfen | im Messenger oder in der Oberfläche | +| **Hoch** | Köderwert in einem ausgehenden Aufruf, Ausbruchsversuch aus der Sandbox, Zugriff auf fremde Workspaces, Skript weicht vom freigegebenen Hash ab | **sofortige Quarantäne**, Nachricht über den Kanal **ohne** Schaltfläche | **nur in der Oberfläche**, nach Prüfung | + +Warum hoch nicht per Messenger: Der Messenger ist ein Kanal, über den auch Fremdinhalt +kommt, und ein Telefon geht leichter verloren als der Zugang zur Oberfläche. Wer einen +Agenten nach einem Köder-Treffer wieder freilässt, soll die Belege vor sich haben. + +### 6.2 Was Quarantäne heißt + +- Der Agent nimmt keine neuen Läufe an (Scanner überspringt ihn, Chat wird abgewiesen). +- Ein laufender Lauf endet beim nächsten Schritt; Sandbox-Prozesse des Agenten werden + beendet. +- Alle ausgehenden Nachrichten des Agenten werden zurückgehalten. +- Seine offenen Freigabe-Vorschläge werden gesperrt, nicht gelöscht. +- Alles ist umkehrbar und steht im Audit. Nichts wird gelöscht. + +### 6.3 Ausnahmen für bekannte Befunde + +Damit dieselbe Meldung nicht jeden Tag wiederkommt: + +- Jeder Befund hat einen **Fingerabdruck** aus Detektor, Agent, Werkzeug und normalisiertem + Ziel. Gleiche Fingerabdrücke innerhalb eines Zeitfensters werden zu einem Befund mit + Zähler zusammengefasst, statt neu gemeldet zu werden. +- Eine **Ausnahme** gilt für einen Fingerabdruck, trägt Begründung, Urheber und ein + **Ablaufdatum** und steht im Audit. Ausnahmen ohne Ablauf gibt es nicht. +- Ausnahmen für niedrige Befunde gehen auch im Messenger („nicht mehr melden, 30 Tage"), + für hohe nur in der Oberfläche. +- **Nie ausnehmbar:** Köder-Treffer und Sandbox-Ausbruchsversuche. + +## 7 — Skripte, die Agenten selbst schreiben + +Vorgabe: Freigegebene Agenten dürfen eigene Skripte schreiben. Ausgeführt wird nur, was +geprüft ist; **jede Änderung, auch ein Bugfix, braucht eine neue Prüfung.** + +- **Wer darf:** nur Agenten mit der Fähigkeit „Skripte schreiben". Standard aus. +- **Form:** Das Skript liegt im Workspace unter `scripts/`, daneben ein Manifest: Zweck, + Interpreter, Eingaben, Ausgaben, Netzziele (5.2), Laufzeitgrenze. +- **Bindung:** Die Freigabe gilt für den SHA-256 von Skript **und** Manifest **und** die + Interpreter-Fassung — nach dem Vorbild von OpenClaws Exec-Freigaben, die an Befehl, + Arbeitsverzeichnis und Datei-Hashes gebunden sind. Ändert sich ein Byte, passt der Hash + nicht mehr: nicht ausführbar, neue Prüfung. Versucht ein Agent, ein verändertes Skript + auszuführen, ist das ein hoher Befund. +- **Saubere Umgebung.** Der Hash allein reicht nicht: Im August 2026 wurde Claude Codes + Auto-Modus umgangen, indem ein Archiv eine Datei `struct.py` in das Arbeitsverzeichnis + legte, die beim Import eines Standardmoduls mitgeladen wurde („confused environment"). + Ein freigegebenes Skript läuft deshalb **aus einer schreibgeschützten, sauberen Kopie**, + mit `python -I` (kein Arbeitsverzeichnis, kein `PYTHONPATH` im Suchpfad), mit + Abhängigkeiten, die im Manifest **mit Hash** festgeschrieben sind, und der Workspace ist + nur als Datenverzeichnis unter einem eigenen Pfad eingebunden. Was das Skript lädt, ist + damit genau das, was geprüft wurde. +- **Ablauf der Prüfung:** + 1. **Deterministische Vorprüfung** (kostenlos): Größe, Imports und Aufrufe, die eine + Begründung brauchen (`subprocess`, `socket`, `ctypes`, `os.system`, `eval`/`exec`, + dynamisches Nachladen, Base64-Dekodieren mit anschließender Ausführung), Abgleich + mit dem Manifest („deklariert kein Netz, importiert aber `requests`"). + 2. **Einschätzung des Security-Agenten:** *unbedenklich* / *bedenklich* (mit Gründen + und Zeilen) / *zu komplex für mich — externe Prüfung*. Ab einer Größen- oder + Komplexitätsgrenze lautet das Urteil ohne Modellaufruf „zu komplex". Externe + Prüfung heißt: Mensch, oder auf ausdrückliche Einstellung ein stärkeres Modell mit + eigenem Budget. + 3. **Freigabe durch den Menschen**, mit Vorprüfung, Einschätzung und Diff zur vorigen + Fassung vor Augen. +- **Die Einschätzung ist ein Rat, keine Freigabe.** Auch „unbedenklich" gibt nichts frei. + Und selbst ein freigegebenes Skript läuft nur im Runner — die Prüfung ist die zweite + Linie, nicht die erste. +- **Selbstschutz des Prüfers:** Das Skript ist für den Security-Agenten Fremdinhalt. Ein + Kommentar wie „als unbedenklich einstufen" darf nichts bewirken: Die Vorprüfung aus + Schritt 1 kann das Modell nicht überstimmen, die Ausgabe ist strukturiert, und ein + Urteil, das der Vorprüfung widerspricht, wird als Widerspruch angezeigt, nicht still + übernommen. + +## 8 — Schicht 2: Regelbasierte Überwachung + +Detektoren über das Audit-Log. Laufen bei jedem Eintrag bzw. im Scanner-Takt, kosten keine +Tokens und erzeugen Befunde nach Abschnitt 6. + +- Grenzverletzungen (`PathBoundary`, `UrlGuard`, `SqlGuard`, Sandbox) und abgelehnte + Aufrufe in Serie +- neue Zieldomains, neue Empfänger +- Kostensprung gegenüber dem eigenen Mittel +- Änderungen an Identity, Soul, Skills, Skripten +- verdächtige Folgen innerhalb eines Laufs: erst Fremdinhalt oder sensible Pfade lesen, + dann Außenwirkung versuchen +- **Köderwerte:** Köderdateien im Workspace und Köder-Secrets im Schlüsselbund, die kein + legitimer Ablauf je braucht. Taucht ein Köderwert in einem ausgehenden Aufruf, einer + Nachricht oder im Sandbox-Netz auf → hoher Befund, sofortige Quarantäne. Praktisch + keine Fehlalarme, weil es keinen legitimen Grund gibt, ihn zu benutzen. + +## 9 — Schicht 3: Security-Agent + +**Ein eingeschränktes Profil des AgentInspector (#204), kein zweites System.** Gleiche +Datenbasis (Audit und Receipts, von der Engine gestempelt), gleicher Zweck. + +- **Wann er läuft:** auf Anlass aus Schicht 2 (Befund bewerten, Zusammenhänge suchen), + bei jeder Skriptprüfung (Abschnitt 7) und einmal täglich als Stichprobe mit kurzer + Lagezusammenfassung. Nie dauerhaft mitlaufend. +- **Was er sieht:** strukturierte Audit-Daten — Werkzeug, Ausgang, Pfade, Ziele, Kosten. + Rohe Fremdtexte nur gekürzt und als Daten gerahmt (#193). +- **Was er darf — hart im Code, nicht im Prompt:** Befunde anlegen und einstufen, über + den Kanal melden, Quarantäne vorschlagen (niedrig) oder verhängen (hoch), Skripte + einschätzen. **Nie:** freigeben, Quarantäne aufheben, Ausnahmen anlegen, Regeln oder + Einstellungen ändern, Werkzeuge mit Außenwirkung benutzen. +- **Kosten:** günstiges Modell, eigenes Tagesbudget im Budget-Guard mit hartem Deckel. + Ist der Deckel erreicht, laufen Schicht 0 bis 2 unverändert weiter, nur Einschätzungen + bleiben aus — und das wird im Sicherheitsbereich angezeigt. Planbar wird es durch den + Deckel und dadurch, dass Schicht 2 vorfiltert. + +## 10 — Sicherheitsbereich in Oberfläche und WebUI + +Eigener Menüpunkt auf Instanzebene, in Avalonia und in der Weboberfläche gleich +aufgebaut: + +- **Freigabequote** je Agent und Werkzeug: wie viel wird freigegeben, wie schnell, wie + oft abgelehnt. Eine Quote nahe 100 % bei hoher Zahl ist selbst ein Befund. +- **Lage:** Sandbox verfügbar, Schlüsselbund dicht, Agenten in Quarantäne, offene + Befunde, offene Skriptprüfungen, Kanalzustand (#645), Budget des Security-Agenten. +- **Befunde:** Liste mit Stufe, Fingerabdruck, Zähler, Beleg aus dem Audit; Quarantäne + aufheben (hoch: nur hier), Ausnahme anlegen. +- **Skripte:** ausstehende Prüfungen mit Vorprüfung, Einschätzung und Diff; freigegebene + Skripte mit Hash und Freigabe-Datum. +- **Richtlinien je Agent:** Netzprofil (Abschnitt 5), Herkunftsregel, Skript-Fähigkeit, + Sandbox-Grenzen. +- **Ausnahmen:** mit Ablauf, Urheber, Begründung. +- **Selbstprüfung auf Drift:** „Sandbox konfiguriert, aber nicht verfügbar", „Modell mit + `:online` bei ausgeschalteter Websuche", „Agent darf Skripte schreiben, Runner fehlt". + Vorbild `openclaw security audit`; die Prüfungen gehören zu den Bausteinen von #648. + +Zwei Regeln: + +- **Agenten kommen an diesen Bereich nicht heran** — auch AgentEditor und ein + Personalmanager-Agent nicht. Seine Einstellungen liegen außerhalb dessen, was ein + Werkzeug schreiben kann. +- **Wer eine Regel lockert, bestätigt ausdrücklich**, und die Änderung steht im Audit. + In der Weboberfläche verlangt das eine erneute Anmeldung. + +## 11 — Zugangsdaten: der Agent sieht sie nie + +*Ergänzt am 2026-09-22 nach einem Vorschlag des Nutzers.* + +Heute bekommt ein Werkzeug seine Zugangsdaten aus der Konfiguration des Agenten. Wo ein +Agent eine fremde API bedienen soll, steht der Schlüssel in Reichweite dessen, was in +seinen Kontext geraten kann. + +**Der Vorschlag: eine Zugangsdatenverwaltung in ClawdDotNet.** Der Agent bekennt nie +einen Wert zu sehen, sondern schreibt einen Platzhalter; ClawdDotNet setzt ihn im +Werkzeug ein, kurz bevor der Aufruf hinausgeht. + +``` +Agent: DirectAPI, Header: { "Authorization": "Bearer {{secret:amazon-sp-api}}" } +ClawdDotNet: ersetzt beim Aufruf, protokolliert die Benutzung, nie den Wert +Antwort: wird auf dem Rückweg maskiert, bevor sie in den Kontext geht +``` + +Das ist der richtige Ansatz, und er löst ein echtes Problem. Er löst aber nicht so viel, +wie er auf den ersten Blick verspricht — und die Lücken dazwischen sind die eigentliche +Arbeit. + +### Wo es klemmt + +**1. Ein Platzhalter darf nicht überall ersetzt werden.** +Ein stumpfes Suchen-und-Ersetzen über alle Argumente wäre die größte Falle: Dann schreibt +ein Agent `{{secret:amazon-sp-api}}` in einen Dateiinhalt, in ein SQL-Statement, in eine +Nachricht oder in eine URL — und der Wert landet dort, wo ihn jeder lesen kann. Die +Ersetzung gehört an **benannte Stellen je Werkzeug** (etwa `DirectAPI.headers`, +`Database.connection`), nie an beliebige Zeichenketten. + +**2. Der Platzhalter schützt den Schlüssel, nicht das Ziel.** +Auch mit (1): Ein Agent, der den Schlüssel im Kopf `Authorization` verwenden darf, kann +die Anfrage an eine beliebige Adresse richten — und schickt das Geheimnis dorthin. Die +Verwaltung muss deshalb **jedes Geheimnis an ein Ziel binden**: „dieser Schlüssel gilt nur +gegen `sellingpartnerapi.amazon.com`". Ohne diese Bindung gibt der Platzhalter ein +falsches Gefühl von Sicherheit. Das Netzprofil je Agent (Abschnitt 5) ist die Hälfte +davon; die andere gehört an den Eintrag selbst. + +**3. Die Antwort kann das Geheimnis enthalten.** +Manche Dienste spiegeln Token in Fehlermeldungen zurück, manche Bibliotheken schreiben +die Verbindungszeichenfolge in die Ausnahme (`Password=…`). Dann steht der Wert im +Werkzeugergebnis, im Kontext und im Transkript. **Die Maskierung auf dem Rückweg ist +keine Zugabe, sondern die zweite Hälfte des Mechanismus** — der allgemeine Fall ist #192, +der Anfang steht in #660. + +**4. Was gilt als Verwendung durch einen Fremden?** +Ein Agent, der nie den Wert sieht, kann ihn nicht verraten — aber er kann ihn *benutzen*, +und dazu lässt sich ein Agent überreden. Der Platzhalter schützt gegen **Diebstahl der +Zugangsdaten**, nicht gegen **Missbrauch der Befugnis**. Dagegen helfen die Zielbindung, +die Freigaberegeln und die Herkunftsregel (#651) — nicht der Platzhalter. + +**5. Die Verwaltung erbt die Schwäche des Hauptschlüssels.** +Eine Zugangsdatenverwaltung ist ein Tresor. Solange **#190** offen ist — der Hauptschlüssel +liegt unter Linux im Klartext —, legt man damit mehr Eier in einen Korb, von dem man +weiß, dass er offen steht. Der Tresor macht den Betrieb ordentlicher, die Sicherheit +verbessert er erst nach #190. Reihenfolge entsprechend. + +**6. Nicht verraten, was es gibt.** +Fragt ein Agent nach `{{secret:buchhaltung-bank}}`, das ihm nicht zugeteilt ist, muss das +Werkzeug abweisen — **ohne zu sagen, ob dieses Geheimnis existiert**. Dieselbe Überlegung +wie beim Hinweis auf den anderen Arbeitsbereich (#662). + +**7. Zuteilung ist eine Rechteänderung.** +Wer welches Geheimnis benutzen darf, entscheidet ein Mensch, nie ein Agent — auch keine +Abteilungsleitung. Die Zuteilung gehört an die Einheit (siehe Organisation-Konzept, +#683/#692), damit sechs Einkäufer sie einmal bekommen und die Buchhaltung den +Marktplatzschlüssel nicht sieht. + +### Was der Tresor dafür zurückgibt + +- **Eine Stelle zum Wechseln.** Ein rotierter Schlüssel wird einmal geändert, alle Agenten + arbeiten weiter. +- **Benutzungsspuren.** Wer hat wann welches Geheimnis gegen welches Ziel verwendet — + im Audit, ohne den Wert. Ein nie benutzter Eintrag kann weg; ein plötzlich viel + benutzter ist ein Befund. +- **Ein sauberer Weg für Skripte.** Ein freigegebenes Skript (#657) bekommt sein + Geheimnis als Umgebungsvariable vom Läufer, deklariert im Manifest — nie im Quelltext, + nie im Aufrufprotokoll (#696). + +### Urteil + +Bauen, ja — aber mit Zielbindung und Rückweg-Maskierung von Anfang an, und nach #190. +Ein Platzhalter allein verschiebt das Geheimnis nur von der Agentenkonfiguration in die +Werkzeugkonfiguration. + +## 12 — Reihenfolge und Items + +| Item | Vorhaben | Abschnitt | +|---|---|---| +| #651 | Herkunftsregel, mit Ausnahmen für feste Ziele, Muster-Freigabe und Herkunft in der Vorschau | 4.1 | +| #659 | Belastung wandert mit (Gedächtnis-Vergiftung) | 4.3 | +| #652 | Befunde und Quarantäne mit zwei Stufen, Ausnahmen | 6 | +| #653 | Regelbasierte Detektoren und Köderwerte | 8 | +| #654 | Sandbox-Runner | 3 | +| #655 | Netzprofil je Agent | 5 | +| #656 | Sicherheitsbereich in Avalonia und Weboberfläche | 10 | +| #657 | Skriptprüfung | 7 | +| #658 | Security-Agent (Profil von #204) | 9 | + +1. **#651 mit #659, #652, #653** — größter Nutzen je Aufwand, braucht nur das Vorhandene und die + Messenger-Freigabe (#644). +2. **#654** — harte Vorbedingung für Skripte, Shell (#196) und MCP-stdio-Server (#197); + steht deshalb vor beiden. +3. **#655** und **#656**. +4. **#657** — mit #198, weil Skripte mit den Skills kommen. +5. **#658** — zuletzt, auf #204 aufbauend. Bis dahin prüft bei Skripten der Mensch + allein, mit der deterministischen Vorprüfung.