Skip to content

[Feature]: Tool security classification properties (isDestructive, isReadOnly, isConcurrencySafe) #62962

Description

@sarkarsaurabh27

Summary

Add six standard security classification properties to tool definitions so safety decisions (confirmation prompts, parallel scheduling, abort handling) are schema-driven rather than requiring per-call case analysis.

Problem to solve

Tool definitions currently carry ownerOnly and participate in allow/deny policy, but have no standard way to declare whether a tool is destructive, read-only, concurrency-safe, or involves external systems. This means:

  • Confirmation prompts are implemented ad-hoc per tool rather than driven by a declared isDestructive flag.
  • Parallel tool scheduling cannot be automated — the orchestrator has no schema signal for whether two tools can safely run simultaneously.
  • Abort behavior on user interrupt is inconsistent — some tools should cancel immediately, others should finish before stopping.
  • Safety classifiers lack a compact representation of what a tool call does, making per-call analysis expensive.

Scaffolding quality (including tool schema design) explains same-model score gaps of 17 issues on 731 SWE-bench problems (SWE-bench leaderboard, Feb 2026). Tool misuse is OWASP #5 agentic risk; tools without declared safety properties are the primary cause (OWASP Top 10 for Agentic Applications, 2026).

Proposed solution

1. Six classification properties

// src/agents/tools/common.ts — extend AnyAgentTool
export type AgentToolSecurityProps = {
  /** Does not modify any state — skip confirmation, allow unrestricted parallel use. */
  isReadOnly?: boolean;
  /** Action is irreversible — always confirm; warn with "may" not "will". */
  isDestructive?: boolean;
  /** Safe to run in parallel with other tool calls — no shared write dependency. */
  isConcurrencySafe?: boolean;
  /** On user interrupt: "cancel" kills immediately; "block" waits for clean finish. */
  interruptBehavior?: "cancel" | "block";
  /** Involves external systems (network, third-party APIs) — applies network policy. */
  isOpenWorld?: boolean;
  /** Compact one-line summary of the call for safety classifier input. */
  toAutoClassifierInput?: (args: unknown) => string;
};

2. Example annotations on existing tools

export const webFetchTool = {
  name: "web_fetch",
  isReadOnly: true,
  isOpenWorld: true,
  isConcurrencySafe: true,
  interruptBehavior: "cancel",
  toAutoClassifierInput: (args) => `web_fetch ${(args as { url: string }).url}`,
};

export const execTool = {
  name: "exec",
  isReadOnly: false,
  isDestructive: false, // depends on command, but tool itself is not always destructive
  isConcurrencySafe: false,
  interruptBehavior: "block",
  isOpenWorld: true,
  toAutoClassifierInput: (args) => `exec ${(args as { command: string }).command?.slice(0, 80)}`,
};

export const fileDeleteTool = {
  name: "file_delete",
  isReadOnly: false,
  isDestructive: true,
  isConcurrencySafe: false,
  interruptBehavior: "block",
  isOpenWorld: false,
  toAutoClassifierInput: (args) => `file_delete ${(args as { path: string }).path}`,
};

3. Drive safety decisions from schema

// Permission layer: skip confirmation for read-only tools
if (tool.isReadOnly) return "allow";

// UI layer: extra confirmation + "may" warning for destructive tools
if (tool.isDestructive) {
  await confirm(`Note: may permanently affect ${tool.toAutoClassifierInput?.(args)}`);
}

// Parallel scheduler: run concurrently only when both tools declare safe
const canParallelize = toolA.isConcurrencySafe && toolB.isConcurrencySafe;

4. Update conformance snapshot

Add the new properties to TOOL_POLICY_CONFORMANCE in src/agents/tool-policy.conformance.ts so CI detects drift when a tool is added without classification.

5. Warning language: "may" not "will"

Destructive operation warnings should use "may" not "will"git push --force does not overwrite anything if the remote hasn't diverged; rm -rf temp/ might be deleting disposable files. Overstated warnings cause alert fatigue; accurate warnings maintain credibility (BP 06).

Alternatives considered

  • Per-tool ad-hoc checks: current approach. Works but requires every new tool to re-implement the same safety logic, and misses tools that don't bother.
  • Allowlist-based safety: already in place via tool-policy.ts. Classification properties are the complement — they describe tool behavior, not access control.
  • Runtime classifier only: the toAutoClassifierInput property enables a separate lightweight safety query before execution (the critic/permission side-query pattern). This is a complement to, not a replacement for, schema-declared properties.

Impact

  • Affected: All tool definitions; parallel tool scheduling; confirmation prompt logic; safety classifier integration.
  • Severity: Medium — no current breakage, but the absence creates inconsistency and makes future safety automation harder.
  • Frequency: Every tool call in every session.
  • Consequence: Without declared properties, adding new safe-to-parallelize tools requires manual orchestrator changes; adding new destructive tools risks missing confirmation prompts.

Evidence/examples

  • OWASP Top 10 for Agentic Applications 2026: tool misuse (CLI: add Opencode integration #5) — tools with poor descriptions/metadata are the primary cause.
  • SWE-bench leaderboard Feb 2026: scaffolding quality (including tool design) explains 17-issue gaps on same-model comparisons.
  • BP 04 (tool design): "every tool should declare six security properties as part of its definition — these properties drive automatic safety decisions without requiring per-call analysis."

Additional information

  • toAutoClassifierInput is the most subtle property: it compresses a tool invocation (including arguments) into a single line that a safety classifier can evaluate cheaply. Example: exec ls -la /project/src. The classifier sees that string and makes a binary safe/unsafe judgment without loading full tool context.
  • isDestructive = true should trigger: confirmation prompt, "may" (not "will") warning language, and a reversibility check (is there a safer alternative?).
  • Properties are optional — tools without them fall back to current behavior. Annotate high-risk tools first (exec, file_delete, git_push, web_fetch), then fill in the rest incrementally.
  • Related review: best-practices/results/agent-review-2026-04-07.md (dimension 04 — Tool design).

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.securitySecurity documentation

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions