Policies
A policy decides what happens to every agent call in an environment: it runs, it waits for a person, or it's denied. It's a short, ordered list of rules that the Gateway checks on every call.
First match wins, otherwise deny
Each environment has one policy. The Gateway checks its rules from top to bottom, and the first rule that matches the call decides. If no rule matches, the call is denied.
This means:
- A new tool does nothing until a rule allows it.
- Without any policy, every call is denied.
- The order of rules matters. Put the narrow rule before the broad one.
The Policies page shows the rules in order, numbered, with tools and agents by name, and ends the list with Otherwise: Deny. Admins change the rules in an editor, where each rule is a card and you drag cards to reorder them. The JSON tab shows the same rules as JSON, for those who prefer to edit them that way. The editor notes when an earlier rule hides a later one: Never applies when the earlier rule covers every call the later one does, and Partly hidden when it decides some of them. See Write a policy.
To see which rule decides a call, use Try it on the Policies page. Choose an agent and a tool, adjust the sample arguments, and click Try. It shows the decision, the rule that made it, and why each earlier rule was skipped. Nothing runs or is recorded.
What a rule says
Each rule has an id, what it matches, and an effect. In the editor, the id is the name at the top of the rule's card, what it matches is Tools, Agents and Conditions, and the effect is Then. The editor saves each rule as JSON, like this:
{
"id": "po-large",
"match": {
"tools": ["erp.purchase_orders.create"],
"args": [{ "path": "max_total", "op": "gt", "value": 1000 }]
},
"effect": "require_approval"
}
A rule matches a call when everything in its match is true:
tools: the call is for one of these tool ids.agents: the call comes from one of these agents, named by agent id. The id is shown on each agent under Tools & agents → Agents. Your customers' agents are listed there too: each registration is its own agent, with its own id.environments: the call is in one of these environments, named by environment id.args: every condition on the call's arguments holds.
A list you leave out matches anything. A rule without tools applies to every tool; the editor shows it as Any tool. Ids must match exactly, including upper and lower case. The editor lets you choose tools and agents by name and stores their ids for you.
Effects
| Effect | What happens |
|---|---|
| Allow | The call runs at once, and the agent gets the result. |
| Needs approval | The call waits until a person approves this exact request. Then it runs once. |
| Deny | The call never reaches your system. The agent is told which rule denied it. |
A require_approval rule can also say who approves, with approvers (Who confirms in the editor): staff (the default, your approvers), customer (the customer the agent acts for), or both. Customer approval only works for your customers' agents. See Your customers' agents.
Conditions on arguments
A condition names an argument by its path, an operator and a value. In the editor, you choose the argument from the tool's arguments, and the console shows the operators in words:
| Operator | Console shows | Matches when the argument |
|---|---|---|
eq | is | equals the value |
in | is one of | equals one of the values in a list |
gt | > | is greater than the value |
gte | ≥ | is greater than or equal to the value |
lt | < | is less than the value |
lte | ≤ | is less than or equal to the value |
Conditions are checked against the arguments after the Gateway has put them into their exact form: text normalized and trimmed, numbers in one notation. So for a number field, "12500.00", 12500 and the same number written in Arabic-Indic digits all compare the same way. Text compares exactly, including upper and lower case. The path uses dots for nested fields, and numbers for positions in a list, for example lines.0.quantity.
When a condition can't be checked
If the argument is missing, or isn't a number where the condition needs one, the condition can't be evaluated. The Gateway then fails closed:
- An
allowrule never matches. - A
denyorrequire_approvalrule does match.
So a missing max_total can never slip past a limit. With the rules po-large (over 1,000 needs approval) and then po (allow), a purchase order without max_total needs approval. Try it shows such a step as Decides (fail closed) or Skipped (fail closed).
Which tools an agent sees
An agent's tool list only shows tools your policy could let it run. A tool is hidden when no rule matches it for this agent, or when the first matching rule without argument conditions is a deny. Calling a hidden tool anyway gives unknown_tool. Showing a tool never decides a call: each call is still checked in full.
Versions
Every save creates a new version, numbered 1, 2, 3 and so on, and the Gateways apply it at their next sync, about 15 seconds later. The Policies page lists every version. You can open older ones to read them and compare them with the version in force. Before you save, Review and save lists what your edits add, remove, change and move, compared with the version in force.
Saving is checked strictly. A rule with an unknown field, a repeated id, an invalid operator or a value of the wrong kind is refused, and nothing changes. The editor catches most of these before you save.
Where to go next
- Write a policy for the steps in the console.
- Policy format for every field and operator.
- Approvals for what happens after
require_approval.
Still stuck? Contact support from the console.