armoriq.yaml Reference
Complete schema for the armoriq.yaml config file — identity, proxy, MCP servers, policy, intent settings, and $ENV_VAR substitution.
armoriq.yaml is the config-as-code manifest for an ArmorIQ-protected agent. It declares the agent's identity, the MCP servers it can reach, the tools it's allowed to invoke, and the intent-token settings that govern how long its permissions last.
Use the YAML when you want:
- Your policy versioned alongside your agent code.
- CI to register agent changes automatically (
armoriq register). - A single source of truth across dev, staging, and production.
Skip the YAML and use ArmorIQClient(api_key=...) directly if you're building a single-service single-environment agent with static policy.
Generate the file
The fastest way to get a correct starting file is armoriq init, which probes each MCP server and pre-fills the policy.allow list with every discovered tool.
armoriq init --output armoriq.yamlThen edit the file to tighten the policy before armoriq register.
Complete schema
version: v1 # schema version (always "v1")
identity:
api_key: $ARMORIQ_API_KEY # supports $ENV_VAR substitution
user_id: service-account # identifier for the service or worker
agent_id: booking-bot # identifier for the agent persona
environment: production # "sandbox" or "production"
proxy:
url: https://proxy.armoriq.ai # usually auto-resolved; set to override
timeout: 30 # seconds; request timeout to the proxy
max_retries: 3 # retry count on transient failures
mcp_servers:
- id: travel # short, unique ID used in policy refs
url: https://mcp.travel.example # MCP server endpoint
description: Flight and hotel bookings # human-readable; optional
auth:
type: bearer # "none" | "bearer" | "api_key"
token: $TRAVEL_MCP_TOKEN # for type=bearer; $ENV_VAR supported
- id: weather
url: https://mcp.weather.example
auth:
type: api_key
api_key: $WEATHER_MCP_KEY
header_name: X-Weather-Key # optional; default "X-API-Key"
- id: crm
url: https://mcp.crm.example
auth:
type: none # public MCP, no auth
policy:
allow:
- travel.book_flight # format: <mcp_id>.<tool_name>
- travel.search_hotels
- weather.get_forecast
- crm.get_contact
deny:
- travel.cancel_booking # more-specific deny wins over allow
- crm.delete_contact
intent:
ttl_seconds: 300 # intent token lifetime
require_csrg: true # require Canonical Structured Reasoning GraphField reference
Top-level
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
version | "v1" | ✓ | "v1" | Schema version. Always v1 today. |
identity | Identity | ✓ | — | Who this agent is. |
environment | "sandbox" | "production" | "sandbox" | Which ArmorIQ environment this config targets. | |
proxy | Proxy | see below | Proxy settings. | |
mcp_servers | MCPServer[] | [] | MCP servers this agent can call. | |
policy | Policy | {allow: [], deny: []} | Tool allow / deny rules. | |
intent | Intent | see below | Intent-token defaults. |
identity
| Field | Type | Required | Description |
|---|---|---|---|
api_key | string | ✓ | ArmorIQ API key. Supports $ENV_VAR substitution — the literal string $ARMORIQ_API_KEY is replaced with the env var value at load time. |
user_id | string | ✓ | Service or worker identifier (e.g. service-account, booking-service). Appears in audit logs. |
agent_id | string | ✓ | Agent persona identifier (e.g. booking-bot, customer-support-bot). Policies can scope by agent. |
proxy
| Field | Type | Default | Description |
|---|---|---|---|
url | string | "https://proxy.armoriq.ai" | Proxy endpoint. Auto-resolved by the SDK; override only for self-hosted proxies. |
timeout | integer (seconds) | 30 | Request timeout for the proxy. |
max_retries | integer | 3 | Retry count on transient failures (network errors, 5xx). |
mcp_servers[]
Each entry declares one MCP server the agent can invoke.
| Field | Type | Required | Description |
|---|---|---|---|
id | string | ✓ | Short, unique identifier used in policy.allow / policy.deny refs (e.g. travel → travel.book_flight). |
url | string | ✓ | MCP server endpoint. Must speak MCP JSON-RPC. |
description | string | Human-readable description shown in the dashboard. | |
auth | MCPAuth | Auth config. Defaults to {type: "none"}. |
mcp_servers[].auth
type | Additional fields | Description |
|---|---|---|
"none" | — | Public MCP, no auth. |
"bearer" | token: string | Bearer token, sent as Authorization: Bearer <token>. Supports $ENV_VAR. |
"api_key" | api_key: string, header_name?: string | API key sent in a custom header (default X-API-Key). Supports $ENV_VAR. |
policy
Tool-level allow and deny rules. Format: <mcp_id>.<tool_name>.
| Field | Type | Default | Description |
|---|---|---|---|
allow | string[] | [] | Tools explicitly permitted. |
deny | string[] | [] | Tools explicitly forbidden. Deny always wins over allow. |
Wildcard match: travel.* allows every tool on the travel MCP. Combine with a narrow deny to whitelist most:
policy:
allow:
- travel.*
deny:
- travel.cancel_bookingRun armoriq validate after editing — it catches typos against the real MCP tool list by probing each server.
intent
| Field | Type | Default | Description |
|---|---|---|---|
ttl_seconds | integer | 300 | How long an intent token is valid after get_intent_token. Lower = safer, higher = fewer round-trips. |
require_csrg | boolean | true | Require the Canonical Structured Reasoning Graph — cryptographic proof that the invoked tool matches what the LLM reasoned about. Set false only if you know what you're doing. |
$ENV_VAR substitution
Anywhere a string field appears in the schema, you can use $NAME to reference an environment variable. The SDK substitutes at load time:
identity:
api_key: $ARMORIQ_API_KEY
mcp_servers:
- id: travel
auth:
type: bearer
token: $TRAVEL_MCP_TOKENIf the env var is unset, loading raises ConfigurationException — you'll see "API key is empty. Set ARMORIQ_API_KEY or update identity.api_key."
Mix literal values and substitutions as needed — $ only triggers substitution when it starts a value.
Using the config
Python
from armoriq_sdk import ArmorIQClient
client = ArmorIQClient.from_config("armoriq.yaml")
# now use client as normalfrom_config reads every field above, resolves $ENV_VARs, and configures the client.
TypeScript
TypeScript does not yet ship a fromConfig helper. Parse the YAML manually:
import { readFileSync } from 'node:fs';
import yaml from 'js-yaml';
import { ArmorIQClient } from '@armoriq/sdk';
const cfg = yaml.load(readFileSync('armoriq.yaml', 'utf8')) as any;
// Replace $ENV_VARs
const resolveEnv = (v: string) =>
typeof v === 'string' && v.startsWith('$') ? (process.env[v.slice(1)] ?? v) : v;
const client = new ArmorIQClient({
apiKey: resolveEnv(cfg.identity.api_key),
userId: cfg.identity.user_id,
agentId: cfg.identity.agent_id,
proxyEndpoint: cfg.proxy?.url,
timeout: (cfg.proxy?.timeout ?? 30) * 1000,
});When to use YAML vs code-only
Use the YAML when any of these are true:
- You have more than one agent or environment.
- Your policy is non-trivial (multiple MCPs, specific tool lists).
- You want policy changes to go through code review.
- You deploy from CI.
Skip the YAML when:
- Single service, single environment, single agent.
- Your policy is just "all tools allowed" on one MCP.
- You're prototyping.
Typical cycle
# One-time
armoriq init # scaffold the file
# Every change
edit armoriq.yaml # add/remove tools, tighten policy
armoriq validate # fail early on typos
armoriq register # push to backend, updates MCPAgent + MCPServer + Policy rowsregister is idempotent — safe to run from CI on every merge.
Next steps
TypeScript SDK
The @armoriq/sdk package for Node.js agents. ArmorIQClient, capturePlan / getIntentToken / invoke loop, per-call user scoping, and known parity gaps with the Python SDK.
Multi-org Workflow
Work with multiple ArmorIQ organizations from one account. List orgs, switch scope, pre-select an org at login, and understand the API key lifecycle.