Governance HTTP API
Vigil exposes a localhost HTTP server (the daemon) that evaluates tool calls and streams governance state to Light Station. This reference documents request/response shapes and fail-closed semantics.
Canonical source: API_CONTRACT.md ↗ · Vigil INTEGRATION_PROTOCOL.md
Overview
OpenClaw plugin / demo agent
│ POST /evaluate
▼
Vigil daemon (127.0.0.1:18820)
│ allow | deny | escalate | reject
▼
Light Station (proxies observability endpoints) Two endpoint families: enforcement (/evaluate, /health) and observability (state, queue, audit, SSE) consumed by Light Station.
Auth and base URL
| Setting | Default | Env var |
|---|---|---|
| Vigil base URL | http://127.0.0.1:18820 | VIGIL_BASE_URL |
| Auth | None (localhost) | Optional Authorization: Bearer <VIGIL_API_KEY> |
| Binding | 127.0.0.1 only | No remote access in v0.6 |
Legacy CLAWLAW_* env aliases supported; VIGIL_* takes precedence.
POST /evaluate
Evaluate an OpenClaw tool call against governance policy. Called before each tool execution.
Request body
{
"tool": "write",
"parameters": { "path": "/workspace/test.txt", "content": "hello" },
"agent_id": "openclaw-main"
} | Field | Type | Required | Description |
|---|---|---|---|
tool | string | yes | OpenClaw tool name |
parameters | object | yes | Tool parameters (heterogeneous JSON) |
agent_id | string | no | Agent identifier (default: openclaw) |
Response 200
{
"decision": "allow",
"rationale": "Budget OK: 100/10000 tokens (1%)",
"approval_id": null,
"trace_summary": "Vigil: 6 laws evaluated — ..."
} | decision | Meaning |
|---|---|
allow | Tool call may proceed |
deny | Blocked by governance law (e.g. outside sandbox) |
escalate | Requires Principal approval (shell, deletion) |
reject | Governance allowed but budget insufficient |
Observability endpoints
Consumed by Light Station. All return JSON unless noted.
| Method | Path | Response | Purpose |
|---|---|---|---|
| GET | /health | status and version fields | Connectivity check |
| GET | /governance/state | GovernanceState | Enforcement level, budget, queue depth |
| GET | /governance/config | config object | Jurisdiction, law list, version |
| GET | /queue | PendingApproval[] | HOLD items awaiting Principal |
| POST | /queue/:id/approve | AuditEntry | Body: optional reason string |
| POST | /queue/:id/reject | AuditEntry | Body: required reason string |
| GET | /audit?limit&offset | AuditEntry[] | Hash-chained decision log |
| GET | /audit/:id | AuditEntry | null | Single entry |
| POST | /budget/increase | AuditEntry | Body: amount and reason |
| POST | /budget/reset | AuditEntry | Body: reason |
| GET | /agents | AgentStatus[] | Agent roster |
| GET | /agents/:id | AgentStatus | null | Single agent |
| POST | /sprint/authorize | AuditEntry | Body: ticketId, sprintId — audit only |
GET /governance/state example
{
"enforcementLevel": "Normal",
"budgetUsedPercent": 42,
"budgetTotal": 100000,
"budgetUsed": 42000,
"agentsRunning": 1,
"queueDepth": 0,
"eventsPerMinute": 8,
"connectedAt": "2026-07-01T12:00:00.000Z"
} Verdict mapping (Vigil → Light Station)
| Vigil decision | Light Station verdict |
|---|---|
allow | ALLOW |
deny, reject | DENY |
escalate | HOLD |
GET /events (SSE)
Accept: text/event-stream — real-time governance events for Lookout.
Each event is a single data: line containing GovernanceEvent JSON:
{
"id": "uuid",
"type": "file_write",
"verdict": "ALLOW",
"lawNumber": null,
"agentId": "openclaw-main",
"summary": "ALLOW file_write",
"detail": "Budget OK: ...",
"timestamp": "2026-07-01T12:00:00.000Z"
} Fail-closed semantics
OpenClaw plugin behavior (client-side): connection refused, timeout (5s), non-200, or any network error → block the tool call. Fail-closed is enforced in the client, not only the server.
Mock path: VIGIL_MOCK=true uses the mock client for offline dev and CI. Do not remove — P0 invariant.
Error responses (/evaluate)
| Status | Body | Cause |
|---|---|---|
| 400 | Invalid request body error JSON | Malformed JSON |
| 404 | Not found error JSON | Wrong path |
| 405 | Method not allowed error JSON | Wrong HTTP method |
| 500 | Internal server error JSON | Server failure |
| 502 | Vigil unreachable error JSON | Light Station proxy when upstream down |