§ DOCUMENTATION
Policy-as-Code
Halten Sie Richtlinien als JSON oder YAML in einem Git-Repository. Execlave synchronisiert sie aus GitHub oder GitLab und hält synchronisierte Richtlinien schreibgeschützt, oder Sie übertragen sie aus CI mit execlave policies sync. Jede Änderung landet in einem manipulationssicheren Verlauf.
Warum Policy-as-Code
Wenn Richtlinien nur im Dashboard leben, umgehen Änderungen das Review, das für Anwendungscode gilt. Eine einzige geänderte Regel (etwa ein enforcementMode von block auf monitor) kann erweitern, was ein Agent tun darf, ohne Diff und ohne Reviewer.
Mit Richtlinien in einem Repository bekommt jede Änderung einen Pull Request, einen Reviewer und einen Commit, und der Commit, aus dem eine Richtlinie stammt, wird an der Richtlinie und in ihrem Audit-Verlauf festgehalten.
Richtliniendateien
Eine Richtliniendatei ist eine .json-, .yaml- oder .yml-Datei mit einer Liste von Richtlinien, einem Objekt mit einer policies-Liste oder einer einzelnen Richtlinie. Jede Richtlinie hat die Form des Request-Bodys von POST /api/v1/policies. Git-Sync und die CLI lesen dieselben Formen.
# policies/guardrails.yaml: eine Liste, { policies: [...] } oder eine einzelne Richtliniepolicies: - name: PII access logging policyType: pii_access enforcementMode: block ruleDefinition: denied_pii_types: [ssn, credit_card, iban] metadata: owner: security ticket: SEC-142 - name: Per-execution cost limit policyType: cost_limit enforcementMode: block ruleDefinition: max_cost_per_execution: 1| Feld | Pflicht | Hinweise |
|---|---|---|
| name | ja | Erkennt die Richtlinie bei jeder Synchronisierung; eindeutig im Bundle |
| policyType | ja | pii_access, data_restriction, cost_limit, injection_scan, … |
| enforcementMode | ja | block, warn, monitor oder require_approval |
| ruleDefinition | ja | Objekt; die Felder hängen vom policyType ab |
| metadata | nein | Schlüssel/Wert-Paare wie owner oder ticket, unverändert gespeichert |
Zwei Wege, sie anzuwenden
| Git-Sync (Bundle) | CLI: execlave policies sync | |
|---|---|---|
| Wer liest die Dateien | Execlave, aus GitHub oder GitLab | Die CLI, aus einer lokalen Datei |
| Wann | „Jetzt synchronisieren“ oder automatisch im Intervall | Wenn Sie sie ausführen (z. B. in CI) |
| Dateien | Jede Richtliniendatei unter einem Verzeichnis | Eine Datei pro Lauf |
| Entfernte Richtlinien | Deaktiviert | Nur mit --prune gelöscht |
| Änderungen anderswo | Abgewiesen: Das Repository ist maßgeblich | Erlaubt |
| Prüfung | Vollständige Serverprüfung, bevor etwas geschrieben wird | Je Richtlinie, wie die API antwortet |
Git-Sync: ein Repository verbinden
Öffnen Sie im Dashboard Richtlinien → Richtlinien-Bundles und legen Sie ein Bundle an, oder rufen Sie als Admin die API auf. Ein Bundle zeigt auf ein Repository, einen Branch und ein Verzeichnis:
| Einstellung | Hinweise |
|---|---|
| Repository-URL | https://github.com/owner/repo oder https://gitlab.com/group/project |
| Branch | Standard main |
| Pfad | Zu lesendes Verzeichnis samt Unterverzeichnissen; Standard / (das ganze Repository) |
| Anbieter | Nur für GitHub Enterprise oder selbst gehostetes GitLab; für github.com und gitlab.com erkannt |
| Zugriffstoken | Nur für ein privates Repository; siehe unten |
| Auto-Sync | Standardmäßig aus; Intervall 1 bis 10.080 Minuten, Standard 60 |
curl -X POST https://api.execlave.com/api/v1/policies/bundles \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Production guardrails", "sourceUrl": "https://github.com/acme/agent-policies", "sourceBranch": "main", "sourcePath": "policies", "sourceToken": "<Lese-Token, nur für ein privates Repository>", "autoSync": true, "syncIntervalMinutes": 30 }' # Jetzt synchronisierencurl -X POST https://api.execlave.com/api/v1/policies/bundles/<bundle-id>/sync \ -H "Authorization: Bearer $TOKEN"Zugriffstoken. Verwenden Sie ein Token nur mit Leserechten: auf GitHub ein Fine-grained Token mit Lesezugriff auf Contents des Repositorys, auf GitLab ein Project Access Token mit read_api. Das Token wird verschlüsselt gespeichert und nie zurückgegeben; API und Dashboard zeigen nur, ob eines gespeichert ist. Es ist an sein Repository gebunden: Um ein Bundle auf ein anderes Repository zu richten, senden Sie im selben Request ein neues Token oder entfernen das gespeicherte. Ersetzen oder entfernen Sie es jederzeit über die Bundle-Karte oder mit PATCH /api/v1/policies/bundles/:id ("sourceToken": null entfernt es).
Selbst gehostet. Zum Speichern eines Tokens muss im Backend SIEM_ENCRYPTION_KEY gesetzt sein. Repository-Hosts in privaten Netzen werden abgewiesen, außer bei POLICY_SYNC_ALLOW_PRIVATE_NETWORKS=true. Der Worker sucht alle POLICY_BUNDLE_SYNC_SWEEP_MINUTES (Standard 5) nach Bundles, die zur automatischen Synchronisierung fällig sind.
Git-Sync: was eine Synchronisierung tut
Eine Synchronisierung löst den Branch zu einem Commit auf und liest jede Richtliniendatei unter dem Pfad in diesem Commit, sodass ein Push während der Synchronisierung keine zwei Stände vermischen kann. Danach prüft sie jede Richtlinie mit denselben Prüfungen wie die API. Ist etwas falsch, wird nichts geändert: Das Bundle zeigt die Synchronisierung als fehlgeschlagen, mit jedem Problem nach Datei, Richtlinie und Feld.
Andernfalls, in einer Transaktion, mit Abgleich der Richtlinien nach Namen innerhalb des Bundles:
| Im Repository | Ergebnis |
|---|---|
| Eine neue Richtlinie | Erstellt, verknüpft mit Bundle und Commit |
| Eine Richtlinie mit geänderten Feldern | Aktualisiert; ein aus der Datei entferntes Feld wird auf seinen Standard zurückgesetzt oder geleert |
| Eine unveränderte Richtlinie | Bleibt unberührt: Version und Verlauf ändern sich nicht |
| Eine entfernte Richtlinie | Deaktiviert, nie gelöscht; kommt sie zurück, wird sie wieder aktiviert |
| Eine umbenannte Richtlinie | Der alte Name wird deaktiviert, der neue erstellt |
Jede Änderung wird mit "source": "git_sync", dem Bundle, dem Commit und der Datei ins Audit-Log geschrieben. Auto-Sync wird mit dem Akteur system erfasst. Eine fehlgeschlagene automatische Synchronisierung wird im nächsten Intervall erneut versucht.
Grenzen: 200 Richtliniendateien, 256 KiB pro Datei, 2 MiB insgesamt und 500 Richtlinien pro Bundle. prerequisites werden in synchronisierten Richtlinien nicht unterstützt, weil sie auf Richtlinien-IDs verweisen, die ein Repository nicht kennen kann.
Synchronisierte Richtlinien sind schreibgeschützt
Eine aus einem Bundle synchronisierte Richtlinie ändert sich nur über ihr Repository. Das Dashboard markiert sie mit Aus Git synchronisiert, nennt Bundle und Commit und schaltet Bearbeiten, Aktivieren und Löschen ab. REST- und GraphQL-API weisen eine Änderung oder Löschung mit 409 POLICY_MANAGED_BY_BUNDLE ab.
REST-Antworten zu Richtlinien enthalten bundleId und bundleCommit; GraphQL hat Policy.bundle (ID, Name, Repository-URL, Commit). Wird ein Bundle gelöscht, bleiben seine Richtlinien erhalten und sind wieder bearbeitbar.
CLI: execlave policies lint
execlave policies lint <Datei> prüft eine Datei, bevor Sie sie committen: Pflichtfelder, bekannte Richtlinientypen, Durchsetzungs- und Fehlermodi, Umgebungen, Feldtypen und doppelte Namen. Es akzeptiert jeden Richtlinientyp, den der Server durchsetzt, und lehnt ab, was auch der Server ablehnt: custom sowie eine semantic_rule, die nicht warn oder monitor verwendet (eine modellgestützte Regel kann nicht blockieren). Bei jedem Problem endet es mit Exit-Code 1 und kann so einen Pull Request absichern. Es prüft Regeldefinitionen nicht gegen ihren Richtlinientyp; das tun die API und Git-Sync.execlave policies lint policies/guardrails.yaml ✓ Policy lint passed (2 policies). # Ein Problem endet mit Exit-Code 1, damit CI fehlschlägt✖ Policy lint failed with 1 error ✖ policy 2 (Per-execution cost limit) enforcementMode: must be one of block, warn, monitor, require_approvalCLI: execlave policies sync
execlave policies sync <Datei> vergleicht die Datei mit allen Richtlinien Ihrer Organisation, nach id, wenn eine Richtlinie eine hat, sonst nach Namen, und gibt den Plan aus. Nichts ändert sich, bis Sie --yes angeben. --prune löscht zusätzlich Richtlinien, die nicht in der Datei stehen, außer Richtlinien, die ein Git-Bundle verwaltet: Nur ihr Repository kann sie entfernen, deshalb führt der Plan sie als nicht gelöscht auf. Geschriebene Richtlinien erhalten "source": "cli-sync" in ihren Metadaten.
Die CLI kann keine Richtlinie ändern, die ein Git-Bundle verwaltet: Die API weist das ab, und die CLI meldet den Fehler und endet mit Exit-Code 1. Haben eine manuelle und eine Bundle-Richtlinie denselben Namen, trifft ein Dateieintrag ohne id die manuelle. Felder, die nur der Server setzt (version, bundleId, bundleCommit), werden nicht zurückgesendet; eine aus der API exportierte Datei lässt sich deshalb unverändert synchronisieren.
YAML-Dateien werden wie beim Git-Sync gelesen: eine Liste von Richtlinien, { policies: [...] } oder eine einzelne Richtlinie, mit verschachtelten Listen und Objekten in einer Regel und höchstens 50 Aliasen. Das beschreibt @execlave/cli 1.3.0; frühere Versionen lesen nur eine YAML-Verschachtelungsebene und nur die ersten 50 Richtlinien. Aktualisieren Sie mit npm install -g @execlave/cli@latest.
# Probelauf (Standard): zeigt den Plan und ändert nichtsexeclave policies sync policies/guardrails.json Policy sync plan Create: 1, Update: 1, Prune: 0, Unchanged: 0---------------------------------------------------------------------- + create PII access logging ~ update Per-execution cost limit (3f2c9a1e-…) Dry run only. Re-run with --yes to apply changes.execlave policies sync policies/guardrails.json --yes ✔ created PII access logging ✔ updated Per-execution cost limit Results: 1 created, 1 updated, 0 pruned, 0 skipped, 0 failedRichtlinienverlauf
Jede Richtlinienänderung wird im manipulationssicheren Audit-Log festgehalten. GET /api/v1/policies/:id/history liefert sie, die neueste zuerst, mit Akteur, Zustand vorher und nachher und den Metadaten, die zeigen, ob eine Änderung aus Git-Sync, der CLI oder dem Dashboard stammt.
curl https://api.execlave.com/api/v1/policies/<policy-id>/history \ -H "Authorization: Bearer $TOKEN" { "data": [ { "action": "policy.updated", "actor": { "userId": null, "email": null }, "changes": { "before": { "enforcement_mode": "warn", "…": "…" }, "after": { "enforcement_mode": "block", "…": "…" } }, "metadata": { "source": "git_sync", "bundleId": "…", "commit": "9f1c2ab…", "file": "policies/guardrails.yaml", "actor": "system" }, "timestamp": "2026-10-23T09:30:00.000Z" } ], "meta": { "total": 1 }}