Skip to main content

Overview

The approvals API manages human-in-the-loop workflows for sensitive operations. When a policy decision is ask or require_approval, the tool call is queued pending human review.
Approvals expire after 1 hour by default (configurable with --approval-timeout).

Endpoints

List Approvals

GET /v1/approvals
Lists pending approvals plus grouped view by run_id.

Request Headers

Authorization
string
required
Bearer token for authentication

Response Fields

approvals
array
required
Array of pending approval objects
run_groups
array
required
Array of run groups (runs with 2+ pending approvals)

Example

TOKEN="$(cat ~/.rampart/token)"
curl -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:9090/v1/approvals"
Response (200 OK):
{
  "approvals": [
    {
      "id": "01J9K8L7M6N5",
      "tool": "exec",
      "command": "kubectl apply -f prod.yaml",
      "agent": "claude-code",
      "session": "myapp/main",
      "message": "production deployment requires approval",
      "status": "pending",
      "run_id": "run_01J...",
      "created_at": "2026-03-03T10:15:30Z",
      "expires_at": "2026-03-03T11:15:30Z"
    }
  ],
  "run_groups": [
    {
      "run_id": "run_01J...",
      "count": 3,
      "earliest_created_at": "2026-03-03T10:15:30Z",
      "items": [ /* approval objects */ ]
    }
  ]
}

Get Single Approval

GET /v1/approvals/{id}
Returns one approval by ID.

Path Parameters

id
string
required
Approval ID

Request Headers

Authorization
string
required
Bearer token for authentication

Response Fields

id
string
required
Approval ID
tool
string
required
Tool name
command
string
required
Command or path
agent
string
required
Agent identifier
session
string
required
Session identifier
message
string
required
Decision message
status
string
required
Status: pending, approved, or denied
created_at
string
required
ISO 8601 timestamp
expires_at
string
required
ISO 8601 timestamp
resolved_at
string
ISO 8601 timestamp (only if resolved)
resolved_by
string
Resolver identifier (only if resolved)

Example

curl -H "Authorization: Bearer $TOKEN" \
  "http://127.0.0.1:9090/v1/approvals/01J9K8L7M6N5"
Response (200 OK):
{
  "id": "01J9K8L7M6N5",
  "tool": "exec",
  "command": "kubectl delete pod critical",
  "agent": "claude-code",
  "session": "myapp/production",
  "message": "production change requires approval",
  "status": "approved",
  "created_at": "2026-03-03T10:15:30Z",
  "expires_at": "2026-03-03T11:15:30Z",
  "resolved_at": "2026-03-03T10:20:15Z",
  "resolved_by": "security-team"
}

Status Codes

StatusMeaning
200 OKApproval found
401 UnauthorizedMissing or invalid token
404 Not FoundApproval not found

Create Approval

POST /v1/approvals
Creates an external/manual approval request.
This endpoint is typically used by integrations that need to create approvals outside of the normal tool evaluation flow.

Request Headers

Authorization
string
required
Bearer token for authentication
Content-Type
string
required
Must be application/json

Request Body

tool
string
required
Tool name (e.g., exec, read, write)
agent
string
required
Agent identifier
message
string
required
Human-readable reason for approval request
command
string
Command to execute (for exec tool)
path
string
File path (for read/write tools)
run_id
string
Run identifier for grouping

Response Fields

id
string
required
Created approval ID
status
string
required
Status: pending or approved (auto-approved if run is bulk-approved)
expires_at
string
required
ISO 8601 timestamp when approval expires
message
string
Additional message (only for auto-approved cases)

Example

curl -X POST "http://127.0.0.1:9090/v1/approvals" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "exec",
    "command": "kubectl delete pod foo",
    "agent": "claude-code",
    "message": "requires approval"
  }'
Response (201 Created):
{
  "id": "01J9K8L7M6N5",
  "status": "pending",
  "expires_at": "2026-03-03T11:15:30Z"
}
Response (200 OK) — Auto-approved:
{
  "id": "01J9K8L7M6N5",
  "status": "approved",
  "message": "auto-approved by bulk-resolve",
  "expires_at": "2026-03-03T11:15:30Z"
}

Status Codes

StatusMeaning
201 CreatedApproval created
200 OKAuto-approved by run cache
400 Bad RequestInvalid JSON
401 UnauthorizedMissing or invalid token
503 Service UnavailableApproval queue full

Resolve Approval

POST /v1/approvals/{id}/resolve
Approves or denies a pending approval.

Path Parameters

id
string
required
Approval ID to resolve

Request Headers

Authorization
string
Bearer token (not required if valid signed sig + exp query params are provided)
Content-Type
string
required
Must be application/json

Request Body

approved
boolean
required
true to approve, false to deny
resolved_by
string
Identifier of the resolver (e.g., security-team, api, cli). Defaults to api.
persist
boolean
If true and approved is true, adds an auto-allow rule to ~/.rampart/policies/auto-allowed.yaml

