Outcall
SpecificationsS004 · Agent API

Interface requirements

S004 Interface Requirements

All endpoints are served on the agent Unix socket (/run/outcall/agent.sock). Content-Type is application/json for all requests and responses.


S004-IF-001 POST /v1/checkin [P1]

Register the agent and receive identity and session context. The agent sends an empty body; outcalld derives the container identity from the Unix socket peer credentials (SO_PEERCRED) and maps it to Docker metadata.

Request body:

{}

No agent-supplied fields. Identity is derived entirely host-side from the calling process's peer credentials.

Success response (200):

{
  "success": true,
  "data": {
    "container_id": "ctr-a1b2c3d4",
    "session_token": "tok-e5f6g7h8i9j0k1l2",
    "context_keys": ["action_type", "target", "metadata"]
  }
}

Error response (403 -- unknown container):

{
  "success": false,
  "error": "check-in rejected: peer PID 12345 does not belong to a known container"
}

S004-IF-002 POST /v1/permissions/check [P1]

Request a verdict before executing an action. The session token MUST be sent in the Authorization header as Bearer <token>.

Request body:

{
  "action_type": "tool_exec",
  "target": "read_file",
  "metadata": {
    "path": "/workspace/config.yaml",
    "mode": "read"
  }
}
FieldTypeRequiredDescription
action_typestringYesOne of: tool_exec, network_call, file_access, shell_exec
targetstringYesThe specific resource (tool name, URL, file path, command)
metadataobjectNoArbitrary key-value pairs for rule matching context

Success response (200 -- allowed):

{
  "success": true,
  "data": {
    "allowed": true,
    "matched_rule": "rule-7f8e9d",
    "reason": null
  }
}

Success response (200 -- denied):

{
  "success": true,
  "data": {
    "allowed": false,
    "matched_rule": null,
    "reason": "no rule allows network_call to evil.example.com"
  }
}

Error response (401 -- missing or invalid token):

{
  "success": false,
  "error": "invalid or missing session token"
}

Error response (429 -- rate limited):

{
  "success": false,
  "error": "rate limit exceeded for container ctr-a1b2c3d4"
}

Header: Retry-After: 2


S004-IF-003 POST /v1/requests/rules [P2]

Submit a rule request for host operator approval. Requires Bearer <token> authorization. The body MUST contain a complete, valid rule file in the S003 YAML format (S003-IF-012). outcalld parses and validates the file before queuing; invalid files are rejected immediately.

Request body:

{
  "rule_file": "version: \"1\"\nrules:\n  - id: allow-workspace-read\n    condition: \"action_type == 'file_access' && target.startsWith('/workspace')\"\n    action: allow\n    description: Allow read access to /workspace directory"
}
FieldTypeRequiredDescription
rule_filestringYesComplete S003-format YAML rule file (S003-IF-012). Must parse and validate successfully.

Success response (201):

{
  "success": true,
  "data": {
    "id": "rr-abc123",
    "status": "pending",
    "reason": null
  }
}

Error response (422 -- invalid rule file):

{
  "success": false,
  "error": "invalid rule file: YAML parse error at line 3: unexpected token"
}

S004-IF-004 GET /v1/requests/rules/{id} [P2]

Query the status of a previously submitted rule request. Requires Bearer <token> authorization.

Success response (200 -- pending):

{
  "success": true,
  "data": {
    "id": "rr-abc123",
    "status": "pending",
    "reason": null
  }
}

Success response (200 -- approved):

{
  "success": true,
  "data": {
    "id": "rr-abc123",
    "status": "approved",
    "reason": "operator approved at 2026-04-21T14:30:00Z"
  }
}

Success response (200 -- rejected):

{
  "success": true,
  "data": {
    "id": "rr-abc123",
    "status": "rejected",
    "reason": "policy does not permit filesystem write rules for this container"
  }
}

Error response (404 -- unknown request ID):

{
  "success": false,
  "error": "rule request rr-xyz789 not found"
}

Error response (403 -- request belongs to another container):

{
  "success": false,
  "error": "rule request rr-abc123 not found"
}

Note: a 403 for cross-container access MUST return the same 404-style message to avoid confirming the existence of another container's request.


S004-IF-005 Error response format [P1]

All error responses MUST use the ApiResponse envelope:

{
  "success": false,
  "error": "human-readable error message"
}

HTTP status codes used by the agent API:

CodeMeaning
200Success (including deny verdicts -- the request succeeded, the action was denied)
201Rule request created
400Malformed request body
401Missing or invalid session token
403Check-in rejected (unknown container)
404Rule request not found
413Request body too large
422Invalid condition syntax in rule request
429Rate limit exceeded
500Internal server error
503Peer identity lookup timed out or session capacity reached

On this page