Skip to content
Back to home

§ DOCUMENTATION

Policy-as-Code

Author policies as JSON or YAML in your repo, validate them before CI with execlave policies lint, reconcile them server-side with execlave policies sync, and audit every change through a tamper-evident version history.

§ 01

Why policy-as-code

When policies live only in the dashboard, changes bypass the same review process you apply to application code. A single misconfigured rule — for example, flipping enforcementMode from block to log_only — can silently widen your agent's blast radius with no diff, no reviewer, and no automated test to catch it.

Execlave's policy-as-code workflow treats policy bundles as first-class source artefacts: code review, CI validation, and reproducible deployments for every policy change. The same schema the API enforces is available locally, so errors are caught at lint time rather than at runtime.

§ 02

Authoring policy bundles

A policy bundle is a JSON or YAML file that declares one policy. The structure mirrors the POST /api/v1/policies request body: required fields are name, policyType, enforcementMode, and ruleDefinition. Optional metadata keys (owner, ticket, team) are stored verbatim and surfaced in the dashboard.

Store bundles anywhere in your repository — a conventional layout is a top-level policies/ directory. The CLI commands accept a directory path and process every .json and .yaml file within it recursively.

FieldRequiredNotes
nameyesHuman-readable label, must be unique within org
policyTypeyestool_call, prompt_injection, pii_detection, …
enforcementModeyesblock, log_only, require_approval
ruleDefinitionyesObject — schema varies by policyType
metadatanoArbitrary key/value pairs stored as JSONB
§ 03

execlave policies lint

execlave policies lint <path> validates every bundle file against the policy JSON Schema before you commit or open a pull request. It exits non-zero on any error, making it drop-in for CI.
What lint catchesExample
Missing required fieldsruleDefinition omitted entirely
Unknown policy typepolicyType: "custom_type" not in enum
Wrong field typeruleDefinition.tools: string instead of array
Invalid enforcementMode"allow" instead of "block" / "log_only" / "require_approval"
Extra top-level keysFields not in the schema trigger additionalProperties error
# Validate all policy bundles before committingexeclave policies lint ./policies/ # Output on success✓ production-guardrails.json — valid✓ data-access.yaml — valid2 bundles validated, 0 errors # Output on failure (exits non-zero — CI-friendly)✗ production-guardrails.json — invalid  ruleDefinition.tools: must be array1 error found
§ 04

execlave policies sync — dry-run & apply

execlave policies sync <path> diffs declared bundles against live policies in your org and prints the plan. No changes are applied until you pass --apply. Synced policies record source: "cli-sync" in their metadata field for provenance tracking.
# Dry-run (default) — prints plan, no changes appliedexeclave policies sync ./policies/ Plan:  + create  "Require approval for file writes"  (production-guardrails.json)  ~ update  "Block PII exfiltration"             (data-access.yaml)      enforcementMode: "log_only""block"  = no-op   "Rate limit external calls"          (already in sync) 2 changes pending. Re-run with --apply to apply.
Once you've reviewed the plan, apply it:
# Apply the planexeclave policies sync ./policies/ --apply Applied:  ✓ created  pol_01j...  "Require approval for file writes"  ✓ updated  pol_02j...  "Block PII exfiltration"
§ 05

Policy history & metadata

Every policy write event is recorded in the tamper-evident audit log. Retrieve the full change history for a policy via GET /api/v1/policies/:id/history. The response is ordered oldest-first and includes the actor, timestamp, and a field-level diff for each change.

Because the audit log uses ENABLE ALWAYS triggers that prevent UPDATE and DELETE, the history cannot be altered after the fact — every entry is immutable by construction.

curl https://api.execlave.com/api/v1/policies/pol_01j.../history \  -H "Authorization: Bearer $EXECLAVE_API_KEY" # Response{  "data": [    {      "eventType": "policy.updated",      "actorId": "user_123",      "changedAt": "2026-06-02T09:30:00Z",      "diff": { "enforcementMode": { "from": "log_only", "to": "block" } }    },    {      "eventType": "policy.created",      "actorId": "cli-sync",      "changedAt": "2026-05-15T14:00:00Z",      "diff": null    }  ]}
§ 06

Frequently asked questions

Does execlave policies lint validate against the same schema the API enforces?
Yes. The CLI validates bundle files against the same policy JSON Schema that the Execlave API enforces on every create and update request. A bundle that passes lint will not be rejected by the server on schema grounds — it is the same validation surface, run locally before you push.
What does dry-run actually show me?
Running execlave policies sync <path> without --apply prints a plan: which policies would be created, which would be updated (with a diff of changed fields), and which are already in sync. No changes are written to the server. This makes it safe to run in CI as a check step — fail the pipeline if the plan is non-empty, or let engineers review the diff in a pull request.
How does provenance metadata work?
Every policy carries a metadata JSONB field. When execlave policies sync applies changes, it stamps source: "cli-sync" into that metadata object. You can extend the metadata with owner, ticket, team, or any other key — the API stores it verbatim and surfaces it in policy list and detail responses. The dashboard shows metadata as a collapsible panel on the policy detail page.
Is policy version history an append-only audit log or a separate versions table?
Policy version history is derived from the tamper-evident audit log, not a separate versions table. GET /api/v1/policies/:id/history queries the audit log for all write events on that policy ID and returns them in chronological order. Because the audit log uses ENABLE ALWAYS triggers that prevent UPDATE and DELETE, the history is immutable by construction.