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

On this page