Policy and Invocation
How CompozyOS validates tool input, applies daemon policy, handles approvals, redacts sensitive fields, and records invocation evidence.
Tool invocation is a runtime operation, not a direct function call from an agent. CompozyOS validates the input, applies policy, dispatches the tool, redacts sensitive fields, and returns a structured result.
Invocation lifecycle
Rendering diagram…
CLI invocation
Invoke with inline JSON:
compozy tool invoke compozy__tool_info --input '{"tool_id":"compozy__skill_view"}' -o jsonInvoke with a file:
compozy tool invoke compozy__tool_info --input-file ./input.json -o jsonInvoke with stdin:
echo '{"tool_id":"compozy__skill_view"}' | compozy tool invoke compozy__tool_info -o jsonWhat happened: the CLI sent JSON input to the daemon, the daemon validated and dispatched the tool, and the response came back as structured output.
Scoped diagnostics
Some tools depend on workspace, session, or agent context. Pass scope when you need diagnostics for the same view a managed session would receive:
compozy tool info compozy__skill_view --workspace ws-1 --session sess-1 --agent reviewer -o jsonUse scoped diagnostics when:
- a tool is visible globally but unavailable inside a session
- a workspace-specific resource should appear but does not
- an agent-specific toolset is narrower than the operator view
- a policy decision depends on the active session context
Approval-gated tools
Some tools may require approval before execution. When a tool requires approval, the descriptor and diagnostics should tell the caller what is missing. The invocation path accepts a single-use approval token:
compozy tool invoke <tool-id> \
--approval-token "$APPROVAL_TOKEN" \
--input '{"target":"example"}' \
-o jsonDo not persist approval tokens in memory, docs, logs, or task descriptions. Treat them as short-lived credentials.
Pending command-palette approvals
A palette invocation can return approval_pending with an approval_id. In the Web palette,
choose Approve or Deny and wait for the displayed execution result. For an invocation from
the CLI or API, use the profile that originally created the approval:
compozy approvals show <approval-id> --profile <owner> -o json
compozy approvals resolve <approval-id> --decision approved --profile <owner> -o json
compozy approvals show <approval-id> --profile <owner> -o jsonUse --decision denied to refuse execution, or compozy approvals cancel <approval-id> with the
same profile to cancel. A successful decision can still report execution_status: dispatching;
only the later status read confirms completion or failure. Expired and resolved approvals cannot
run again. Selecting another profile does not transfer ownership.
HTTP and UDS expose POST /api/tools/approvals/{id}/resolve?profile=<owner> with
{"decision":"approved"} or {"decision":"denied"}. HTTP decisions require a loopback listener.
The daemon checks profile availability and session binding again before accepting the decision,
and the deferred tool call rechecks current tool policy under the recorded owner.
Remembered native-tool decisions
When a managed session answers a native-tool approval prompt with allow-always or
reject-always, CompozyOS remembers the decision in the workspace database. The remembered key is exact:
workspace, agent, tool ID, and the SHA-256 digest of the authored input must all match. A different
agent or input prompts again.
Operators and managed agents can also set an explicit wider decision. Agent scope matches one agent and tool across every input; tool scope matches the tool across every agent and input in the workspace. This management path never accepts an input digest, so it cannot fabricate an exact prompt-origin decision.
CompozyOS checks a supplied single-use approval token first. Without one, it checks the remembered decision before opening another prompt. A remembered allow continues to dispatch; a remembered reject blocks the invocation. These decisions survive daemon restarts and remain workspace-scoped. They do not broaden ACP or workspace policy.
Set, list, or revoke remembered decisions from any management surface:
compozy tool approvals set compozy__workspace_list \
--workspace <workspace> \
--decision allow \
--scope agent \
--agent claude-code \
-o json
compozy tool approvals set compozy__workspace_list \
--workspace <workspace> \
--decision reject \
--scope tool \
-o json
compozy tool approvals list --workspace <workspace> -o json
compozy tool approvals revoke <grant-id> --workspace <workspace> -o jsonThe matching HTTP and UDS routes are PUT /api/tool-approval-grants,
GET /api/tool-approval-grants, and DELETE /api/tool-approval-grants/:grant_id, all with
workspace_id. The PUT body is {tool_id, decision, scope, agent_name?}; agent_name is required
for agent scope and forbidden for tool scope. Managed agents can use compozy__tool_approvals_set,
compozy__tool_approvals_list, and compozy__tool_approvals_revoke. Web Settings → General exposes the
same wider set, workspace list, and revoke actions.
An explicit wider allow only skips the prompt when the workspace tool policy already permits the invocation. It does not change the configured tool mode or broaden ACP, capability, or workspace boundaries.
Sensitive input fields
If input contains sensitive values, mark the field path so invocation evidence can redact it:
compozy tool invoke <tool-id> \
--input '{"secret_ref":"vault://provider/token"}' \
--sensitive-input-field secret_ref \
-o jsonWhat happened: CompozyOS still received the input needed by the handler, but the specified field is treated as sensitive in diagnostic and event surfaces.
Retired tool IDs
The removed memory tool IDs and the two removed memory toolsets stay reserved and are never reused. A tool policy that still names one of them by its exact ID is never an error. CompozyOS drops the entry and applies the rest of the policy:
- in an agent definition's
tools,toolsets, ordeny_tools; - in the tool list of a spawned or coordinator session's permission policy, or in a session's allowed-tools override.
CompozyOS logs one tools.retired_ids_ignored warning per policy owner (agent:<source path or name>
or session:<session id>) for the life of the daemon process, with the owner and the dropped ids.
A wildcard pattern in tools or deny_tools is not a retired entry. It is kept and matches no tool
because the memory tools no longer exist. An allow-list that held only retired entries stays
enforced, so it grants no tools; it never becomes an unrestricted policy. The filter is removed in
v0.6.0. See the migration guide.
Common failures
| Symptom | Likely cause | First check |
|---|---|---|
| Tool is not found | Wrong ID or tool not registered in the current runtime. | compozy tool search <query> -o json |
| Tool is visible but unavailable | Missing workspace/session/agent scope or prerequisite configuration. | compozy tool info <tool-id> --session <id> -o json |
| Invocation rejects input | JSON does not match the tool schema. | compozy tool info <tool-id> -o json |
| Invocation needs approval | Policy requires an approval token. | Descriptor diagnostics |
| Result omits expected secret value | Secrets are write-only or redacted by design. | Vault and policy docs |