Response Fields

id
string
required
Approval ID
status
string
required
New status: approved or denied
approved
boolean
required
Whether the approval was granted
persisted
boolean
required
Whether an auto-allow rule was created

Example — Approve

curl -X POST "http://127.0.0.1:9090/v1/approvals/01J9K8L7M6N5/resolve" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "approved": true,
    "resolved_by": "security-team",
    "persist": false
  }'
Response (200 OK):
{
  "id": "01J9K8L7M6N5",
  "status": "approved",
  "approved": true,
  "persisted": false
}

Example — Deny

curl -X POST "http://127.0.0.1:9090/v1/approvals/01J9K8L7M6N5/resolve" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "approved": false,
    "resolved_by": "cli"
  }'
Response (200 OK):
{
  "id": "01J9K8L7M6N5",
  "status": "denied",
  "approved": false,
  "persisted": false
}

Example — Approve and Persist

curl -X POST "http://127.0.0.1:9090/v1/approvals/01J9K8L7M6N5/resolve" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "approved": true,
    "resolved_by": "user",
    "persist": true
  }'
Response (200 OK):
{
  "id": "01J9K8L7M6N5",
  "status": "approved",
  "approved": true,
  "persisted": true
}
When persist: true, Rampart adds an auto-allow rule to ~/.rampart/policies/auto-allowed.yaml so future identical tool calls are automatically approved.

Status Codes

StatusMeaning
200 OKApproval resolved
400 Bad RequestInvalid JSON
401 UnauthorizedInvalid token/signature
404 Not FoundUnknown approval ID
410 GoneApproval already resolved (replay attempt)

Bulk Resolve

POST /v1/approvals/bulk-resolve
Bulk approves or denies all pending approvals for one run_id.
This endpoint requires a non-empty run_id to prevent accidental mass-approval of unrelated operations.

Request Headers

Authorization
string
required
Bearer token for authentication
Content-Type
string
required
Must be application/json

Request Body

run_id
string
required
Run identifier — all pending approvals with this run_id will be resolved
action
string
required
Must be approve or deny
resolved_by
string
Resolver identifier. Defaults to api.

Response Fields

resolved
integer
required
Number of approvals resolved
ids
array
required
Array of resolved approval IDs

Example

curl -X POST "http://127.0.0.1:9090/v1/approvals/bulk-resolve" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "run_id": "run_01J...",
    "action": "approve",
    "resolved_by": "api"
  }'
Response (200 OK):
{
  "resolved": 3,
  "ids": ["01J9K8L7M6N5", "01J9K8L7M6N6", "01J9K8L7M6N7"]
}

Status Codes

StatusMeaning
200 OKBulk resolve completed
400 Bad RequestMissing/empty run_id or invalid action
401 UnauthorizedMissing or invalid token
When you bulk-approve a run, the run_id is cached. Subsequent tool calls with the same run_id are automatically approved without creating new approvals.

Signed URL Authorization

When server-side signing is enabled (rampart serve --sign), approval resolution can be authorized via HMAC-signed URLs instead of bearer tokens.

Example Signed URL

http://127.0.0.1:9090/v1/approvals/01J.../resolve?sig=abc123&exp=1709481600
  • sig — HMAC signature
  • exp — Unix timestamp when the signature expires

Usage

# No Authorization header needed
curl -X POST "http://127.0.0.1:9090/v1/approvals/01J.../resolve?sig=abc&exp=1234" \
  -H "Content-Type: application/json" \
  -d '{"approved":true,"resolved_by":"webhook"}'
Signed URLs are single-use and time-limited. They’re included in webhook notifications when signing is enabled.

Common Use Cases

Approval Dashboard

import requests
import os

token = open(os.path.expanduser("~/.rampart/token")).read().strip()
headers = {"Authorization": f"Bearer {token}"}

# List pending approvals
response = requests.get(
    "http://localhost:9090/v1/approvals",
    headers=headers
)
approvals = response.json()["approvals"]

# Display to user
for approval in approvals:
    print(f"{approval['id']}: {approval['command']}")
    print(f"  Agent: {approval['agent']}")
    print(f"  Expires: {approval['expires_at']}")

# Approve one
requests.post(
    f"http://localhost:9090/v1/approvals/{approvals[0]['id']}/resolve",
    headers={**headers, "Content-Type": "application/json"},
    json={"approved": True, "resolved_by": "dashboard"}
)

Bulk Approve CI Runs

#!/bin/bash
# Approve all pending operations for a CI run

RUN_ID="$1"
TOKEN="$(cat ~/.rampart/token)"

curl -X POST "http://127.0.0.1:9090/v1/approvals/bulk-resolve" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"run_id":"'"$RUN_ID"'","action":"approve","resolved_by":"ci-approver"}'

Next Steps

Events

Real-time event streaming

Status

Server status and health

Build docs developers (and LLMs) love