Getting Started — AI Runtime Governor
Real-time governance, compliance, and observability for autonomous AI agents.
Evaluate every tool call before execution. Enforce custom policies. Detect multi-step threats. Stay audit-ready.
AI Runtime Governor is a managed API that sits between your AI agents and the tools they invoke — providing policy enforcement, risk scoring, behavioural fingerprinting, and full audit trails out of the box.
Base URL: https://api.airg.nov-tia.com
Dashboard: https://app.airg.nov-tia.com
Table of Contents
- Quick Start
- Core Concepts
- Authentication & API Keys
- Integrating Your Agent
- Dashboard
- Post-Execution Verification
- Conversation Logging
- Agent Trace Observability
- Real-Time Streaming (SSE)
- Policy Management
- SURGE Credit Governance
- Escalation & Alerting
- Agent Fingerprinting
- Impact Assessment
- Compliance & Regulatory
- API Reference
- Troubleshooting
Quick Start
Get your first governance decision in under 2 minutes.
Step 1: Get your API key
Log in to the dashboard and navigate to the API Keys tab. Copy your key — it starts with airg_.
Step 2: Verify connectivity
curl https://api.airg.nov-tia.com/healthz
# → {"status":"ok"}Step 3: Evaluate your first tool call
curl -s -X POST https://api.airg.nov-tia.com/actions/evaluate \
-H "X-API-Key: airg_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"tool": "shell",
"args": {"command": "rm -rf /"},
"context": {"agent_id": "my-agent"}
}' | jq .Response:
{
"decision": "block",
"risk_score": 95,
"explanation": "Destructive filesystem operation",
"policy_ids": ["shell-dangerous"],
"execution_trace": [...]
}That's it. Your agent now has real-time governance. Every call returns a decision (allow, review, or block), a risk score (0–100), and a full execution trace showing exactly why.
Step 4: Install an SDK (optional)
# Python
pip install airg-client
# TypeScript / JavaScript
npm install @airg/governor-client
# Java (Maven)
<dependency>
<groupId>com.airg</groupId>
<artifactId>airg-client</artifactId>
<version>0.3.4</version>
</dependency>Core Concepts
How It Works
Every tool call your agent makes passes through a multi-layer evaluation pipeline before execution. The pipeline short-circuits on the first block:
Your Agent → POST /actions/evaluate
│
├─ Emergency Stop ← global emergency halt
├─ Agent Quarantine ← per-agent isolation
├─ Tool Poison Detector ← blocklist, typosquat, exfil detection
├─ Injection Firewall ← 93-pattern semantic + regex detection
├─ Indirect Injection ← deep-scan JSON/CSV/HTML data fields
├─ PII Scanner ← 12 entity types, risk boost
├─ Content Moderation ← harmful content classification
├─ Scope Enforcer ← tool whitelist enforcement
├─ Policy Engine ← built-in + custom policies
├─ Risk Analysis ← heuristic scoring + chain detection
├─ Multi-Turn Tracker ← session behavioural analysis
├─ Canary Self-Test ← detector health monitoring
└─ Verification ← post-execution compliance
│
▼
Response {
decision: "allow" | "review" | "block",
risk_score: 0–100,
explanation: "...",
error_code: "TOOL_POISON_BLOCKED" | null,
remediation: "Register this tool via the allowlist API" | null,
policy_ids: ["shell-dangerous"],
chain_pattern: "credential-then-http" | null,
execution_trace: [layer-by-layer detail]
}
│
├─► Audit trail (searchable, exportable)
├─► Real-time SSE stream (dashboard + webhooks)
├─► SURGE receipt (SHA-256 cryptographic attestation)
└─► Escalation engine (review queue + notifications)
Every layer emits a TraceStep with timing, risk contribution, and detail — making every governance decision fully explainable and auditable.
Decisions
| Decision | Meaning | Agent Should |
|---|---|---|
allow | Tool call is safe | Proceed with execution |
review | Needs human review | Queue for approval or skip |
block | Dangerous — rejected | Do NOT execute the tool |
Chain Analysis
The Governor detects multi-step attack patterns by examining session history. When a pattern is detected, the risk score is automatically boosted and the pattern name is stored in the chain_pattern response field.
Detected patterns include credential exfiltration sequences, privilege escalation chains, lateral movement attempts, data staging, scope probing, and other adversarial behaviours. Each pattern applies a dynamic risk boost based on severity.
Chain analysis runs automatically on every evaluation. No configuration required. Detected patterns appear in the Chain Analysis dashboard tab.
Data Persistence
All evaluation logs, policy versions, audit trails, fingerprint profiles, and compliance records are stored in a fully managed PostgreSQL database. Data is encrypted at rest and retained according to your account plan.
Authentication & API Keys
Auth Methods
All protected endpoints accept three authentication methods simultaneously:
| Method | Header / Param | How to Obtain |
|---|---|---|
| JWT Bearer | Authorization: Bearer <token> | POST /auth/login |
| API Key | X-API-Key: airg_<key> | Dashboard API Keys tab, or POST /auth/me/rotate-key |
| Query Param | ?token=<jwt> | For SSE/EventSource (browser can't set headers) |
Getting a Token
# Login → JWT token
TOKEN=$(curl -s -X POST https://api.airg.nov-tia.com/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"your-password"}' | jq -r .access_token)
echo $TOKENGetting an API Key
# Rotate your own API key (self-service)
curl -s -X POST https://api.airg.nov-tia.com/auth/me/rotate-key \
-H "Authorization: Bearer $TOKEN" | jq .
# Returns: {"api_key": "airg_abc123..."}Or use the API Keys tab in the dashboard — it shows your key (masked by default), lets you copy or regenerate it, and provides quick-start code samples.
Role-Based Access Control (RBAC)
| Role | Evaluate | View Logs | Policies | Emergency Stop | Verify | Users | Stream |
|---|---|---|---|---|---|---|---|
admin | ✅ | ✅ | ✅ CRUD | ✅ | ✅ | ✅ CRUD | ✅ |
operator | ✅ | ✅ | Read | ❌ | ✅ | ❌ | ✅ |
auditor | ❌ | ✅ | Read | ❌ | ❌ | ❌ | ✅ |
Module RBAC: SURGE v2 write endpoints (/issue, /checkpoint) and PII scanning require operator+ role. Fingerprint reset (DELETE /fingerprint/agents/:id) requires admin. All module read endpoints are available to any authenticated user.
Creating Users
# As admin, create an operator account
curl -s -X POST https://api.airg.nov-tia.com/auth/users \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"username":"agent-ops","password":"secure-password","role":"operator"}' | jq .Or use the User Management tab in the dashboard.
Account Security
Admin credentials are configured during account provisioning. Contact your organisation's admin or the AI Runtime Governor team to obtain your login credentials.
Tip: After your first login, navigate to the API Keys tab in the dashboard to generate an API key for programmatic access. API keys (airg_… prefix) are the recommended authentication method for agent integrations.
Integrating Your Agent
Option A: SDK (Recommended)
Three official SDKs — authenticate with X-API-Key, throw on block decisions.
Python · pip install airg-client
import governor_client
from governor_client import evaluate_action, GovernorBlockedError
governor_client.GOVERNOR_URL = "https://api.airg.nov-tia.com"
governor_client.GOVERNOR_API_KEY = "airg_your_key_here"
try:
decision = evaluate_action("shell", {"command": "ls -la"}, context={
"agent_id": "my-agent",
"session_id": "session-123",
"allowed_tools": ["shell", "http_request", "file_read"],
})
print(f"{decision['decision']} — risk {decision['risk_score']}")
except GovernorBlockedError as e:
print(f"Blocked: {e}")
# Do NOT execute the toolTypeScript / JavaScript · npm install @airg/governor-client
import { GovernorClient, GovernorBlockedError } from "@airg/governor-client";
const gov = new GovernorClient({
baseUrl: "https://api.airg.nov-tia.com",
apiKey: "airg_your_key_here",
});
try {
const d = await gov.evaluate("shell", { command: "ls -la" }, {
agent_id: "my-agent",
allowed_tools: ["shell", "http_request"],
});
console.log(`${d.decision} — risk ${d.risk_score}`);
} catch (err) {
if (err instanceof GovernorBlockedError) {
console.error("Blocked:", err.message);
}
}Java · com.airg:airg-client:0.3.4
GovernorClient gov = new GovernorClient.Builder()
.baseUrl("https://api.airg.nov-tia.com")
.apiKey("airg_your_key_here")
.build();
try {
GovernorDecision d = gov.evaluate("shell", Map.of("command", "ls -la"));
System.out.println(d.getDecision() + " — risk " + d.getRiskScore());
} catch (GovernorBlockedError e) {
System.err.println("Blocked: " + e.getMessage());
}Environment Variables (all SDKs)
export GOVERNOR_URL=https://api.airg.nov-tia.com
export GOVERNOR_API_KEY=airg_your_key_hereAll SDKs read these automatically when explicit configuration is not provided.
Hold / Review Mode (Python SDK)
When the Governor returns a review decision, the Python SDK supports a hold mode that long-polls for human approval:
from governor_client import (
evaluate_action,
GovernorBlockedError,
GovernorReviewRejectedError,
GovernorReviewExpiredError,
)
try:
decision = evaluate_action(
"deploy_contract",
{"contract": "TokenSwap.sol"},
context={"agent_id": "defi-agent"},
review_mode="hold", # wait for human decision
hold_timeout=120, # max 120s
)
# If we reach here, the action was approved
print(f"Approved by {decision.get('review_resolved_by')}")
except GovernorBlockedError:
print("Blocked by policy")
except GovernorReviewRejectedError as e:
print(f"Human rejected: {e}")
except GovernorReviewExpiredError as e:
print(f"Review timed out: {e}")review_mode | Behavior |
|---|---|
"proceed" (default) | Return immediately — caller inspects decision field |
"hold" | Long-poll POST /escalation/queue/{id}/hold until human approves, rejects, or timeout |
Option B: Direct HTTP
No SDK needed — just POST /actions/evaluate with JSON:
curl -s -X POST https://api.airg.nov-tia.com/actions/evaluate \
-H "X-API-Key: airg_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"tool": "http_request",
"args": {
"method": "POST",
"url": "https://api.example.com/data",
"body": {"query": "SELECT * FROM users"}
},
"context": {
"agent_id": "data-pipeline-agent",
"session_id": "run-456",
"allowed_tools": ["http_request", "file_read"]
}
}' | jq .Integration Pattern
The standard integration pattern:
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
│ Your Agent │─────►│ Governor API │─────►│ Real World │
│ │ │ /evaluate │ │ │
│ 1. Decide │ │ → allow/block │ │ Tool runs │
│ 2. Ask Gov │◄─────│ │ │ only if │
│ 3. Execute │ │ /verify │ │ allowed │
│ if allow │─────►│ → compliant/ │ │ │
│ 4. Verify │ │ violation │ │ │
└──────────────┘ └──────────────────┘ └──────────────┘
# Full lifecycle example (Python)
import governor_client as gc
gc.GOVERNOR_URL = "https://api.airg.nov-tia.com" # production endpoint
gc.GOVERNOR_API_KEY = "airg_..." # your API key from the dashboard
# Step 1: Pre-execution governance
decision = gc.evaluate_action("file_write", {
"path": "/app/config.py",
"content": "DEBUG = True"
}, context={"agent_id": "my-agent"})
if decision["decision"] == "block":
print("Blocked — skipping execution")
elif decision["decision"] == "allow":
# Step 2: Execute the tool
result = actually_write_file("/app/config.py", "DEBUG = True")
# Step 3: Post-execution verification (optional but recommended)
import httpx
verify_resp = httpx.post(f"{gc.GOVERNOR_URL}/actions/verify", json={
"action_id": decision["action_id"],
"tool": "file_write",
"result": {"status": "success", "output": "Wrote 1 line"},
"context": {"agent_id": "my-agent"}
}, headers={"X-API-Key": gc.GOVERNOR_API_KEY})
print(verify_resp.json()["verdict"]) # "compliant" or "violation"Context Fields
The context object controls scope enforcement and tracing:
| Field | Type | Purpose |
|---|---|---|
agent_id | string | Recommended — identifies the agent for chain analysis and filtering |
session_id | string | Groups related tool calls into a session for chain analysis |
allowed_tools | string[] | If set, blocks any tool not in this list |
user_id | string | Associate evaluations with a human user |
channel | string | Communication channel (slack, web, etc.) |
trace_id | string | Links evaluation to an agent trace tree |
span_id | string | Parent span for governance span injection |
parent_action_id | integer/string | Links a child specialist action to the parent delegation audit row |
parent_trace_id | string | Links a child action to the parent delegation trace |
parent_span_id | string | Links a child action to the parent delegation span |
delegated_by | string | Supervisor/source agent that delegated the child action |
conversation_id | string | Links to a conversation for conversation logging |
turn_id | integer | Turn number within a conversation |
prompt | string | (opt-in) The agent's reasoning / prompt — encrypted at rest |
Enterprise Context Isolation
AIRG keeps the public agent_id and session_id exactly as you send them, but internally scopes runtime memory by organization. That means two organizations can both use names like support-agent and sess-1 without sharing chain history, multi-turn state, budget counters, fingerprint baselines, adversary scores, or quarantine state.
For best results, always send stable agent_id and session_id values. The organization boundary comes from your authenticated JWT or API key, not from a client-controlled context field.
Multi-Hop Delegation
For supervisor -> specialist -> tool workflows, send the parent delegation through /actions/evaluate, then include the returned action_id in the specialist's child action as parent_action_id.
# Parent delegation
curl -s -X POST https://api.airg.nov-tia.com/actions/evaluate \
-H "X-API-Key: airg_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"tool": "delegate_to_specialist",
"args": {
"target_agent_id": "database-specialist",
"task": "Count active users for the weekly operations report.",
"allowed_tools": ["execute_sql"]
},
"context": {
"agent_id": "supervisor-agent",
"session_id": "ops-weekly",
"trace_id": "trace-ops-001",
"span_id": "supervisor-delegation",
"allowed_tools": ["delegate_to_specialist"]
}
}' | jq .
# Child specialist action
curl -s -X POST https://api.airg.nov-tia.com/actions/evaluate \
-H "X-API-Key: airg_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"tool": "execute_sql",
"args": {"query": "SELECT count(*) FROM users WHERE active = true"},
"context": {
"agent_id": "database-specialist",
"parent_action_id": 12345,
"allowed_tools": ["execute_sql"]
}
}' | jq .AIRG blocks missing parent references, wrong target agents, explicitly blocked child tools, and child tools outside the delegated tool set. Ambiguous high-risk child actions are sent to review. See Multi-Hop Delegation Governance.
Controlled Agent Mesh
For peer-to-peer or multi-agent systems, register participating agents and peer policies before using tool: "call_agent". AIRG blocks unregistered source agents, unregistered target agents, inactive agents, and unapproved peer calls by default.
# Register two agents
curl -s -X POST https://api.airg.nov-tia.com/agent-mesh/agents \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"agent_id":"support-agent","agent_type":"support","allowed_peers":["billing-agent"]}' | jq .
curl -s -X POST https://api.airg.nov-tia.com/agent-mesh/agents \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"agent_id":"billing-agent","agent_type":"billing"}' | jq .
# Evaluate an agent-to-agent call
curl -s -X POST https://api.airg.nov-tia.com/actions/evaluate \
-H "X-API-Key: airg_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"tool": "call_agent",
"args": {
"target_agent_id": "billing-agent",
"requested_action": "lookup_invoice",
"message": "Please check invoice INV-1024."
},
"context": {
"agent_id": "support-agent",
"session_id": "case-1024",
"allowed_tools": ["call_agent"]
}
}' | jq .Use mesh policies when the relationship needs action-level controls, such as allowing lookup_invoice while blocking issue_refund. See Controlled Agent Mesh Governance.
Dashboard
The dashboard has 16 tabs, each accessible based on your role:
| Tab | Icon | What It Shows |
|---|---|---|
| Dashboard | 📊 | Summary: total actions, allow/review/block counts, risk distribution, live feed |
| Agent Demo | 🤖 | Run the 17-step demo agent directly from the browser |
| Action Tester | ⚡ | Manual tool evaluation form — test any tool /args / context |
| Policies | 📜 | CRUD editor for dynamic policies with active/inactive toggle |
| Review Queue | 👁 | Pending escalation events — approve / reject actions |
| SURGE | 💎 | SURGE receipts, fee tiers, wallet balances, policy staking |
| Audit Log | 🔍 | Full action history with search/filter, SSE live merge (LIVE badge) |
| Conversations | 💬 | Agent conversation turns + unified timeline |
| Verification | ✅ | Post-execution verification logs |
| Drift | 📈 | Per-agent drift detection — deviation from behavioural baseline |
| Chain Analysis | 🔗 | Detected multi-step attack patterns (dynamic bar chart) |
| Traces | 🌲 | Agent trace explorer — span trees, governance correlation |
| Topology | 🗺 | Agent-to-tool interaction graph |
| API Keys | 🔑 | View / copy / regenerate your API key + code samples |
| Settings | ⚙️ | Kill switch toggle, system configuration |
| Users | 👥 | User management — create operators and auditors |
Demo Mode vs Live Mode
- Demo Mode: Fully self-contained — uses simulated data to showcase all 16 tabs.
- Live Mode: Connects to the production backend at
https://api.airg.nov-tia.com. All data is real.
Post-Execution Verification
The verification engine inspects tool results after execution — closing the gap between allowing an intent and validating the outcome.
Submit a verification
curl -s -X POST https://api.airg.nov-tia.com/actions/verify \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action_id": 42,
"tool": "file_write",
"result": {
"status": "success",
"output": "Wrote 150 lines to /etc/passwd",
"diff": "- root:x:0:0\n+ root:x:0:0:hacked"
},
"context": {
"agent_id": "my-agent",
"trace_id": "trace-abc"
}
}' | jq .Verification Checks
The verification engine runs multiple automated checks against tool outputs including credential scanning, destructive output detection, scope compliance validation, anomaly detection, policy re-verification, and behavioural drift analysis. Each check contributes to a final verdict.
Verdict
| Verdict | Meaning |
|---|---|
compliant | All checks passed |
suspicious | Some checks flagged concerns but below violation threshold |
violation | One or more critical failures — auto-escalated |
List verifications
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/actions/verifications?verdict=violation" | jq .Conversation Logging
Opt-in capture of agent reasoning and prompts. All content is encrypted at rest.
Include conversation context in evaluations
decision = evaluate_action("shell", {"command": "ls"}, context={
"agent_id": "my-agent",
"conversation_id": "conv-abc-123",
"turn_id": 1,
"prompt": "User asked me to list directory contents"
})Batch ingest conversation turns
curl -s -X POST https://api.airg.nov-tia.com/conversations/turns/batch \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '[
{
"conversation_id": "conv-abc-123",
"turn_number": 1,
"role": "user",
"content": "List the files in /tmp"
},
{
"conversation_id": "conv-abc-123",
"turn_number": 2,
"role": "assistant",
"content": "I will use the shell tool to list the files."
}
]' | jq .View conversations
# List all conversations
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/conversations" | jq .
# Get unified timeline (turns + governance actions interleaved)
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/conversations/conv-abc-123/timeline" | jq .Agent Trace Observability
Capture the full lifecycle of every agent task — LLM reasoning, tool invocations, retrieval steps, and governance decisions as an OpenTelemetry-inspired span tree.
Ingest trace spans
curl -s -X POST https://api.airg.nov-tia.com/traces/ingest \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"spans": [
{
"trace_id": "trace-task-001",
"span_id": "root-span",
"name": "Research Market Data",
"kind": "agent",
"start_time": "2026-02-28T12:00:00Z",
"end_time": "2026-02-28T12:00:05Z"
},
{
"trace_id": "trace-task-001",
"span_id": "llm-call-1",
"parent_span_id": "root-span",
"name": "GPT-4 reasoning",
"kind": "llm",
"start_time": "2026-02-28T12:00:01Z",
"end_time": "2026-02-28T12:00:03Z"
}
]
}' | jq .Zero-config governance correlation
Pass trace_id and span_id in the evaluation context — the Governor auto-creates a governance span as a child:
decision = evaluate_action("shell", {"command": "ls"}, context={
"agent_id": "my-agent",
"trace_id": "trace-task-001",
"span_id": "llm-call-1",
})
# → A governance span is auto-created as a child of llm-call-1View traces
# List all traces
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/traces" | jq .
# Full trace with span tree
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/traces/trace-task-001" | jq .Span Kinds
| Kind | Dashboard Color | What It Represents |
|---|---|---|
agent | Red | Root agent task / orchestration |
llm | Violet | LLM inference call |
tool | Amber | Tool invocation |
governance | Red | Governor evaluation (auto-created) |
retrieval | Cyan | RAG / vector search |
chain | Green | Multi-step chain execution |
custom | Gray | Anything else |
Real-Time Streaming (SSE)
The Governor pushes every governance decision to connected clients via Server-Sent Events.
Connect to the stream
# Terminal
curl -N -H "Authorization: Bearer $TOKEN" \
https://api.airg.nov-tia.com/actions/stream
# Or with API key
curl -N -H "X-API-Key: airg_your_key" \
https://api.airg.nov-tia.com/actions/streamFrom JavaScript
const es = new EventSource(
"https://api.airg.nov-tia.com/actions/stream?token=" + jwt
);
es.addEventListener("action_evaluated", (e) => {
const { tool, decision, risk_score } = JSON.parse(e.data);
console.log(`${tool}: ${decision} (risk ${risk_score})`);
});Events
| Event | When |
|---|---|
connected | On initial connection |
action_evaluated | After every POST /actions/evaluate |
:heartbeat | Every 15 seconds (keep-alive) |
Check status
curl https://api.airg.nov-tia.com/actions/stream/status
# → {"active_subscribers": 2, "heartbeat_interval_seconds": 15}The dashboard auto-connects to SSE in Live Mode. A LIVE badge appears in the Audit Log + Dashboard tabs when streaming is active.
Policy Management
Policies define how AIRG should treat a tool call before the tool executes. A policy can allow, send to review, or block based on the tool name, URL, arguments, organization settings, and optional agent scope.
The easiest path for non-technical users is the dashboard:
- Open Platform → Policies.
- Choose the policy scope: All agents or a specific agent.
- Describe what should be controlled.
- Set the match conditions, such as tool name, URL regex, or args regex.
- Use the severity rubric sliders, then save.
- Test the policy in Simulation before relying on it in production.
Technical users can do the same through the API.
Built-in Policies
Multiple governance policies are pre-configured and active on every account. Example:
- policy_id: shell-dangerous
description: "Block destructive shell commands"
tool: "shell"
severity: critical
action: block
args_regex: "(rm\\s+-rf|mkfs|dd\\s+if=|shutdown|reboot)"Built-in policies are system-level guardrails. They apply to every organization and cannot be loosened by organization or agent policies. Custom policies add your own controls on top.
Policy Scope
AIRG supports two custom policy scopes:
| Scope | How to set it | When it applies |
|---|---|---|
| Organization-wide | Omit agent_id or set it to null | Every agent in the authenticated user's organization |
| Agent-specific | Set agent_id to an agent ID | Only evaluations whose context.agent_id or top-level agent_id matches |
Agent search and policy selection in the dashboard are organization-scoped. Users only see agents that belong to their organization.
When an action is evaluated, AIRG loads:
- System built-in policies.
- Active custom policies for the caller's organization.
- Organization-wide custom policies where
agent_idis empty. - Agent-specific custom policies where
agent_idmatches the evaluated action.
Example:
{
"tool": "send_email",
"args": {"to": "external@example.com", "body": "Patient SSN: 987-65-4321"},
"context": {
"agent_id": "healthcare-support-agent",
"session_id": "case-123"
}
}For that call, an agent-scoped policy with "agent_id": "healthcare-support-agent" applies. A policy scoped to "agent_id": "finance-agent" does not.
Governance Mode
Each organization has a governance mode:
| Mode | Behavior |
|---|---|
allow-by-default | If no policy or detector blocks/reviews the call, the call is allowed. |
deny-by-default | Only explicitly allowed tools can run. Use allowlist policies for approved tools. |
audit-only | Evaluations are logged and scored, but policy blocks are treated as audit signals instead of enforcement. |
Set it in Platform → Governance Mode or by API:
curl -s -X PATCH https://api.airg.nov-tia.com/policies/governance-mode \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"governance_mode": "deny-by-default"}' | jq .For deny-by-default rollout, create an allowlist:
curl -s -X POST https://api.airg.nov-tia.com/policies/allowlist \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tools": ["search_kb", "summarize", "send_email"],
"agent_id": "support-agent-1",
"note": "Approved tools for customer support workflow"
}' | jq .Omit agent_id to allow those tools for the whole organization.
Severity Scoring
Policy severity is a 0-100 score used for risk scoring, escalation, and review priority. You can either provide severity directly or let AIRG calculate it from the rubric:
severity =
blast_radius × weight_blast_radius
+ reversibility × weight_reversibility
+ data_sensitivity × weight_data_sensitivity
Default organization weights:
| Dimension | Default weight | What it means |
|---|---|---|
blast_radius | 0.40 | How widely the action can affect systems, users, money, or data |
reversibility | 0.35 | How hard it is to undo the action |
data_sensitivity | 0.25 | Whether the action touches PII, credentials, regulated, or confidential data |
Admins can change these weights in Platform → Organization or Platform → Policies → Severity Weights. The three weights must sum to 1.0.
curl -s -X PUT https://api.airg.nov-tia.com/policies/severity-weights \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"blast_radius": 0.40,
"reversibility": 0.30,
"data_sensitivity": 0.30
}' | jq .Preview a score before creating a policy:
curl -s -X POST https://api.airg.nov-tia.com/policies/severity/calculate \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"blast_radius": 90,
"reversibility": 70,
"data_sensitivity": 100,
"action": "block"
}' | jq .Manual Severity Overrides
Manual scoring is intentionally controlled. AIRG validates that the selected action matches the severity range:
| Action | Valid severity range |
|---|---|
allow | 0-49 |
review | 20-89 |
block | 50-100 |
If you provide rubric dimensions and a manual severity, the manual value must match the calculated value. To intentionally override the calculated score, include an override_justification of at least 20 characters. The override is stored in the policy record, version history, and audit trail.
Use overrides sparingly. They are meant for documented business exceptions, not normal policy creation.
Dynamic Policies (API)
Create, update, toggle, and delete policies at runtime:
# Create a policy
curl -s -X POST https://api.airg.nov-tia.com/policies \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"policy_id": "block-external-uploads",
"description": "Block HTTP uploads to external domains",
"severity": 85,
"action": "block",
"match_json": {
"tool": "http_request",
"url_regex": "^https?://(?!internal\\.company\\.com)"
},
"agent_id": null
}' | jq .
# Create an agent-specific policy using rubric scoring
curl -s -X POST https://api.airg.nov-tia.com/policies \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"policy_id": "support-review-pii-email",
"description": "Review support-agent emails that include sensitive identifiers",
"blast_radius": 70,
"reversibility": 60,
"data_sensitivity": 95,
"action": "review",
"match_json": {
"tool": "send_email",
"args_regex": "(SSN|passport|credit card|patient)"
},
"agent_id": "support-agent-1"
}' | jq .
# Toggle a policy on/off
curl -s -X PATCH https://api.airg.nov-tia.com/policies/block-external-uploads/toggle \
-H "Authorization: Bearer $TOKEN" | jq .
# Partial update (only change description and severity)
curl -s -X PATCH https://api.airg.nov-tia.com/policies/block-external-uploads \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"description": "Updated description", "severity": 95}' | jq .Policy Matching Fields
Custom policy match conditions live inside match_json:
| Field | Purpose |
|---|---|
tool | Exact tool name to match, such as shell, send_email, or http_request |
url_regex | Optional regex against URL-like fields |
args_regex | Optional regex against serialized tool arguments |
agent_id | Optional legacy match constraint; prefer the top-level agent_id scope for new policies |
Regex patterns are validated before save and capped in length to reduce ReDoS risk.
Policy Versioning
Every edit creates an immutable PolicyVersion snapshot + PolicyAuditLog with before/after JSON diffs. You can restore any previous version:
# List versions
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/policies/block-external-uploads/versions" | jq .
# Restore a version
curl -s -X POST \
"https://api.airg.nov-tia.com/policies/block-external-uploads/versions/2/restore" \
-H "Authorization: Bearer $TOKEN" | jq .Policy Cache
Policies are cached with a 10-second TTL. After creating or updating a policy, allow up to 10 seconds for the change to take effect across all evaluations.
SURGE Credit Governance
Economically-backed governance layer — all data DB-persisted.
| Feature | Description |
|---|---|
| Governance Receipts | SHA-256 signed receipt for every evaluation |
| Tiered Fees | 0.001 (standard) → 0.005 (elevated) → 0.010 (high) → 0.025 (critical) $SURGE |
| Virtual Wallets | Auto-provisioned on first call (100 SURGE), returns 402 when empty |
| Policy Staking | Operators stake $SURGE on policies to signal confidence |
Fee Tiers
| Risk Score | Fee |
|---|---|
| 0–39 | 0.001 $SURGE |
| 40–69 | 0.005 $SURGE |
| 70–89 | 0.010 $SURGE |
| 90–100 | 0.025 $SURGE |
# Check SURGE status
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/surge/status" | jq .
# List receipts
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/surge/receipts" | jq .Escalation & Alerting
Automated escalation engine with 5 notification channels:
| Channel | Integration |
|---|---|
| SMTP (any provider) | |
| Slack | Webhook URL or Bot API token |
| Meta Cloud API | |
| Jira | Issue creation via REST API |
| Webhook | Generic HTTP POST |
Automatic Emergency Stop (Per-Agent Quarantine)
The escalation engine monitors for sustained high-risk activity and automatically quarantines the offending agent when thresholds are breached. Unlike the global emergency stop, quarantine only blocks the specific agent — all other agents continue operating normally. Thresholds are configurable per-agent via the API or the dashboard’s Security tab.
| Threshold | Default | Description |
|---|---|---|
auto_ks_block_threshold | 5 | Consecutive blocks before auto-quarantine triggers |
auto_ks_risk_threshold | 80 | Average risk score that triggers auto-quarantine |
review_risk_threshold | 40 | Risk score that sends action to review queue |
review_expiry_minutes | 30 | Minutes before pending reviews auto-expire |
Quarantined agents can be released via POST /admin/unquarantine/{agent_id} or from the agent’s profile page in the dashboard. In multi-tenant deployments, quarantine is organization-scoped: quarantining support-agent in one organization does not affect another organization that uses the same agent name.
Configure notification channels
# Create a Slack channel
curl -s -X POST https://api.airg.nov-tia.com/notifications/channels \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "security-alerts",
"channel_type": "slack",
"config_json": {
"webhook_url": "https://hooks.slack.com/services/T.../B.../..."
},
"is_active": true
}' | jq .View escalation events
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/escalation/events?status=pending" | jq .
# Approve an event
curl -s -X PUT https://api.airg.nov-tia.com/escalation/events/42/approve \
-H "Authorization: Bearer $TOKEN" | jq .Agent Fingerprinting
Behavioural fingerprinting automatically tracks each agent's usage patterns and detects deviations from established baselines.
The fingerprint engine monitors 6 deviation dimensions:
| Check | What It Detects |
|---|---|
| Tool distribution | Agent using tools outside its normal pattern |
| Risk score drift | Average risk shifting higher than baseline |
| Action frequency | Unusual spike or drop in evaluation volume |
| Block rate | Abnormal increase in blocked actions |
| Session pattern | Changes in session duration/length |
| Temporal pattern | Activity outside normal time windows |
Retrieve fingerprint data via the API:
# List all fingerprinted agents
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/fingerprint/agents" | jq .Impact Assessment
Built-in AI impact assessment engine aligned with international governance frameworks.
Supported Frameworks
| Framework | Coverage |
|---|---|
| ISO 42001 | AI management system requirements |
| NIST AI RMF | Risk management framework for AI systems |
| EU AI Act | European AI regulatory compliance |
Endpoints
# Assess a specific action
curl -s -X POST https://api.airg.nov-tia.com/impact/assess \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"tool": "deploy_contract", "args": {}, "context": {"agent_id": "my-agent"}}' | jq .
# Get impact assessment for an agent
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/impact/assess/agent/my-agent" | jq .
# List all assessed agents
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/impact/agents" | jq .Compliance & Regulatory
Nine compliance modules are included with every account:
| Module | What It Does |
|---|---|
| PII Scanner | Detects PII (emails, SSNs, phone numbers) in tool arguments and outputs |
| Injection Detector | 93-pattern semantic + regex injection detection (17 languages) |
| Indirect Injection Scanner | Deep-scans structured data (JSON fields, CSV cells, HTML comments) for hidden instructions embedded in tool args or retrieved data |
| Tool Poison Detector | Blocks malicious/typosquatted tool names, exfiltration URLs, and dangerous commands in arguments |
| Multi-Turn Tracker | Session-level behavioural analysis — detects injection accumulation, privilege probing, recon-then-exploit, and sudden shift patterns across conversation turns |
| Canary Self-Test | Continuously validates injection detector health with 5 synthetic canary patterns; applies global risk boost when detection degrades |
| Budget Enforcer | Per-agent budget and quota enforcement |
| Metrics | Prometheus-compatible /metrics endpoint for your monitoring stack |
| Compliance Exporter | Generate compliance reports for auditing and regulatory submissions |
Agent mesh governance is built into the core evaluator rather than a separate module. It governs call_agent style tools using the org-scoped agent registry and mesh policies.
All modules run automatically in the evaluation pipeline. Modules can be individually enabled/disabled via environment variables:
| Environment Variable | Default | Purpose |
|---|---|---|
INDIRECT_INJECTION_ENABLED | true | Toggle indirect injection scanning |
TOOL_POISON_DETECTOR_ENABLED | true | Toggle tool poison detection |
TOOL_POISON_BLOCKED_TOOLS | "" | Comma-separated list of explicitly blocked tool names |
MULTI_TURN_TRACKER_ENABLED | true | Toggle multi-turn session tracking |
MULTI_TURN_ACCUMULATION_THRESHOLD | 0.15 | Avg injection similarity that triggers accumulation alert |
MULTI_TURN_SESSION_TTL | 3600 | Session memory window in seconds |
GOVERNOR_CANARY_ENABLED | true | Toggle canary self-test system |
GOVERNOR_CANARY_INTERVAL_SECONDS | 600 | How often canaries run (default: 10 minutes) |
GOVERNOR_CANARY_RISK_BOOST_PER_FAILURE | 10 | Risk boost added per failed canary (max 5 × this) |
Canary operations are available to authenticated operators and admins:
# View live detector health
curl -s -H "Authorization: Bearer $TOKEN" \
https://api.airg.nov-tia.com/admin/canary/status | jq .
# Run an immediate self-test before a release or during incident response
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
https://api.airg.nov-tia.com/admin/canary/run | jq .Error Codes
When the Governor blocks an action, the response includes a machine-readable error_code and human-readable remediation field:
| Error Code | Trigger | Remediation |
|---|---|---|
KILL_SWITCH_ACTIVE | Global emergency stop enabled | Contact your administrator to resume operations |
AGENT_QUARANTINED | Per-agent quarantine | Review agent behaviour and remove quarantine via admin API |
TOOL_POISON_BLOCKED | Blocked/typosquatted tool or dangerous args | Register this tool via the allowlist API or remove dangerous patterns from arguments |
INJECTION_DETECTED | Prompt injection firewall triggered | Sanitize input to remove injection patterns |
INDIRECT_INJECTION_DETECTED | Hidden instructions in structured data | Sanitize data fields before passing to agent — remove embedded instructions from JSON/CSV/HTML |
CONTENT_MODERATION_BLOCKED | Harmful content detected | Remove flagged content categories from the request |
SCOPE_VIOLATION | Tool not in allowed_tools whitelist | Add the tool to the allowed_tools list in context |
POLICY_BLOCKED | Policy engine matched a blocking rule | Review matched policy_ids and adjust agent behaviour or request a policy exception |
MULTI_TURN_ESCALATION | Session-level threat pattern detected | Clear session context or review the conversation history for adversarial patterns |
Regulatory Clauses
The Governor includes regulatory clause mappings for three frameworks:
# List all clauses
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/compliance/clauses" | jq .
# Filter by framework
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.airg.nov-tia.com/compliance/clauses/eu_ai_act" | jq .
# Seed clauses (first time)
curl -s -X POST https://api.airg.nov-tia.com/compliance/clauses/seed \
-H "Authorization: Bearer $TOKEN" | jq .Available frameworks: eu_ai_act, nist_ai_rmf, owasp_llm_top10.
Drift Detection
Drift detection compares an agent's current behaviour against its historical baseline to identify behavioural changes.
The verification engine includes drift-detection as one of its checks — it compares:
- Tool usage distribution — is the agent calling different tools than usual?
- Risk score trend — is the average risk score climbing?
- Action outcome pattern — is the block/review ratio changing?
Drift scores are computed per-agent and displayed in the Drift dashboard tab as trend charts. High drift scores may indicate compromised agent behaviour or configuration changes.
API Reference
Base URL
https://api.airg.nov-tia.com
Authentication
All API calls require one of:
X-API-Key: airg_your_keyheader (recommended)Authorization: Bearer <jwt_token>header?token=<jwt>query parameter (for SSE/EventSource)
Key Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /healthz | Health check |
POST | /auth/login | Authenticate and receive JWT |
POST | /auth/me/rotate-key | Generate / rotate API key |
POST | /actions/evaluate | Evaluate a tool call (core endpoint) |
GET | /actions | List evaluation history |
POST | /actions/verify | Post-execution verification |
GET | /actions/stream | Real-time SSE event stream |
GET/POST | /agent-mesh/agents | List or register governed mesh agents |
PATCH | /agent-mesh/agents/{agent_id} | Update mesh agent status, peers, and metadata |
GET/POST | /agent-mesh/policies | List or create agent-to-agent mesh policies |
GET/POST | /policies | List / create governance policies |
PATCH | /policies/:id | Update a policy |
PATCH | /policies/:id/toggle | Enable / disable a policy |
GET | /policies/:id/versions | Policy version history |
POST | /policies/simulate | Test a draft policy against a sample action |
GET | /policies/severity-weights | Get effective organization severity weights |
PUT | /policies/severity-weights | Update organization severity weights |
POST | /policies/severity/calculate | Preview rubric-derived severity |
GET/PATCH | /policies/governance-mode | Read or update organization governance mode |
POST | /policies/allowlist | Create allow policies for deny-by-default mode |
POST | /conversations/turns/batch | Batch ingest conversation turns |
GET | /conversations | List conversations |
GET | /conversations/:id/timeline | Unified conversation timeline |
POST | /traces/ingest | Ingest agent trace spans |
GET | /traces | List traces |
GET | /traces/:trace_id | Full trace with span tree |
GET | /surge/status | SURGE wallet balance and fee status |
GET | /surge/receipts | Governance receipts |
GET | /escalation/events | Escalation review queue |
PUT | /escalation/events/:id/approve | Approve an escalation |
POST | /notifications/channels | Create notification channel |
GET | /fingerprint/agents | Agent fingerprint profiles |
POST | /impact/assess | Run impact assessment |
GET | /compliance/clauses | Regulatory compliance clauses |
GET | /summary/overview | Governance summary statistics |
GET | /admin/status | Emergency stop status |
POST | /admin/kill | Engage global emergency stop |
POST | /admin/resume | Release global emergency stop |
GET | /admin/canary/status | View detector canary self-test health |
POST | /admin/canary/run | Run canary self-test immediately |
POST | /admin/quarantine/{agent_id} | Quarantine a specific agent |
POST | /admin/unquarantine/{agent_id} | Release agent quarantine |
GET | /admin/quarantine/{agent_id} | Check agent quarantine status |
Rate Limits
| Endpoint | Limit |
|---|---|
POST /auth/login | 5 requests / minute |
POST /actions/evaluate | 120 requests / minute |
| All other endpoints | Fair use |
SDKs
| Language | Package | Install |
|---|---|---|
| Python | airg-client | pip install airg-client |
| TypeScript/JS | @airg/governor-client | npm install @airg/governor-client |
| Java | com.airg:airg-client | GitHub Packages 0.3.4 |
All SDKs auto-read GOVERNOR_URL and GOVERNOR_API_KEY from environment variables.
Troubleshooting
| Problem | Solution |
|---|---|
| 401 Unauthorized | Token expired (8-hour TTL). Re-authenticate via POST /auth/login or use an API key instead. |
| 403 Forbidden | Your account role lacks permission. Contact your admin to update your role. |
| Policy changes not visible | Policy cache refreshes every 10 seconds. Wait briefly and retry. |
| Kill switch won't release | curl -X POST https://api.airg.nov-tia.com/admin/resume -H "Authorization: Bearer $TOKEN" |
| All evaluations return "block" | Kill switch may be engaged. Check at GET /admin/status and resume if needed. |
| SSE stream disconnects | 15s heartbeat keeps connections alive. Check proxy/firewall timeouts. Dashboard auto-reconnects. |
| CORS errors in browser | Contact support to add your domain to the allowed origins list. |
| SDK connection timeout | Verify GOVERNOR_URL is https://api.airg.nov-tia.com and outbound HTTPS is allowed. |
Further Reading
| Resource | Description |
|---|---|
| API Overview | Full feature comparison and API reference |
| Architecture | System architecture and request lifecycle |
| SDK Reference | Multi-language SDK reference (Python, TypeScript, Java) |
| Governance Audit | Compliance coverage audit report |
| Recent Enterprise Implementation Summary | Recent gateway, canary, context isolation, mesh, and delegation hardening work |
Need help? Open an issue on GitHub or reach out to the AI Runtime Governor team.
License: MIT — Copyright © 2026 Sovereign AI Lab