Approvals API¶
Manage just-in-time (JIT) access requests for restricted tools. When an agent attempts to call a tool with requireApproval: true and no existing access policy, the platform creates an access request that must be approved by an admin before the agent can proceed.
Create Access Request¶
POST /governance/requests
Create a new access request. This endpoint is idempotent -- if a pending request already exists for the same subject and tool, the existing request is returned.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
subject | string | Yes | User or service identity requesting access |
tool_id | string | Yes | Name of the tool being requested |
agent_id | string | No | Agent making the request |
duration | string | No | Requested access duration (e.g., "4h", "1d") |
run_id | string | No | Associated run ID (enables automatic run pausing) |
capability | string | No | Specific tool capability being requested |
payload_hash | string | No | SHA-256 hash of the action payload for integrity |
curl -X POST https://api.runagents.io/governance/requests \
-H "Authorization: Bearer $RUNAGENTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "payment-agent-sa",
"tool_id": "stripe-api",
"agent_id": "payment-agent",
"duration": "4h",
"run_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"capability": "create-charge",
"payload_hash": "sha256:abc123"
}'
import requests
resp = requests.post(
"https://api.runagents.io/governance/requests",
headers={"Authorization": f"Bearer {api_key}"},
json={
"subject": "payment-agent-sa",
"tool_id": "stripe-api",
"agent_id": "payment-agent",
"duration": "4h",
"run_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
},
)
print(resp.json())
Response (201 Created)¶
| Field | Type | Description |
|---|---|---|
id | string | Access request ID |
status | string | Initial status: PENDING |
action_id | string | Blocked action ID (present when run_id was provided) |
Run correlation
When run_id is provided, the platform automatically:
- Creates a blocked action for the tool call
- Pauses the run (status changes to
PAUSED_APPROVAL) - Appends an
APPROVAL_REQUIREDevent to the run's audit log
This enables the console to display the paused run with approval context.
Idempotency¶
If a PENDING request already exists for the same subject and tool_id, the existing request is returned with a 200 OK instead of creating a duplicate.
List Access Requests¶
GET /governance/requests
List access requests. By default, returns requests in PENDING status.
Query Parameters¶
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: PENDING, APPROVED, REJECTED, EXPIRED |
Response (200 OK)¶
[
{
"id": "req-a1b2c3d4-e5f6-7890",
"subject": "payment-agent-sa",
"agent_id": "payment-agent",
"tool_id": "stripe-api",
"status": "PENDING",
"duration": "4h",
"created_at": "2026-02-23T10:00:00Z",
"updated_at": "2026-02-23T10:00:00Z"
}
]
Get Access Request Details¶
GET /governance/requests/:id
Retrieve details for a specific access request.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
id | string | Access request ID |
Response (200 OK)¶
{
"id": "req-a1b2c3d4-e5f6-7890",
"subject": "payment-agent-sa",
"agent_id": "payment-agent",
"tool_id": "stripe-api",
"status": "PENDING",
"duration": "4h",
"created_at": "2026-02-23T10:00:00Z",
"updated_at": "2026-02-23T10:00:00Z"
}
Approve Access Request¶
POST /governance/requests/:id/approve
Approve a pending access request. This creates a time-limited access policy that allows the agent to call the tool.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
id | string | Access request ID |
Response (200 OK)¶
{
"id": "req-a1b2c3d4-e5f6-7890",
"subject": "payment-agent-sa",
"agent_id": "payment-agent",
"tool_id": "stripe-api",
"status": "APPROVED",
"duration": "4h",
"approver_id": "admin@example.com",
"expires_at": "2026-02-23T14:00:00Z",
"created_at": "2026-02-23T10:00:00Z",
"updated_at": "2026-02-23T10:05:00Z"
}
What happens on approval¶
- A time-limited access policy is created granting the agent access to the tool
- The policy expires after the requested duration (default: 4 hours)
- If the request was associated with a run, the corresponding blocked action is marked as
APPROVED - The platform's resume worker automatically detects approved actions and resumes paused runs
Errors¶
| Status | Error | Description |
|---|---|---|
404 | request not found | Access request does not exist |
409 | request is not pending | Request has already been approved, rejected, or expired |
Reject Access Request¶
POST /governance/requests/:id/reject
Reject a pending access request.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
id | string | Access request ID |
Request Body (optional)¶
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Reason for rejection |
Response (200 OK)¶
{
"id": "req-a1b2c3d4-e5f6-7890",
"subject": "payment-agent-sa",
"tool_id": "stripe-api",
"status": "REJECTED",
"reason": "Not authorized for production Stripe access",
"updated_at": "2026-02-23T10:05:00Z"
}
Access Request Lifecycle¶
| Status | Description |
|---|---|
PENDING | Awaiting admin review |
APPROVED | Access granted with a time-limited policy |
REJECTED | Access denied by admin |
EXPIRED | Time-limited policy has expired (automatic) |
Automatic Expiry¶
When an access request is approved, the platform creates an access policy with a TTL (default: 4 hours, configurable per tool via governance.approval.defaultDuration). When the TTL expires:
- The access policy is automatically removed by the garbage collector
- The access request status transitions to
EXPIRED - The agent can no longer call the tool until a new request is approved
Configuring approval TTL
Set the default approval duration per tool in the tool's governance configuration:
Access Request Object Reference¶
| Field | Type | Description |
|---|---|---|
id | string | Unique request ID |
subject | string | Identity requesting access |
agent_id | string | Agent making the request |
tool_id | string | Target tool |
status | string | Current status |
duration | string | Requested access duration |
reason | string | Rejection reason (when rejected) |
approver_id | string | Who approved the request |
expires_at | string | ISO 8601 expiration timestamp (when approved) |
created_at | string | ISO 8601 creation timestamp |
updated_at | string | ISO 8601 last update timestamp |