ArmorGemini

Intent-based security enforcement for the Gemini CLI

ArmorGemini

ArmorGemini adds security enforcement to the Gemini CLI. Gemini must declare what it intends to do before doing it, and every tool call is checked against that declared intent, a local policy, and an org-wide backend policy before it runs.

One Command Setup

curl -fsSL https://armoriq.ai/install_armorgemini.sh | bash

Installs the six ArmorGemini hooks into ~/.gemini/settings.json, wires the bundled armorgemini-policy MCP server via gemini-extension.json, copies the /armor:* slash commands into ~/.gemini/commands/armor/, and installs the ArmorIQ CLI.

What It Does

When you prompt Gemini to do something, ArmorGemini:

  1. Injects a directive on every turn the BeforeAgent hook tells Gemini to call register_intent_plan before any other tool
  2. Captures the plan via a bundled MCP server the armorgemini-policy server exposes register_intent_plan, reset_intent_plan, and get_intent_plan as native MCP tools
  3. Checks every tool call in BeforeTool, a layered evaluator runs: intent drift, then local policy, then backend policy
  4. Logs everything best-effort audit records flow to the ArmorIQ backend via POST /iap/audit

Setup

ArmorGemini requires an ArmorIQ API key. Get one at armoriq.ai.

armoriq login --product armorgemini       # OAuth device-code flow, saves to ~/.armoriq/credentials.json
# or
export ARMORIQ_API_KEY=YOUR_ARMORIQ_API_KEY

See Configuration for the full key-resolution order.

How Gemini CLI Sees It

ArmorGemini wires six Gemini CLI lifecycle hooks into ~/.gemini/settings.json and declares a bundled MCP server in gemini-extension.json. The hook block the installer merges in looks like this:

{
  "hooks": {
    "SessionStart":         [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node <install-dir>/scripts/hook-router.mjs session-start" }] }],
    "BeforeAgent":          [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node <install-dir>/scripts/hook-router.mjs before-agent" }] }],
    "BeforeToolSelection":  [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node <install-dir>/scripts/hook-router.mjs before-tool-selection" }] }],
    "BeforeTool":           [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node <install-dir>/scripts/hook-router.mjs before-tool" }] }],
    "AfterTool":            [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node <install-dir>/scripts/hook-router.mjs after-tool" }] }],
    "SessionEnd":           [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node <install-dir>/scripts/hook-router.mjs session-end" }] }]
  }
}

The installer rewrites <install-dir> to the absolute path where ArmorGemini is checked out on your machine. This is the Gemini CLI's native hook format: an event key, one matcher per entry, command-type hooks that receive the payload on stdin and return a JSON decision on stdout.

The MCP server is declared separately in gemini-extension.json:

{
  "mcpServers": {
    "armorgemini-policy": {
      "command": "node",
      "args": ["${extensionPath}/scripts/policy-mcp.mjs"],
      "cwd": "${extensionPath}"
    }
  }
}

Gemini CLI launches the MCP server automatically on session start. See Core Concepts for how the pieces fit together.

Requirements

  • Gemini CLI (gemini on your PATH)
  • Node.js 20+
  • curl (preinstalled on every macOS and Linux)
  • macOS, Linux, or Windows with WSL or any bash-compatible shell

On this page