Forge Orbital

Guide

How to Add Approval Gates to an AI Agent

A practical pattern for AI agent guardrails: make the agent pause on risky actions (payments, refunds, procurement), enforce spending limits, and wait for a person, with working code and an MCP option.

Forge Orbital is built for enterprise and federal AI accountability. Agent Gate is the developer on-ramp to the same engine, so you can start small and grow into the platform.

An AI agent that can only chat is low risk. An AI agent that can issue a refund, send a payment, approve a vendor, or place an order is a different animal, because a single bad call executes at machine speed and you tend to find out afterward. An approval gate is how you keep the speed on the safe actions while forcing the consequential ones to stop and wait for a person.

This guide covers the pattern that actually holds: separate the agent proposing an action from the system executing it, put a deterministic policy check in between, and record every decision. At the end there is a short, working example using the open source forge-agent-gate package, plus an MCP option for agents that call tools.

What an approval gate actually is

An approval gate is a checkpoint that sits between your agent and the system that carries out the action. The agent does not act directly. It proposes an action, the gate evaluates that action against a policy you set, and only then does anything happen. Every gate resolves to one of three outcomes:

The escalate outcome is the approval gate in the strict sense: the agent keeps working, but the risky action pauses until a person signs off. Allow and block are the two ends that make the pause meaningful.

Why a system prompt is not an approval gate

The most common mistake is to write "always ask before spending more than $500" into the system prompt and call it a control. A prompt is a request, not a boundary. The model can ignore it, misread it, or be talked out of it by a prompt injection, and when that happens the action still fires. A real approval gate lives outside the model, runs deterministically, and checks the action before it executes, so a confused or compromised agent cannot exceed the limits you set. If the enforcement can be argued with, it is not enforcement.

Decide which actions need a gate

Gating every action would grind the agent to a halt and train your reviewers to rubber-stamp. The useful pattern is tiered by risk, so only a small share of actions ever pause, usually the irreversible, expensive, or externally visible ones:

Start with the single action that would be painful to unwind, and gate that one first. You can widen the net later.

How to add an approval gate, step by step

1. Pick one action and one rule

Name the action the agent should never take alone, and the rule it must not break. A refund over a ceiling, a payment to a new payee, a purchase above a budget code, a trade above a size. One agent, one action, one rule is enough to start.

2. Write the policy as data, not prose

Move the rule out of the prompt and into a policy object you control. With forge-agent-gate this is a signed mandate with fields like amount caps, counterparty allowlists, daily totals, approval thresholds, and allowed hours. Because it is data, the check is deterministic and testable rather than a matter of the model's mood.

3. Check the action before it executes

Between the agent choosing an action and your code carrying it out, call the gate and branch on the result.

npm i forge-agent-gate
import { generic, presets } from "forge-agent-gate";

// The policy is data you sign once, not a line in a prompt.
// The payments preset caps each transfer and sends new payees to a human.
const mandate = presets.paymentsPresetMandate({ maxSingleTransferUsd: 5000 });

// The action your agent chose, checked before it runs.
const action = {
  actionType: "transfer",
  amountUsd: 1200,
  counterparty: "northwind-llc",
};

const decision = generic.enforceAction({
  mandate,
  action,
  activity: { dailyTotalUsd: 0, knownCounterparties: ["acme-llc", "globex"] },
  now: new Date(),
});

// northwind-llc is a brand-new payee, so decision.disposition === "escalate".
// A transfer over the 5000 cap would come back as "block" instead.
if (decision.disposition === "allow") {
  await sendPayment(action);            // your normal execution path
} else if (decision.disposition === "escalate") {
  await holdForHumanApproval(decision); // the approval gate: wait for a person
} else {
  // "block": the action never reaches the payment system
}

The engine is a pure function. Given the same mandate, action, and moment, it returns the same decision every time, and it evaluates every constraint so nothing slips through unchecked.

4. Route escalations to a human and keep the record

An escalation should reach a person with enough context to decide: what the agent wants to do, why, and what it would cost. Send that to whatever you already use, a chat message, a dashboard, an email, and pause the action until the answer comes back. Then record the decision.

// Every decision, allow, escalate, or block, becomes a replayable proof trail.
// npx forge-agent-gate init writes this for you. In a service, it is just config.
const forgeConfig = {
  baseUrl: process.env.FORGE_BASE_URL || "https://forgeorbital.com",
  apiKey: process.env.FORGE_API_KEY,   // your fi_... Agent Gate key
  recordMode: "required",              // or "best_effort"
  tenantId: process.env.FORGE_TENANT_ID || "agent-gate-demo",
  agentId: "refund-agent"              // one stable id per monitored workflow
};

await generic.recordGenericAction(forgeConfig, mandate, action, decision);

Approval gates for MCP tool calls

If your agent uses the Model Context Protocol, you can run Agent Gate as an MCP server so tool calls are checked before they execute, without rewriting the agent.

{
  "mcpServers": {
    "forge-agent-gate": {
      "command": "npx",
      "args": ["-y", "forge-agent-gate", "serve"]
    }
  }
}

The server exposes gate_action for refunds, payments, procurement, approvals, security actions, trades, and custom actions. The tool checks the signed mandate, records the proof trail, and returns allow, escalate, or block without executing the downstream action. When a trading mandate and venue adapter are configured, optional trading tools are also available; Kalshi is the connected venue today and other venues are in preview. A blocked or escalated write is returned as a tool error, so the agent cannot mistake it for a completed action. Read-only tools pass through untouched. You can watch the gate stop an agent in real time on the live demo.

The knobs: thresholds, limits, and allowlists

