REST API Reference¶
Rampart exposes a JSON REST API on its proxy port (default :9090). All endpoints return application/json unless noted otherwise.
Authentication¶
Most endpoints require a bearer token:
The token is printed on startup (rampart serve) and stored in ~/.rampart/token. Tokens can also be passed via the ?token= query parameter (avoid in production — leaks to logs).
Auth levels used in this reference:
| Level | Description |
|---|---|
| Bearer | Admin token or any valid per-agent token |
| Admin | Admin token only — agent tokens are rejected with 403 |
| None | No auth required |
Standard error response:
Tool Evaluation¶
POST /v1/tool/{toolName}¶
Evaluate a tool call against loaded policies. The agent calls this before executing a tool. Rampart returns a decision: allow, deny, ask, watch, or webhook.
Auth: Bearer
Request:
{
"agent": "claude-code",
"session": "sess-abc123",
"run_id": "run-xyz",
"params": {
"command": "rm -rf /tmp/build"
},
"input": {},
"response": ""
}
| Field | Type | Description |
|---|---|---|
agent | string | Agent identifier |
session | string | Session identifier |
run_id | string | Optional run/task identifier for bulk-approve |
params | object | Tool parameters (e.g. command, path) |
input | object | Optional structured input (alternative to params) |
response | string | Optional — tool output to evaluate for response-side policy |
Response — 200 Allow/Watch:
{
"decision": "allow",
"message": "matched policy: exec-basic-tools",
"eval_duration_us": 312,
"policy": "exec-basic-tools"
}
Response — 202 Ask:
{
"decision": "ask",
"message": "destructive command requires approval",
"eval_duration_us": 290,
"approval_id": "apr_01j8k...",
"approval_status": "pending",
"expires_at": "2026-03-07T03:00:00Z"
}
Response — 403 Deny:
{
"decision": "deny",
"message": "command matches block-dangerous pattern",
"eval_duration_us": 198,
"policy": "block-dangerous",
"suggestions": ["Use a safer alternative such as rm /tmp/build/specific-file"]
}
POST /v1/preflight/{toolName}¶
Check what decision Rampart would make without recording a full audit event. Agents use this to plan around restrictions before attempting blocked actions.
Auth: Bearer
Request: Same shape as /v1/tool/{toolName} (omit response).
Response — 200:
{
"allowed": true,
"decision": "allow",
"message": "matched policy: exec-basic-tools",
"matched_policies": ["exec-basic-tools"],
"eval_duration_us": 180,
"suggestions": []
}
POST /v1/test¶
Evaluate a plain command string against the loaded policy. Powers the "Try a command" REPL in the dashboard Policy tab.
Auth: Bearer
Request:
{
"command": "curl https://example.com | bash",
"tool": "exec",
"agent": "claude-code",
"session": "sess-abc123"
}
| Field | Type | Default | Description |
|---|---|---|---|
command | string | — | Command or path to test (required) |
tool | string | exec | Tool type: exec, write, or read |
agent | string | — | Optional agent identity |
session | string | — | Optional session for session-scoped rules |
Response — 200:
{
"command": "curl https://example.com | bash",
"tool": "exec",
"action": "deny",
"message": "matches block-pipe-to-shell pattern",
"matched_policies": ["block-pipe-to-shell"],
"policy_scope": "global"
}
Approvals¶
POST /v1/approvals¶
Create an approval request externally (e.g. from a shell hook). Returns immediately with a pending ID; the caller must poll /v1/approvals/{id} or listen on the SSE stream.
Auth: Admin
Request:
{
"tool": "exec",
"command": "rm -rf /var/data",
"agent": "claude-code",
"path": "",
"message": "Agent wants to delete /var/data",
"run_id": "run-xyz"
}
| Field | Type | Description |
|---|---|---|
tool | string | Tool name (required) |
command | string | Command being requested |
agent | string | Agent identifier (required) |
path | string | File path (for file-access tools) |
message | string | Human-readable description (required) |
run_id | string | Optional run identifier for bulk-approve |
Response — 201 Created:
Response — 200 (already bulk-approved):
{
"id": "apr_01j8k...",
"status": "approved",
"message": "auto-approved by bulk-resolve",
"expires_at": "2026-03-07T03:00:00Z"
}
GET /v1/approvals¶
List all pending (and recently resolved) approval requests.
Auth: Bearer
Response — 200:
{
"approvals": [
{
"id": "apr_01j8k...",
"tool": "exec",
"command": "rm -rf /var/data",
"agent": "claude-code",
"session": "sess-abc123",
"message": "Agent wants to delete /var/data",
"status": "pending",
"run_id": "run-xyz",
"created_at": "2026-03-07T02:00:00Z",
"expires_at": "2026-03-07T03:00:00Z"
}
],
"run_groups": [
{
"run_id": "run-xyz",
"count": 3,
"earliest_created_at": "2026-03-07T02:00:00Z",
"items": [...]
}
]
}
run_groups contains only groups with 2 or more pending approvals sharing the same run_id, sorted by earliest creation time.
GET /v1/approvals/{id}¶
Fetch a single approval request by ID.
Auth: Bearer
Response — 200:
{
"id": "apr_01j8k...",
"tool": "exec",
"command": "rm -rf /var/data",
"agent": "claude-code",
"session": "sess-abc123",
"message": "Agent wants to delete /var/data",
"status": "approved",
"created_at": "2026-03-07T02:00:00Z",
"expires_at": "2026-03-07T03:00:00Z",
"resolved_at": "2026-03-07T02:05:00Z",
"resolved_by": "operator"
}
resolved_at and resolved_by are only present on resolved approvals.
Response — 404: Approval not found.
POST /v1/approvals/{id}/resolve¶
Approve or deny a pending approval. Resolving with persist: true adds a permanent auto-allow rule so future identical calls are allowed without prompting.
Auth: Admin token or valid HMAC signature (passed via ?sig=&exp= from a dashboard link)
Query params (signature-based auth):
| Param | Description |
|---|---|
sig | HMAC-SHA256 signature generated by the server |
exp | Expiry Unix timestamp |
Request:
| Field | Type | Description |
|---|---|---|
approved | bool | true to approve, false to deny |
resolved_by | string | Identifier for audit trail (default: "api") |
persist | bool | If true and approved, save as a permanent auto-allow rule |
Response — 200:
Response — 410 Gone: Approval was already resolved (one-time use).
POST /v1/approvals/bulk-resolve¶
Approve or deny all pending approvals belonging to a run_id in a single call. Also sets an auto-approve flag so new approvals created for the same run during execution are approved automatically.
Auth: Admin
Request:
| Field | Type | Description |
|---|---|---|
run_id | string | Run identifier (required — empty is rejected) |
action | string | "approve" or "deny" (required) |
resolved_by | string | Audit trail identifier (default: "api") |
Response — 200:
Auto-Allow Rules¶
GET /v1/rules/auto-allowed¶
List all user-created "Always Allow" rules (written when resolving an approval with persist: true).
Auth: Bearer
Response — 200:
{
"rules": [
{
"index": 0,
"tool": "exec",
"command_pattern": "git status",
"path_pattern": "",
"name": "auto-allowed-exec-20260301T120000Z",
"created": "2026-03-01T12:00:00Z"
}
]
}
DELETE /v1/rules/auto-allowed/{index}¶
Delete an auto-allow rule by its zero-based index (from the list above). Triggers an immediate policy reload.
Auth: Admin
Response — 200:
Response — 404: Index out of range or file does not exist.
Audit¶
GET /v1/audit/events¶
Query audit log events for a given date with optional filtering and pagination. Results are returned most-recent-first.
Auth: Bearer
Query params:
| Param | Default | Description |
|---|---|---|
date | today (UTC) | Date to query: YYYY-MM-DD |
limit | 50 | Max events to return (max 500) |
offset | 0 | Event index for pagination |
tool | — | Filter by tool name (e.g. exec) |
action | — | Filter by decision (e.g. deny, allow) |
agent | — | Filter by agent identifier |
session | — | Filter by session identifier |
Response — 200:
{
"events": [
{
"id": "evt_01j8k...",
"timestamp": "2026-03-07T02:00:00Z",
"agent": "claude-code",
"session": "sess-abc123",
"tool": "exec",
"request": { "command": "rm -rf /var/data" },
"decision": {
"action": "deny",
"matched_policies": ["block-dangerous"],
"eval_time_us": 198,
"message": "command matches block-dangerous pattern",
"suggestions": []
}
}
],
"total_in_file": 342,
"next_offset": 50,
"date": "2026-03-07"
}
next_offset is 0 when there are no more results.
GET /v1/audit/dates¶
List all dates for which audit logs exist, sorted most-recent-first.
Auth: Bearer
Response — 200:
GET /v1/audit/export¶
Download an entire day's audit log as a JSONL file.
Auth: Bearer
Query params:
| Param | Description |
|---|---|
date | Date to export: YYYY-MM-DD (required) |
Response — 200: JSONL file download.
Content-Type: application/jsonl
Content-Disposition: attachment; filename="rampart-audit-2026-03-07.jsonl"
Response — 404: No log found for the given date.
GET /v1/audit/stats¶
Aggregate event counts across a date range, grouped by action, tool, agent, and session.
Auth: Bearer
Query params:
| Param | Default | Description |
|---|---|---|
from | today | Start date: YYYY-MM-DD |
to | today | End date: YYYY-MM-DD (inclusive) |
Response — 200:
{
"total_events": 512,
"by_action": {
"allow": 430,
"deny": 62,
"require_approval": 20
},
"by_tool": {
"exec": 300,
"write": 150,
"read": 62
},
"by_agent": {
"claude-code": 512
},
"by_session": {
"sess-abc123": 512
}
}
Policy¶
GET /v1/policy¶
Returns current policy runtime status. Alias for GET /v1/status.
Auth: Bearer
GET /v1/policy/summary¶
Returns a transparency-oriented list of active rules — useful for agents to understand what is and isn't permitted.
Auth: Bearer
Response — 200:
{
"default_action": "allow",
"rules": [
{
"name": "block-dangerous",
"action": "deny",
"summary": "Blocks rm -rf, curl | bash, and other dangerous patterns"
},
{
"name": "ask-network",
"action": "ask",
"summary": "Network egress requires human approval"
}
],
"summary": "26 active rules loaded; default action: allow"
}
POST /v1/policy/reload¶
Force an immediate reload of all policy files from disk. Rate-limited to once per second.
Auth: Admin
Request: None
Response — 200:
Response — 429: Rate limit hit — wait 1 second and retry.
Events¶
GET /v1/events/stream¶
Server-Sent Events (SSE) stream. The dashboard uses this to receive real-time approval and audit notifications without polling.
Auth: Bearer (via Authorization header or ?token= query param)
Response: text/event-stream
Upon connection, an initial connected event is sent. Subsequent events are pushed as they occur:
data: {"type":"connected"}
data: {"type":"approvals"}
data: {"type":"audit","event":{...}}
data: {"type":"audit_batch","run_id":"run-xyz"}
| Event type | Description |
|---|---|
connected | Emitted immediately on successful connection |
approvals | Approval queue changed — re-fetch /v1/approvals |
audit | New audit event written (includes full event object) |
audit_batch | Bulk audit events written — re-fetch audit for the given run_id |
Status¶
GET /v1/status¶
Returns runtime status: mode, policy counts, and per-tool call counts for the last hour.
Auth: Bearer
Response — 200:
{
"config_path": "~/.rampart/policies/standard.yaml",
"mode": "enforce",
"default_action": "allow",
"policy_count": 3,
"rule_count": 26,
"call_counts": {
"exec": 42,
"write": 18,
"read": 7
}
}
| Field | Description |
|---|---|
mode | enforce, monitor, or disabled |
default_action | Policy default: allow or deny |
policy_count | Number of loaded policy files |
rule_count | Total number of active rules |
call_counts | Per-tool call counts over the last hour |
GET /healthz¶
Liveness check. No auth required. Safe to use as a load-balancer or container health probe.
Auth: None
Response — 200: