Plugin API: let service plugins require canonical approval for dangerous tools #353

Closed
opened 2026-09-08 02:03:37 +00:00 by nsaspy · 0 comments
Owner

Upstream handoff from lost-rob0t/zara-plugins / zara-shell #5

The pinned Zara plugin API used by the registry (8e247fd4cb6ffe1f3258bfb4f115a3339208e8c1) exposes service-plugin tools through ServicePlugin.tools(), but a plugin cannot declare that a specific tool must traverse Zara's canonical ToolApprovalController.

Today ToolRegistry.requires_approval(name) is populated only from global [tool_approval].required_tools. That works when an operator already knows every dangerous plugin tool name, but a generic execution plugin cannot safely make its mutation surface available while also proving approval cannot be accidentally omitted from configuration.

Needed contract

  • plugin-owned tool registration can mark a tool as approval required through Zara's existing principal-scoped approval controller;
  • plugin/model/client input cannot downgrade that requirement;
  • duplicate/conflicting registration fails closed;
  • lifecycle unload removes the tool and its approval metadata together;
  • compatibility tests can assert the published plugin tool is approval-gated before invocation;
  • no second approval channel/runtime is introduced.

Concrete consumer

zara-shell intends to expose an argv-only, allowlisted, cwd-confined, time/output/input-bounded command runner. The runner implementation can proceed in the plugin repo, but its execution tool should not be published/merged until Zara Core can make shell.run canonically approval-required by construction rather than relying on optional operator configuration.

This is a Core API gap only; no Zara runtime changes are being made from the plugin worker.

## Upstream handoff from `lost-rob0t/zara-plugins` / zara-shell #5 The pinned Zara plugin API used by the registry (`8e247fd4cb6ffe1f3258bfb4f115a3339208e8c1`) exposes service-plugin tools through `ServicePlugin.tools()`, but a plugin cannot declare that a specific tool must traverse Zara's canonical `ToolApprovalController`. Today `ToolRegistry.requires_approval(name)` is populated only from global `[tool_approval].required_tools`. That works when an operator already knows every dangerous plugin tool name, but a generic execution plugin cannot safely make its mutation surface available while also proving approval cannot be accidentally omitted from configuration. ### Needed contract - plugin-owned tool registration can mark a tool as **approval required** through Zara's existing principal-scoped approval controller; - plugin/model/client input cannot downgrade that requirement; - duplicate/conflicting registration fails closed; - lifecycle unload removes the tool and its approval metadata together; - compatibility tests can assert the published plugin tool is approval-gated before invocation; - no second approval channel/runtime is introduced. ### Concrete consumer `zara-shell` intends to expose an argv-only, allowlisted, cwd-confined, time/output/input-bounded command runner. The runner implementation can proceed in the plugin repo, but its execution tool should not be published/merged until Zara Core can make `shell.run` canonically approval-required by construction rather than relying on optional operator configuration. This is a Core API gap only; no Zara runtime changes are being made from the plugin worker.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/zara#353
No description provided.