Configuration
API key setup, environment variables, the Gemini settings.json hook block, and the bundled MCP server declaration
Configuration
ArmorGemini has one required knob (your ArmorIQ API key) and a small set of environment variables that shape behavior. Everything else is a tested-good default.
Authentication
ArmorGemini requires an ArmorIQ API key. The key unlocks the backend policy layer and audit logging. Without it, hooks fail closed and every tool call is denied with a clear "not configured" message.
Via armoriq login (recommended)
armoriq login --product armorgeminiRuns the OAuth device-code flow, opens your browser, saves the key to ~/.armoriq/credentials.json.
Via Environment Variable
export ARMORIQ_API_KEY=ak_live_...Resolution Order
ArmorGemini looks for the API key in this order:
ARMORIQ_API_KEYenvironment variable~/.armoriq/credentials.json(written byarmoriq login)
If no key is found, the plugin fails closed. Run armoriq login --product armorgemini to recover.
~/.gemini/settings.json
The installer merges a six-hook block into your existing ~/.gemini/settings.json. It is idempotent: existing keys are preserved, only the ArmorGemini hooks are added or updated. The merged block looks like this (with <install-dir> rewritten to the actual path on your machine):
{
"hooks": {
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"name": "armorgemini-session-start",
"type": "command",
"command": "node <install-dir>/scripts/hook-router.mjs session-start"
}
]
}
],
"BeforeAgent": [
{
"matcher": "*",
"hooks": [
{
"name": "armorgemini-before-agent",
"type": "command",
"command": "node <install-dir>/scripts/hook-router.mjs before-agent"
}
]
}
],
"BeforeToolSelection": [
{
"matcher": "*",
"hooks": [
{
"name": "armorgemini-before-tool-selection",
"type": "command",
"command": "node <install-dir>/scripts/hook-router.mjs before-tool-selection"
}
]
}
],
"BeforeTool": [
{
"matcher": "*",
"hooks": [
{
"name": "armorgemini-before-tool",
"type": "command",
"command": "node <install-dir>/scripts/hook-router.mjs before-tool"
}
]
}
],
"AfterTool": [
{
"matcher": "*",
"hooks": [
{
"name": "armorgemini-after-tool",
"type": "command",
"command": "node <install-dir>/scripts/hook-router.mjs after-tool"
}
]
}
],
"SessionEnd": [
{
"matcher": "*",
"hooks": [
{
"name": "armorgemini-session-end",
"type": "command",
"command": "node <install-dir>/scripts/hook-router.mjs session-end"
}
]
}
]
}
}This is the Gemini CLI's native hook format:
- Event key (
SessionStart,BeforeAgent,BeforeToolSelection,BeforeTool,AfterTool,SessionEnd) is one of the CLI's lifecycle events. matcherfilters which invocations trigger the hook."*"matches every tool.hooks[]is an array of hooks that run in order. Each has aname, atype(onlycommandis used here), and acommandstring that is exec'd with the event payload on stdin.- The command writes
{ "decision": "allow" | "deny", "reason"?: string }on stdout.denyblocks the tool call.
BeforeToolSelection is wired but is a no-op today (Gemini API rejects allowedFunctionNames with mode: "AUTO", see Core Concepts). It is present so future Gemini CLI builds pick up the tightening layer as soon as the API allows it.
gemini-extension.json (the MCP server)
Alongside the settings hooks, the installer wires a bundled stdio MCP server so Gemini CLI launches it automatically on session start. The declaration lives in gemini-extension.json at the plugin root:
{
"name": "armorgemini",
"version": "0.3.2",
"description": "ArmorIQ intent-based security enforcement for the Gemini CLI.",
"mcpServers": {
"armorgemini-policy": {
"command": "node",
"args": ["${extensionPath}/scripts/policy-mcp.mjs"],
"cwd": "${extensionPath}"
}
}
}The server exposes register_intent_plan, reset_intent_plan, and get_intent_plan. See Core Concepts for what each tool does.
Environment Variables
| Variable | Default | Description |
|---|---|---|
ARMORIQ_API_KEY | (none) | ArmorIQ API key. Precedence: env > credentials.json. |
ARMORIQ_BACKEND_ENDPOINT | https://api.armoriq.ai | Backend base URL. Override for staging. |
ARMORIQ_ORG_ID | (none) | Scope the plugin to a specific ArmorIQ org. |
ARMORGEMINI_TIMEOUT_MS | 8000 | Per-request timeout to the backend, in milliseconds. |
ARMORGEMINI_DATA_DIR | ~/.gemini/armorgemini | Where per-session plan files and the local policy live. |
ARMORGEMINI_INTENT_REQUIRED | true | If false, the plugin skips intent-plan enforcement and runs in policy-only mode (v0.2 behavior). |
ARMORGEMINI_PLAN_TTL_SECONDS | 600 | Age after which a stored plan is treated as stale. |
ARMORGEMINI_DEBUG | false | Print plugin trace logs to stderr. |
GEMINI_SESSION_ID | (injected by Gemini CLI) | Per-session routing. Do not set manually. |
For a dev-only test escape hatch, ARMORGEMINI_SKIP_CREDS_FILE=1 prevents the plugin from reading ~/.armoriq/credentials.json. This lets fail-closed asserts hold on a developer machine that has a real credentials file. Not for production use.
Managing the Plugin
ArmorGemini installs as a set of hook entries, a gemini-extension.json manifest, and a set of TOML slash commands. To manage it, edit those files directly, or use the installer.
Update
cd ~/.armoriq/armorGemini
git pullDisable temporarily
Comment out (or delete) the ArmorGemini entries under hooks in ~/.gemini/settings.json. Gemini CLI reloads settings on the next gemini invocation.
Uninstall
Remove the six ArmorGemini hook entries from ~/.gemini/settings.json, remove the armorgemini-policy entry from gemini-extension.json (or delete the whole file if only ArmorGemini used it), remove ~/.gemini/commands/armor/, and delete ~/.armoriq/armorGemini if you no longer want the checkout.
# Optional: also remove the ArmorIQ CLI (shared with other Armor* products)
npm uninstall -g @armoriq/sdk
rm -rf ~/.armoriq