Concepts

Concepts

How intent plans, drift detection, and CSRG proofs work together

Concepts

ArmorCopilot enforces security at two layers: intent (what Copilot said it would do) and policy (what you said is allowed). Both must pass before a tool runs.

Intent Plans

Every Copilot session begins with a plan. The userPromptSubmitted hook injects a directive into Copilot's context telling it to call the register_intent_plan MCP tool as its first action.

A plan has this shape:

{
  "goal": "Add a summary file for /etc",
  "steps": [
    {
      "action": "write",
      "description": "Create the summary file",
      "metadata": { "inputs": { "file_path": "/tmp/etc-notes.md" } }
    },
    {
      "action": "read",
      "description": "Verify the file was written",
      "metadata": { "inputs": { "file_path": "/tmp/etc-notes.md" } }
    }
  ],
  "session_id": "<copilot-session-uuid>"
}

ArmorCopilot normalizes the plan, mints a signed intent JWT against the ArmorIQ backend (if connected), and writes a pending plan file at ~/.copilot/armorcopilot/pending-plan.<session_id>.json.

Per-session paths ensure concurrent Copilot windows don't clobber each other's plans.

Intent Drift

After the plan is registered, every preToolUse hook checks the tool name + arguments against the plan's declared steps.

  • If the tool matches a declared step → allow
  • If the tool isn't in the plan → block (intent drift)
  • If the tool IS in the plan but policy denies it → block (policy wins)

Drift detection catches the case where Copilot says "I'll write the file then verify it" but then quietly tries shell to run rm -rf. Without drift detection, a policy that only blocked rm -rf would not catch the pattern. Drift makes any unplanned tool suspicious by default.

The whitelisted tools register_intent_plan, policy_read, policy_update, plus a small set of read-only coordination tools (read, grep, glob, todowrite, etc.) bypass the drift check. Network egress tools (webfetch, websearch) do not bypass. They go through full policy + intent enforcement.

Policy Rules

Policies are evaluated before intent. A denied tool stays denied even if it's in the plan.

Rules support:

  • Tool-name match
  • Argument-pattern match (substring or regex)
  • Data-class match (PCI / PAYMENT / PHI / PII)
  • Compound rules (path conditions, negation)

See Policy Rules for the full command surface + practical patterns.

CSRG Cryptographic Proofs

When backend-connected with crypto_policy_enabled=true, ArmorCopilot signs each step of the intent plan as it executes. The proof chain is bound to a Merkle root that's anchored on the ArmorIQ backend.

Benefits:

  • Tamper detection. Any post-hoc modification of audit rows invalidates the chain.
  • Step provenance. Each tool call is cryptographically tied to the plan that declared it.
  • Compliance evidence. Exportable proof artifacts for SOC 2 / ISO 27001 audits.

CSRG is opt-in. Default is off (intent + policy alone work fine for most enforcement use cases).

Audit Pipeline

Every tool call (allowed OR denied) is enqueued to a local write-ahead log at ~/.copilot/armorcopilot/audit/. A background flusher inside the MCP server batches WAL entries and ships them to the ArmorIQ backend asynchronously.

PropertyValue
DurabilityDisk-backed (WAL). Survives plugin restart.
DeliveryAsync batched. Does not block the user-facing tool call.
BackpressureCapped read window (4MiB per batch). Prevents OOM on backend outage.
Visibilityplatform.armoriq.ai/products/armor-copilot

If the ArmorIQ backend is unreachable, the WAL grows on disk and flushes when connectivity returns. The user-facing flow is never blocked.

On this page