An approval gate is only as good as the policy behind it. The mandate gives you the levers that decide allow, escalate, or block:

All of that is one object you sign once. Here is a full mandate as data, the thing every agent action is checked against:

{
  "schemaVersion": 1,
  "mandateId": "policy-payments-2026-07",
  "allowedActionTypes": ["transfer", "refund"],
  "counterpartyAllowlist": ["acme-llc", "globex"],
  "counterpartyDenylist": ["sanctioned-1"],
  "maxSingleActionUsd": 5000,
  "maxDailyTotalUsd": 25000,
  "perActionType": { "refund": { "humanApprovalThresholdUsd": 100 } },
  "allowedHours": null,
  "humanApprovalThresholdUsd": 2500,
  "requireApprovalForNewCounterparty": true,
  "rateLimit": { "maxActions": 20, "windowSeconds": 60 },
  "killSwitch": false,
  "signature": { "alg": "ed25519", "publicKey": "MCowBQYDK2Vw...", "value": "b7c1a4...", "signedAt": "2026-07-09T00:00:00.000Z" }
}

You sign it with a key you control, and the gate refuses to run against an unsigned or tampered mandate. That signature is why the policy cannot be quietly edited by the agent it governs.

Keep an audit trail of every approval

Approvals are only half the value. The other half is being able to show, later, exactly what the agent did and what it was stopped from doing. Every decision the gate makes, allowed, escalated, or blocked, leaves a proof trail you can replay offline, with a cryptographic signature as the integrity check. When someone asks why a payment went out, why a refund paused, or why a procurement request was blocked, the answer is a record you can produce, not a memory you have to defend. An approval gate decides in the moment. The proof trail is what you keep.

Here is the shape of one record. It binds the decision to the exact mandate it was checked against, so the record cannot claim a policy that was not in force:

{
  "recordId": "rec_01J...",
  "agentId": "payments-agent-1",
  "timestamp": "2026-07-09T14:22:07.113Z",
  "action": { "actionType": "transfer", "amountUsd": 40000, "counterparty": "northwind-llc" },
  "disposition": "block",
  "reasons": ["maxSingleActionUsd exceeded: 40000 > 5000"],
  "mandate": { "mandateId": "policy-payments-2026-07", "version": 1, "hash": "sha256:3f9a..." },
  "signature": { "alg": "ed25519", "publicKey": "MCowBQYDK2Vw...", "value": "9c02f1..." }
}

Anyone can verify the signature offline without trusting you or the agent. That is the difference between a log the agent wrote about itself and a record an outside reviewer can check.

Getting your key: what runs locally and what needs Forge

The package is open source and live on npm, so npm i forge-agent-gate works right now and the gate logic runs on your machine. npx forge-agent-gate init is an interactive setup: it walks you through your first signed mandate, writes the local config and your signing key, and asks for a Forge API key. The enforcement engine and the mandate check are local and deterministic and need no key. The Forge API key is what sends each decision to Forge for the verifiable, replayable proof trail. Hosted keys are opening in waves, so you can request one while you wire the gate against your own mandate.

Where this fits

forge-agent-gate is the self-serve developer on-ramp to Forge Orbital. You can add it to one agent today with npm and grow into the enterprise and federal platform on the same engine when you need it. Forge's AI decision engine has been federally evaluated, and the Forge solution was assessed as Awardable on the U.S. Department of Defense CDAO Tradewinds Solutions Marketplace. Not a generic LLM wrapper.

To be clear about scope: this is a policy gate and proof-trail layer. It holds no funds and no venue keys, it is not a broker, and it gives no trading advice. It decides whether an action your agent already chose is permitted by your mandate, and it records the outcome. Start with the Agent Gate overview or watch it block an agent on the demo.

Frequently asked questions

What is an approval gate for an AI agent?

An approval gate is a checkpoint between your agent and the system that carries out an action. The agent proposes an action, the gate checks it against a policy you set, and the action is allowed, escalated for a human to approve, or blocked before it runs. It lets an agent act on its own for routine work while the consequential actions wait for a person.

Can I add an approval gate with just a system prompt?

No. A system prompt is a request the model can ignore, misread, or be steered around by a prompt injection. A real approval gate runs outside the model, deterministically, and checks the action before it executes, so a confused or compromised agent cannot exceed the limits you set.

Which AI agent actions should require approval?

Gate the actions that are irreversible, expensive, or visible to the outside world: payments, refunds, transfers, procurement, account changes, security responses, and trades. Let reads and easily reversible actions run without a gate. In practice, only a small share of actions should ever pause for a human.

How do approval gates work with an MCP server?

You can run forge-agent-gate as an MCP server so tool calls are checked before they execute. The generic gate_action tool checks refunds, payments, procurement, approvals, security actions, trades, and custom actions against the signed mandate, records the proof trail, and returns allow, escalate, or block without executing the downstream action. When a trading mandate and venue adapter are configured, optional trading tools are also available; Kalshi is the connected venue today and other venues are in preview.

Does forge-agent-gate hold my funds or API keys?

No. It is a local policy gate and proof-trail layer. It holds no funds and no venue keys, it is not a broker, and it gives no trading advice. It only decides whether an action your agent already chose is permitted by your mandate, and records the result.

What is the difference between an approval gate and an audit trail?

An approval gate decides in the moment whether an action runs, waits, or is blocked. An audit trail, or proof trail, is the record you keep afterward. forge-agent-gate does both: it enforces the policy before the action and writes every decision, allow, escalate, or block, as a replayable proof trail.

Add an approval gate to one agent today.

Start with the single action your agent should not take alone. Set one mandate, gate that action, and keep the proof trail.