Output Gate
Das Output Gate ist ToolMeshs Inhaltskontrollschicht. JavaScript-Policies laufen vor (pre) und nach (post) jeder Tool-Ausführung und ermöglichen Eingabevalidierung, Ausgabefilterung und PII-Schwärzung.
Funktionsweise
Abschnitt betitelt „Funktionsweise“Gate-Policies sind Top-Level-JavaScript-Dateien im policies/-Verzeichnis. Sie werden von goja ausgeführt, einer Go-nativen JavaScript-Engine, mit einem Timeout von 5 Sekunden pro Policy.
Jede Policy erhält eine einzige globale Variable ctx und läuft in einer von zwei Phasen:
pre— vor der Tool-Ausführung.ctx.paramsmodifizieren, um den Aufruf umzuschreiben, oderthrow, um ihn abzulehnen.post— nach der Tool-Ausführung.ctx.response.contentmodifizieren, um die Antwort zu filtern.
Wirft das Skript einen String oder Error, wird der Aufruf abgelehnt. Läuft es ohne Throw durch, wird der Aufruf zugelassen.
ctx-Referenz
Abschnitt betitelt „ctx-Referenz“| Feld | Beschreibung |
|---|---|
ctx.phase | "pre" oder "post" |
ctx.tool | Tool-Name mit Backend-Präfix (z. B. github_merge_pull) |
ctx.toolAccess | DADL-Access-Tag: "read", "write", "admin", "dangerous" oder leer |
ctx.params | Tool-Parameter (in pre mutierbar) |
ctx.response.content | Tool-Antwort (in post mutierbar; nur in post befüllt) |
ctx.user.userID | Authentifizierte Nutzerkennung |
ctx.user.callerId | Caller-Identität (z. B. cli, claude-desktop) |
ctx.user.callerClass | "trusted", "standard" oder "untrusted" |
ctx.user.roles | Array mit Nutzerrollen |
ctx.rateLimitExceeded(n) | Funktion — liefert true, wenn der Nutzer n Aufrufe/Stunde überschritten hat |
Beispiele
Abschnitt betitelt „Beispiele“Gefährliche Parameter ablehnen (pre)
Abschnitt betitelt „Gefährliche Parameter ablehnen (pre)“if (ctx.phase === "pre" && ctx.params.force_delete === true) { throw "force_delete ist per Policy gesperrt";}PII aus Antworten schwärzen (post)
Abschnitt betitelt „PII aus Antworten schwärzen (post)“if (ctx.phase === "post" && ctx.response && ctx.response.content) { for (var i = 0; i < ctx.response.content.length; i++) { var block = ctx.response.content[i]; if (block && block.type === "text" && block.text) { block.text = block.text.replace( /[\w.-]+@[\w.-]+\.\w+/g, "[REDACTED]" ); } }}Mutationen an ctx.response.content werden in die Live-Antwort zurückpropagiert — nachgelagerte Evaluatoren und der Executor sehen den geschwärzten Inhalt.
Co-Authored-By aus GitHub-PRs entfernen (pre)
Abschnitt betitelt „Co-Authored-By aus GitHub-PRs entfernen (pre)“Viele AI-Coding-Agents hängen Co-Authored-By-Trailer an Commit-Nachrichten und PR-Beschreibungen. Eine Pre-Gate-Policy entfernt diese vor dem GitHub-API-Aufruf:
if (ctx.phase === "pre") { var coAuthorPattern = /^[Cc]o-[Aa]uthored-[Bb]y:.*$/gm;
function stripTrailer(text) { if (!text) return text; return text .replace(coAuthorPattern, "") .replace(/\n{3,}/g, "\n\n") .replace(/\n+$/, "\n"); }
if (ctx.tool === "github_create_pull" || ctx.tool === "github_update_pull") { if (ctx.params.body) { ctx.params.body = stripTrailer(ctx.params.body); } } if (ctx.tool === "github_merge_pull" && ctx.params.commit_message) { ctx.params.commit_message = stripTrailer(ctx.params.commit_message); } if (ctx.tool === "github_create_git_commit" && ctx.params.message) { ctx.params.message = stripTrailer(ctx.params.message); }}Der AI-Agent merkt nichts davon, und keine Co-Authored-By-Zeile erreicht das Repository.
Read-only-Durchsetzung für untrusted Caller (pre)
Abschnitt betitelt „Read-only-Durchsetzung für untrusted Caller (pre)“if (ctx.phase === "pre" && ctx.user.callerClass === "untrusted" && ctx.toolAccess !== "read") { throw "CallerClass 'untrusted' darf nur Tools mit Access-Tag 'read' aufrufen";}Das setzt auf den DADL-access-Tag (read, write, admin, dangerous), der pro Tool deklariert wird — siehe DADL-Spezifikation.
CallerClass-basierte Filterung
Abschnitt betitelt „CallerClass-basierte Filterung“Das Gate erhält die CallerClass und ermöglicht abgestufte Policies:
| CallerClass | Typische Filterung |
|---|---|
trusted | Nur Credentials |
standard | Hochrisiko-PII + Credentials |
untrusted | Alle PII-Muster, nur Read-Tools |
Rate Limiting
Abschnitt betitelt „Rate Limiting“Policies können ein Sliding-Window-Rate-Limit pro Nutzer durchsetzen:
if (ctx.phase === "pre" && ctx.rateLimitExceeded(100)) { throw "Rate Limit überschritten (100/Stunde)";}Konfiguration
Abschnitt betitelt „Konfiguration“GATE_EVALUATORS=goja # goja-Evaluator aktivieren (Standard)Policy-Dateien im policies/-Verzeichnis ablegen. ToolMesh lädt sie beim Start.
Enterprise: Compliance-LLM
Abschnitt betitelt „Enterprise: Compliance-LLM“Die Enterprise-Erweiterung fügt einen LLM-basierten Gate-Evaluator hinzu, der Inhalte gegen Compliance-Regeln klassifiziert. Das ermöglicht Policies wie „Antworten mit Finanzberatung blockieren”, ohne Regex-Muster schreiben zu müssen.