Apus's Gateway exposes an HTTP endpoint for invoking a single tool directly. It is always enabled and uses Gateway auth plus tool policy. Like the OpenAI-compatible /v1/* surface, shared-secret bearer auth is treated as trusted operator access for the whole gateway.

Authentication

Uses the Gateway auth configuration.

Common HTTP auth paths:

Notes:

Security boundary (important)

Treat this endpoint as a full operator-access surface for the gateway instance.

Auth matrix:

Auth mode Behavior
token or password + Authorization: Bearer ... Proves possession of the shared gateway operator secret. Ignores narrower x-apus-scopes. Restores the full default operator scope set: operator.admin, operator.approvals, operator.pairing, operator.read, operator.talk.secrets, operator.write. Treats direct tool invokes as owner-sender turns.
Trusted identity-bearing HTTP (trusted proxy auth, or mode="none" on private ingress) Authenticates an outer trusted identity or deployment boundary. Honors x-apus-scopes when present. Falls back to the normal operator default scope set when the header is absent. Only loses owner semantics when the caller explicitly narrows scopes and omits operator.admin.

Request body

{
  "tool": "sessions_list",
  "action": "json",
  "args": {},
  "sessionKey": "main",
  "dryRun": false
}

Fields:

Policy + routing behavior

For identity-authenticated callers with named operator roles, the role's agent allowlist applies even when the selected session has no stored entry. A role with sandbox: "required" must target an existing session with recorded required-sandbox provenance; a missing session, including an omitted or "main" target that resolves to one, returns 403. Create a session through the normal session flow first. The WebSocket tools.invoke method uses the same rule. Shared-secret and trusted system calls retain their existing authority.

Recording direct actions in a conversation

The WebSocket tools.invoke method additionally accepts recordResult: true for an authenticated direct operator. Supply conversationReadOrigin: "direct-operator", an explicit sessionKey, its expectedSessionId, and an idempotencyKey. The Gateway refuses a replaced conversation before executing the action. HTTP calls and delegated agent calls cannot request this recording mode.

The existing transcript owner reserves the request before execution and stores its actual outcome as an operator receipt, without a model turn. A completed response has recorded: true; valid artifact payloads appear through the same artifacts.list and download APIs as model tool results. The action and its publication use current session and requester authority.

Retry the same key with the same arguments after a lost response. A completed receipt replays its recorded result, including a recorded failure, without executing the tool again. Different arguments return a key conflict. An accepted request without a completed receipt returns an uncertain-outcome error; inspect the original operation before explicitly creating another request. Receipt recovery follows the active transcript's retention and branch lifetime; this is not an independent long-term job ledger.

Tool availability is filtered through the same policy chain used by Gateway agents:

If a tool is not allowed by policy, the endpoint returns 404.

Important boundary notes:

Gateway HTTP also applies a hard deny list by default (even if session policy allows the tool):

Tool Reason
exec Direct command execution (RCE surface)
spawn Arbitrary child process creation (RCE surface)
shell Shell command execution (RCE surface)
fs_write Arbitrary file mutation on the host
fs_delete Arbitrary file deletion on the host
fs_move Arbitrary file move/rename on the host
apply_patch Patch application can rewrite arbitrary files
sessions_spawn Session orchestration; spawning agents remotely is RCE
sessions_send Cross-session message injection
cron Persistent automation control plane
gateway Gateway control plane; prevents reconfiguration via HTTP
nodes Node command relay can reach system.run on paired hosts

cron, gateway, and nodes are also owner-only: even outside this default deny list, non-owner callers cannot invoke them on this surface.

Customize the general deny list via gateway.tools:

{
  gateway: {
    tools: {
      // Additional tools to block over HTTP /tools/invoke
      deny: ["browser"],
      // Remove tools from the default deny list for owner/admin callers
      allow: ["gateway"],
    },
  },
}

gateway.tools.allow is an exposure override, not a scope upgrade. In identity-bearing HTTP modes, cron, gateway, and nodes remain unavailable to callers without owner/admin identity (operator.admin) even when listed in gateway.tools.allow. Shared-secret bearer auth still follows the full trusted-operator rule above.

To help group policies resolve context, you can optionally set:

Responses

Status Meaning
200 { ok: true, result }
400 { ok: false, error: { type, message } } (invalid request or tool input error)
401 Unauthorized
403 { ok: false, error: { type, message, requiresApproval? } } (tool call blocked by policy)
404 Tool not available (not found or not allowlisted)
405 Method not allowed
408 Request body read timed out
413 Request body exceeded the max payload size
429 Auth rate-limited (Retry-After set)
500 { ok: false, error: { type, message } } (unexpected tool execution error; sanitized message)

Example

curl -sS http://127.0.0.1:18789/tools/invoke \
  -H 'Authorization: Bearer secret' \
  -H 'Content-Type: application/json' \
  -d '{
    "tool": "sessions_list",
    "action": "json",
    "args": {}
  }'

Related