Action Types

HushSpec defines a standard taxonomy of action types. Engines use action types to route evaluation to the appropriate rule blocks. Each action type represents a distinct category of agent behavior that may be controlled by one or more security rules.

Action-to-Rule Mapping

The following table shows every action type and which rule blocks are evaluated when that action occurs.

Action TypeDescriptionEvaluated Rule Blocks
file_read Reading a file from the filesystem forbidden_paths, path_allowlist
file_write Writing or creating a file forbidden_paths, path_allowlist, secret_patterns
egress Outbound network request egress
shell_command Executing a shell command shell_commands
tool_call Invoking a tool or MCP endpoint tool_access
patch_apply Applying a patch or diff to a file patch_integrity, forbidden_paths, path_allowlist, secret_patterns
computer_use Computer use agent action computer_use
input_inject Injecting keyboard, mouse, or touch input input_injection
custom Engine-defined action type tool_access (if name matches), otherwise engine-specific

Evaluation Flow

When an agent runtime intercepts an action, the following evaluation process occurs:

  1. Action arrives. The engine captures the action type and its context (path, domain, command string, tool name, content, etc.).
  2. Rule routing. The engine identifies which rule blocks apply to this action type using the mapping above.
  3. Per-rule evaluation. Each applicable and enabled rule block independently evaluates the action and produces a decision: allow, warn, or deny.
  4. Decision aggregation. All decisions are collected and the most restrictive one wins, using the precedence order: deny > warn > allow.
  5. Final decision. The engine enforces the aggregated decision.

Disabled rule blocks (enabled: false) are skipped entirely and produce no decision. If no enabled rule blocks apply to an action, the action is allowed by default.

Decision Types

Rules produce one of three standard decision outcomes:

DecisionPrecedenceMeaning
deny Highest The action is blocked. Execution MUST NOT proceed.
warn Middle The action is permitted pending confirmation. Engines determine how confirmation is obtained (interactive prompt, approval queue, auto-approve in CI, etc.). If confirmation is not possible, engines SHOULD treat warn as deny.
allow Lowest The action is permitted. Execution may proceed.

The precedence rule is simple: a single deny from any applicable rule block overrides everything else. This is the fail-closed principle applied to runtime evaluation.

Multi-Rule Evaluation Examples

Most action types are evaluated against multiple rule blocks simultaneously. The following examples illustrate how this works in practice.

Example 1: file_write to a sensitive path with secrets

An agent attempts to write a file to src/config.js that contains an AWS access key.

yaml
rules:
  forbidden_paths:
    patterns: ["**/.env", "**/.ssh/**"]
  path_allowlist:
    enabled: true
    write: ["src/**"]
  secret_patterns:
    patterns:
      - name: "aws_key"
        pattern: "AKIA[0-9A-Z]{16}"
        severity: "critical"

Evaluation:

  • forbidden_paths: src/config.js does not match **/.env or **/.ssh/**allow
  • path_allowlist: src/config.js matches src/** in write list → allow
  • secret_patterns: content contains AKIA... at severity criticaldeny

Aggregated result: deny. The secret detection overrides the path permissions.

Example 2: patch_apply with multiple checks

An agent applies a 50-line patch to lib/utils.py.

yaml
rules:
  forbidden_paths:
    patterns: ["**/node_modules/**"]
  patch_integrity:
    max_additions: 200
    max_deletions: 100
  secret_patterns:
    patterns:
      - name: "generic_api_key"
        pattern: "(?i)api[_-]?key\\s*[=:]\\s*['\"]?[a-z0-9]{32,}"
        severity: "error"

Evaluation:

  • forbidden_paths: lib/utils.py does not match → allow
  • patch_integrity: 50 additions is within the 200 limit → allow
  • secret_patterns: no API key pattern found in patch content → allow

Aggregated result: allow. All three rule blocks permit the action.

Example 3: tool_call with confirmation

An agent invokes the deploy tool.

yaml
rules:
  tool_access:
    block: ["rm_database"]
    require_confirmation: ["deploy", "database_write"]
    default: "allow"

Evaluation:

  • tool_access: deploy is not in block, but it is in require_confirmationwarn

Aggregated result: warn. The engine prompts for confirmation before allowing the tool call to proceed. If running in a non-interactive context where confirmation is impossible, the engine should treat this as deny.

Example 4: file_write to a forbidden path

An agent writes to .env which is clean (no secrets detected).

yaml
rules:
  forbidden_paths:
    patterns: ["**/.env"]
    exceptions: ["**/.env.example"]
  secret_patterns:
    patterns:
      - name: "aws_key"
        pattern: "AKIA[0-9A-Z]{16}"
        severity: "critical"

Evaluation:

  • forbidden_paths: .env matches **/.env and does not match exceptions → deny
  • secret_patterns: no secrets in content → allow

Aggregated result: deny. The path rule blocks the write regardless of the content being clean.