Getting Started

Policy Rules

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

Policy Rules

Policy rules control what tools Codex can use. Rules are evaluated before intent plans - a denied tool stays denied even if it appears in the plan. Applying a policy change is human-only: Codex can read policy and stage a proposal, but only you can confirm it.

Type policy commands as plain prompts with no leading slash (armor policy list, not /armor). Codex reserves / for its own built-in commands, so ArmorCodex intercepts the armor ... text in the UserPromptSubmit hook.

How Rules Work

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

Rule Effects

EffectKeywordWhat happens
AllowallowTool call proceeds
Denydeny, blockTool call is blocked before execution
Holdhold, require_approvalTool call pauses for approval

Adding Rules

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

armor policy add deny bash

ArmorCodex responds with a diff and risk warnings showing what will change. Then confirm:

armor yes

Multiple Rules at Once

Comma-separate different effects:

armor policy add allow bash and apply_patch, deny apply_patch

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

Tool Names

Use Codex tool names directly. Codex's shell tool has several internal names, all normalized to bash:

You typeMatches
bashThe shell tool (exec_command, shell, local_shell, unified_exec, container.exec)
apply_patchFile edits
mcp__<server>__<tool>A specific MCP tool
mcp__<server>__*Every tool from an MCP server
*All tools (wildcard)

Setting the Default Decision

The default decision applies when no rule matches. By default tools with no matching rule are allowed. To fail closed, set the default to deny (this appends a catch-all rule) and confirm:

armor policy default deny
armor yes

Options: allow, deny, hold.

Removing Rules

Remove by rule ID (shown in armor policy list), then confirm:

armor policy remove policy1
armor yes

Clear all rules:

armor policy reset
armor yes

Both go through the stage then confirm workflow.

Policy Templates

Apply a pre-built policy in one command, then confirm:

armor policy template lockdown
armor yes
TemplateDescription
all-allowEverything permitted - intent planning still enforced
strict-read-onlyOnly read-style tools allowed. Everything else denied
balancedReads allowed. Shell and file edits require approval
lockdownAll tools require approval. Nothing auto-allowed

Data Classification

ArmorCodex 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 (manual policy)
PIIPersonal data, SSN patterns (manual policy)

Example: Block Payment Data

armor policy add deny * for payment data
armor yes

If Codex tries to write a credit card number to a file, ArmorCodex detects PCI data, matches the payment rule, and blocks the tool call.

The Stage then 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. ArmorCodex stages the proposal and shows a diff plus risk warnings. Nothing is enforced yet
  3. You review and either confirm or cancel:
ActionCommand
Apply staged changearmor yes or armor policy confirm
Apply by proposal IDarmor policy confirm pol_abc12345
Discard staged changearmor no or armor policy cancel

Staged proposals are written to policy-pending.json with an id, hashes, the base version, and a 30 minute expiry.

Confirm re-checks the base version, base hash, proposal hash, and expiry before applying. If the active policy changed since you staged, the proposal is rejected and you re-stage.

Human-Only Apply

Applying a policy change is human-only. The policy_command MCP tool (callable by Codex) can read policy and stage proposals, but it cannot confirm. Only a terminal armor yes applies a staged change, and confirm echoes the applied diff and notes who staged it.

A legacy policy_update MCP tool is retained for back-compat and applies immediately. Prefer the staged armor commands and policy_command for the human-in-the-loop guarantee. See MCP Tools.

Viewing Policy

CommandWhat it shows
armor policy listHuman-readable summary with rule IDs and effects
armor policy viewThe active policy as raw JSON

Policy Schema

ArmorCodex stores policy as a simple rule list:

{
  "rules": [
    { "id": "policy1", "action": "deny", "tool": "bash" },
    { "id": "policy2", "action": "deny", "tool": "*" }
  ]
}

Rules are evaluated in order; the first match wins. Each rule matches by tool name (with an optional trailing * glob, e.g. mcp__github__*) and can add matchers for finer control:

FieldMeaning
actionallow, deny, or hold
toolTool name or trailing-* glob
dataClassMatch a detected data class (PCI, PAYMENT, PHI, PII)
anyParamApply an operator across every string field on the tool input

Matcher Operators

OperatorMeaning
$equalsExact string match
$containsSubstring match
$startsWith / $endsWithPrefix / suffix match
$matchesRegex match
$pathContainsPath match (canonicalizes ~ and absolute forms)
anyParamApply the operator across every string field on the tool input

Plain string sugar is supported: anyParam: "curl" is the same as anyParam: { "$contains": "curl" }.

Natural Language (Back-Compat)

The older natural-language form still works and applies immediately (no staging):

Policy list
Policy new: deny bash containing curl
Policy delete policy1
Policy reset

Prefer the structured armor policy commands for the stage then confirm safety.

Where Policies are Stored

Policies persist across sessions in the ArmorCodex data directory:

cat ~/.codex/armorcodex/policy.json

They survive restarts, plugin updates, and re-installs. Override the location with ARMORCODEX_POLICY_FILE.

On this page