§ DOCUMENTATION
Benutzerdefinierte Validatoren (BYOV)
Ihr eigener HTTPS-Endpunkt, den Execlave während der Richtliniendurchsetzung aufruft. Führen Sie Ihre eigene Geschäftslogik aus — Finanzobergrenzen, Datenraum-ACLs, systemübergreifende Lookups — innerhalb der Allow-/Deny-Entscheidung.
Wann ein benutzerdefinierter Validator sinnvoll ist
Die integrierten Richtlinientypen (Prompt Injection, PII, Rate-Limits, Werkzeugumfang, Ausgabenobergrenzen) decken die meisten Governance-Anforderungen ab. Benutzerdefinierte Validatoren sind die Notluke, wenn Ihre Richtlinie von Zuständen abhängt, die Execlave nicht speichert.
- Kundenspezifische Ausgabenlimits, die in Ihrem Abrechnungssystem liegen.
- Berechtigungs-Lookups (Rolle, Org, Region) gegen Ihren IdP oder LDAP.
- Zugriffsprüfungen auf Zeilenebene gegen einen internen Datenkatalog.
- Geschäftszeiten-/Freeze-Window-Gates, gesteuert durch Ihren Betriebskalender.
- Systemübergreifende Freigaben, bei denen Execlave-Freigaben allein nicht ausreichen.
Ein Validator ist einfach ein HTTPS-Endpunkt. Execlave signiert jede Anfrage mit einem HMAC-SHA256-Secret, erzwingt SSRF-Schutzmaßnahmen und respektiert Ihren konfigurierten Fail-Modus (fail_closed standardmäßig).
Request-Vertrag
POST an Ihren Endpunkt, bevor der Agent ausführt. Der Body spiegelt den Durchsetzungskontext wider.POST https://validators.internal.acme.com/enforceContent-Type: application/jsonX-Execlave-Signature: sha256=<hex HMAC of the raw body>X-Execlave-Timestamp: 2026-04-22T09:00:00ZX-Execlave-Validator-Id: 5f3a…X-Execlave-Delivery-Id: 9c21… { "organizationId": "org_...", "agentId": "agt_...", "agentName": "finance-assistant", "environment": "production", "input": "Transfer $50,000 to vendor-9923", "tools": ["payments.transfer"], "metadata": { "userId": "u_42" }, "estimatedCost": 0.02, "timestamp": "2026-04-22T09:00:00Z"}Response-Vertrag
200 und einem JSON-Body, der eine von drei Entscheidungen enthält. Jeder andere Statuscode wird als Fehler behandelt und vom konfigurierten Fail-Modus gehandhabt.HTTP/1.1 200 OKContent-Type: application/json { "decision": "deny", "reason": "Transfer exceeds $10,000 daily cap for finance-assistant", "metadata": { "policyRef": "FIN-TX-0003" }}| Entscheidung | Verhalten |
|---|---|
allow | Validator ist zufrieden — die Durchsetzung wird mit den übrigen Richtlinien fortgesetzt. |
deny | Löst PolicyBlockedError / ValidatorDeniedError im SDK aus — der LLM-Aufruf wird verhindert. |
require_approval | Erstellt eine Freigabeanfrage und setzt den Aufruf aus, bis ein Mensch zustimmt. |
Sicherheitsgarantien
- Nur HTTPS — der SSRF-Schutz weist Nicht-HTTPS-URLs und jedes Ziel zurück, das auf eine private, Loopback-, Link-Local- oder Cloud-Metadaten-Adresse auflöst.
- HMAC-SHA256-signiert — ein 32-Byte-validatorbezogenes Secret, serverseitig generiert und einmalig angezeigt. Rotieren Sie es jederzeit; das alte Secret funktioniert sofort nicht mehr.
- Replay-geschützt — Anfragen enthalten einen RFC3339-Zeitstempel; lehnen Sie alles ab, was älter als 15 s ist.
- Circuit Breaker — nach 10 aufeinanderfolgenden Fehlern öffnet der Validator; Execlave ruft ihn 30 s lang nicht mehr auf und wendet während der Abkühlphase den konfigurierten Fail-Modus an.
- Größenbegrenzt — Antworten größer als
VALIDATOR_MAX_RESPONSE_BYTES(Standard 64 KiB) werden abgebrochen und als Fehler behandelt. - Verschlüsselt im Ruhezustand — das HMAC-Secret wird mit AES-256-GCM unter Verwendung von
VALIDATOR_ENCRYPTION_KEYverschlüsselt.
Referenzimplementierungen
import express from 'express';import crypto from 'node:crypto'; const app = express();const SECRET = process.env.EXECLAVE_VALIDATOR_SECRET!; // 32-Byte-Hex // Rohen Body für die HMAC-Verifizierung erhaltenapp.use(express.json({ verify: (req, _res, buf) => ((req as any).rawBody = buf) })); app.post('/enforce', (req, res) => { const sig = (req.header('X-Execlave-Signature') ?? '').replace('sha256=', ''); const ts = req.header('X-Execlave-Timestamp') ?? ''; const raw = (req as any).rawBody as Buffer; // 1. Anfragen älter als 15 s ablehnen (Replay-Schutz) if (Math.abs(Date.now() - Date.parse(ts)) > 15_000) { return res.status(400).json({ error: 'stale timestamp' }); } // 2. HMAC-Verifizierung in konstanter Zeit const expected = crypto.createHmac('sha256', SECRET).update(raw).digest('hex'); const ok = sig.length === expected.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected)); if (!ok) return res.status(401).json({ error: 'invalid signature' }); // 3. Ihre Geschäftslogik const body = req.body as { input: string; estimatedCost: number }; if (body.estimatedCost > 1.0) { return res.json({ decision: 'deny', reason: 'estimated cost exceeds $1.00' }); } return res.json({ decision: 'allow' });}); app.listen(8080);import hmac, hashlib, os, timefrom datetime import datetime, timezonefrom fastapi import FastAPI, Request, HTTPException SECRET = os.environ["EXECLAVE_VALIDATOR_SECRET"].encode() app = FastAPI() @app.post("/enforce")async def enforce(request: Request): raw = await request.body() sig = (request.headers.get("x-execlave-signature", "") .removeprefix("sha256=")) ts = request.headers.get("x-execlave-timestamp", "") # 1. Veraltete Anfragen ablehnen (>15 s Abweichung) try: delta = abs(time.time() - datetime.fromisoformat( ts.replace("Z", "+00:00")).timestamp()) except ValueError: raise HTTPException(400, "invalid timestamp") if delta > 15: raise HTTPException(400, "stale timestamp") # 2. HMAC-Verifizierung in konstanter Zeit expected = hmac.new(SECRET, raw, hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): raise HTTPException(401, "invalid signature") # 3. Ihre Geschäftslogik body = await request.json() if body.get("estimatedCost", 0) > 1.0: return {"decision": "deny", "reason": "cost exceeds $1.00 cap"} return {"decision": "allow"}CLI
# Validatoren auflistenexeclave validators list # Validator erstellen (Secret wird einmalig angezeigt)execlave validators create \ --name finance-spend-cap \ --url https://validators.internal.acme.com/enforce \ --fail-mode fail_closed \ --timeout-ms 2000 # Validator testenexeclave validators test <id> # HMAC-Secret rotierenexeclave validators rotate-secret <id>Fail-Modi
Jeder Validator deklariert, was Execlave tun soll, wenn der Aufruf fehlschlägt (Timeout, Netzwerkfehler, ungültige Antwort, Circuit offen):
- fail_closed (Standard, empfohlen für sicherheitskritische Richtlinien) — Fehler als Deny behandeln. Der LLM-Aufruf wird blockiert.
- fail_open — Fehler als Allow behandeln. Nur für unkritische, verfügbarkeitssensible Richtlinien verwenden.
Wählen Sie den Modus pro Validator im Dashboard oder über die API. Fehler werden über Audit-Logs und das Webhook-Ereignis custom_validator.failed sichtbar gemacht.
SDK-Fehlerbehandlung
Sowohl sdk-js als auch execlave-sdk (Python) lösen ValidatorDeniedError aus — eine Unterklasse von PolicyBlockedError — wenn die Ablehnung von einem benutzerdefinierten Validator stammt. Fangen Sie die allgemeine Klasse für eine einheitliche UX ab oder die spezifische Klasse für validatorbewusste Meldungen.
import { ValidatorDeniedError, PolicyBlockedError } from '@execlave/sdk'; try { await exe.enforcePolicy({ agentId: agent.id, input, tools: ['web_search'], }); // Sicher, mit dem LLM-Aufruf fortzufahren const answer = await llm.call(input);} catch (err) { if (err instanceof ValidatorDeniedError) { return `Blocked by ${err.validatorViolations[0].policyName}: ${err.validatorViolations[0].message}`; } if (err instanceof PolicyBlockedError) { return `Blocked by policy: ${err.violations[0].message}`; } throw err;}