Tool policy

Sub-agents use the same profile and tool-policy pipeline as the parent or target agent first. After that, Apus applies the sub-agent restriction layer.

When settled children resume a requester after sessions_yield, the continuation keeps the requester policy captured at spawn. The handoff must still belong to the current requester session and settled batch, and every child in that batch must carry the same verified requester policy. Conflicting or missing child policies leave the continuation under its ordinary restricted policy. Current tool restrictions and live revocation checks still apply at execution; the handoff does not grant additional tools or infer a sender identity.

An automatic completion turn for a requester on the Claude CLI backend keeps that same captured policy. The tools reach the CLI only through Apus's policy-filtered MCP surface, so native CLI tools stay disabled for the turn and every inherited deny still applies. Other CLI backends, node-hosted Claude CLI sessions, and settle batches do not regain requester tools. Message-tool-only replies keep their existing source-bound message grant. When that restricted surface needs its own Claude CLI session, the requester's next resumed turn receives the completion prompt and reply as quoted context when its account may replay saved history; see CLI backends.

Sub-agents always lose gateway, agents_list, session_status, progress_card, cron, message, sessions_send, and the conversations_* tools regardless of depth or role (system-level/interactive tools, parent-owned progress cards, direct delivery surfaces, or tools the main agent should coordinate). This hard-deny layer is derived from the persisted sub-agent session envelope on every turn, including resumed and visible dashboard sessions; ordinary allow/alsoAllow entries cannot override it. Hidden launches also disable message before tool construction as defense in depth. Sub-agents at the configured depth cap additionally lose subagents, sessions_list, sessions_history, and sessions_spawn, so their communication stays on the announce chain.

sessions_history remains a bounded, redacted recall view here too — it is neither a raw transcript dump nor a prose-only rendering.

By default, sub-agents below depth 5 receive sessions_spawn, subagents, sessions_list, and sessions_history so they can manage their children.

Override via config

{
  agents: {
    defaults: {
      subagents: {
        maxConcurrent: 1,
      },
    },
  },
  tools: {
    subagents: {
      tools: {
        // deny wins
        deny: ["gateway", "cron"],
        // if allow is set, it becomes allow-only (deny still wins)
        // allow: ["read", "exec", "process"]
      },
    },
  },
}

tools.subagents.tools.allow is a final allow-only filter. It can narrow the already-resolved tool set, but it cannot add back a tool removed by tools.profile. For example, tools.profile: "coding" includes web_search/web_fetch but not the browser tool. To let coding-profile sub-agents use browser automation, add browser at the profile stage:

{
  tools: {
    profile: "coding",
    alsoAllow: ["browser"],
  },
}

Use per-agent agents.entries.*.tools.alsoAllow: ["browser"] when only one agent should get browser automation.