Getting Started

Policy Rules

Control what tools Claude can use with allow/deny/hold rules managed entirely from the chat prompt

Policy Rules

Policy rules control what tools Claude can use. Rules are evaluated before intent plans - a denied tool stays denied even if it appears in the plan. All policy changes are human-only: Claude can read policy through MCP but cannot update it.

How Rules Work

  1. Rules evaluate top-to-bottom in statement order
  2. First matching rule wins (allow, deny, or hold)
  3. If no rule matches, the default decision applies (configurable per policy)
  4. New rules are added at the top, giving them highest priority

Rule Effects

EffectKeywordWhat happens
AllowallowTool call proceeds
Denydeny, blockTool call is blocked before execution
Holdhold, require_approval, ask beforeTool call pauses for user approval via Claude Code's native UI

Adding Rules

Use /armor policy add to stage a rule change. All changes go through a stage → confirm workflow:

/armor policy add deny WebFetch

ArmorClaude responds with a diff showing what will change. Then confirm:

/armor yes

Multiple Rules at Once

Comma-separate different effects:

/armor policy add allow Read and Grep, deny Write, hold Bash

This stages all three rules in one proposal. Confirm with /armor yes.

Tool Name Resolution

You can use exact Claude Code tool names (Read, WebFetch, Bash) or natural language:

You typeResolves to
read, read filesRead
shell, terminalBash
fetch web, web fetchWebFetch
search web, web searchWebSearch
sub agent, subagentAgent
file searchGlob
code searchGrep
multi edit, multi-editMultiEdit
*All tools (wildcard)

Setting the Default Decision

The default decision applies when no rule matches a tool call:

/armor policy default deny

Options: allow, deny, hold.

Removing Rules

Remove by rule ID (shown in /armor policy list):

/armor policy remove stmt_1

Clear all rules:

/armor policy reset

Both go through the stage → confirm workflow.

Policy Templates

Apply a pre-built policy in one command:

/armor policy template balanced
TemplateDescription
all-allowEverything permitted - intent planning still enforced
strict-read-onlyOnly Read/Grep/Glob allowed. Everything else denied
balancedRead allowed. Bash/Write/Edit require approval
lockdownAll tools require approval. Nothing auto-allowed

Data Classification

ArmorClaude auto-detects sensitive data in tool arguments:

ClassWhat it detects
PCICredit card numbers (Luhn validation), card-related keywords
PAYMENTPayment tool names, banking keywords (IBAN, SWIFT, routing numbers)
PHIHealth/medical data identifiers
PIIPersonal data, SSN patterns

When sensitive data is detected, rules with data class conditions are evaluated. For example:

/armor policy add deny * for payment data

The Stage → Confirm Workflow

Every policy mutation goes through staging. This prevents accidental changes:

  1. You type a command (e.g., /armor policy add deny Bash)
  2. ArmorClaude stages the proposal and shows a diff
  3. You review and either confirm or cancel:
ActionCommand
Apply staged change/armor yes or /armor policy confirm
Apply by proposal ID/armor policy confirm pol_abc12345
Discard staged change/armor no or /armor policy cancel

Staged proposals expire after 30 minutes if not confirmed.

Proposals include a base version check. If someone else changes the policy between staging and confirming, the confirm is rejected to prevent conflicts.

Draft Workflow (Advanced)

For complex policy edits, use the draft workflow:

Validate Pasted JSON

/armor policy draft validate {"schemaVersion":"armor.policy.v1",...}

Validates the JSON against the policy schema and creates a draft with a draft_XXXXXXXX ID.

Edit an Existing Draft

/armor policy draft edit draft_abc12345 {"schemaVersion":"armor.policy.v1",...}

Replaces the draft's JSON with new validated content.

Revise a Draft

/armor policy revise draft_abc12345 "remove stmt_2"

Applies a deterministic edit to a draft (e.g., removing a statement).

Stage a Draft

/armor policy stage draft_abc12345

Moves a validated draft into the staging area for confirmation.

Policy IR Format

Policies use the armor.policy.v1 schema internally:

{
  "schemaVersion": "armor.policy.v1",
  "kind": "PolicyProfile",
  "metadata": { "name": "my-policy", "description": "..." },
  "defaults": {
    "decision": "deny",
    "conflictResolution": "deny_overrides"
  },
  "statements": [
    {
      "id": "stmt_1",
      "effect": "permit",
      "principal": { "type": "agent", "id": "claude-code" },
      "action": { "type": "tool", "eq": "Read" },
      "resource": { "type": "workspace", "scope": "current" },
      "conditions": []
    }
  ]
}

Statement Fields

FieldDescription
idUnique identifier (e.g., stmt_1)
effectpermit, forbid, or require_approval
principalWho the rule applies to (agent, user, org, role)
actionTool matcher - eq for exact, in for list
resourceScope (workspace, file, directory, network)
conditionsAdditional constraints (see below)

Condition Operators

OperatorExampleDescription
eqbash.program eq "curl"Exact match
intool.name in ["Read", "Grep"]Value in list
not_inbash.program not_in ["rm", "curl"]Value not in list
matchesfile.path matches "*.secret"Pattern match
not_matchesfile.path not_matches "*.log"Negative pattern
starts_withfile.path starts_with "/etc"Prefix match
within_workspacefile.path within_workspace trueWithin project dir

Condition Fields

FieldDescription
tool.nameClaude Code tool name
bash.programProgram being run in Bash (e.g., curl, rm)
bash.rawRaw bash command string
bash.hasWriteRedirectionWhether command writes to files
file.pathFile path being accessed
network.hostNetwork host being contacted
mcp.serverMCP server name

Viewing and Exporting Policy

CommandWhat it shows
/armor policy listHuman-readable summary with rule IDs
/armor policy viewRaw policy JSON
/armor policy exportFull policy state JSON (including version history)

Crypto Policy Binding

When connected to the ArmorIQ backend, policies are cryptographically bound using Merkle trees. After changing policy, ArmorClaude automatically reissues the crypto binding. To manually rebind:

/armor policy rebind

This ensures the policy hash in the signed intent token matches the active policy.

Where Policies are Stored

Policies persist across sessions in the plugin data directory:

cat ~/.claude/plugins/data/armorclaude-armoriq/policy.json

They survive restarts, plugin updates, and re-installs.

On this page