Limit what an agent may do
Grant an AI agent a capability, set limits on the details of each action, and add project rules that deny an action or send it to a person.
An AI agent starts with no permissions. This guide shows you how to give an agent a permission, grant it a capability that limits the details of what it may do, and add rules that hold for the whole project.
How permissions, capabilities, limits and rules fit together
Four things decide what an agent may do.
- A permission is an action on one kind of thing, such as
transfer:accounts. An agent holds a permission the way a person does: through a role. - A capability names that permission on the agent itself, and can carry limits on it. The console shows a capability as a permission on the agent's Permissions tab.
- A limit is a condition on the details of one action. It belongs to one capability on one agent: this agent may transfer, up to 5,000.
- A rule applies across the project, to the agents and people it names. A rule can deny an action, or make it wait for a person to approve it. The console calls a rule a policy.
Each time the agent asks before acting, AuthFI checks the limits and the rules, and whether the agent holds the permission. The names of an agent's capabilities travel in its access token, in the capabilities and scope claims. The limits do not. They stay with AuthFI, so a changed limit applies to the agent's next call.
For the model behind this, see How agent sign-in works.
Before you begin
You need:
- A registered agent. See Give an AI agent an identity.
- Administrator access to the AuthFI console.
Give the agent the permission
An agent holds a permission the way a person does: through a role.
- In the console, open Identity > Roles & permissions and select the Permissions tab. Choose New permission, enter
transferas the Action andaccountsas the Resource, and choose Add permission. The permission's key istransfer:accounts. - On the Roles tab, choose New role, enter a Name such as
Payments agent, and choose Create role. On the role's page, selecttransfer:accounts, choose Save changes, and confirm with Save. - Choose Give this role, then An AI agent. Pick the agent and choose Give the role.
A permission is about one kind of thing. transfer:accounts covers the objects written account:…, such as account:4821.
Grant a capability
- In the console, open Identity > AI Agents and select the Agents tab.
- Open the agent, and select its Permissions tab.
- Under "What it may do on the platform", choose Grant a permission.
- Fill in the dialog, then choose Grant.
Choose a permission whose name means something to the people who read it in an approval. This guide uses transfer:accounts.
The capability appears in the table on the Permissions tab, with its limits in the "Limited to" column.
Write the limits
In the Limits field, name each field of the action's details and the values it may take. The details are the context the agent sends when it asks before acting.
{
"amount": { "max": 5000 },
"currency": { "in": ["USD", "EUR"] },
"region": { "not_in": ["sanctioned"] },
"account_type": "business"
}The field shows {"amount": {"max": 2000}} as an example.
You can also set limits while you register an agent, in the "What it may do" step. There you choose Add a limit and pick an operator by name.
Add a rule for the whole project
- In the console, open Security > Triage and select the Rules tab.
- Under "Policies", choose New policy.
- Enter a "Name", choose an "Effect", choose who the rule applies to in "Applies to", and choose Create draft.
- In the editor, choose Validate, then Enable, then Save.
A rule names whom it applies to, an action, the things it applies to, and a condition on the action's details.
{
"subjects": ["agent:*"],
"relation": "transfer:accounts",
"object": "account:*",
"condition": { "field": "amount", "op": "gte", "value": 1000 }
}agent:* is every agent, shown as Every agent in "Applies to". A condition compares a field with gte, gt, lte, lt, eq or ne.
With the effect "Require step-up", the rule above says that transfers of 1,000 or more need a person. It is one rule, and it holds for every agent you register from then on.
A new policy is marked "Draft". After you enable it, it is marked "Live".
Check that it works
Test a decision in the console first.
- Open Security > Authorization and select the Evaluate tab.
- Under "Would this be allowed?", enter the "Subject", the "Action" and "On what". For the example agent, the subject is
agent:agt_7f3a9c21, the action istransfer:accountsand the object isaccount:4821. - Choose Check.
Then ask AuthFI to decide, as the agent does. A transfer of 100 is inside every limit, and below the 1,000 at which the rule asks for a person.
First bind a transaction token to the action. A transaction token names one action and its details, and lasts 60 seconds.
curl https://acme.authfi.io/apis/regional/v1/ai/auth/transaction-token \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "transfer:accounts",
"resource": "account:4821",
"context": { "amount": 100, "currency": "USD", "account_type": "business" }
}'Then ask for the decision, with the transaction_token from the response.
curl https://acme.authfi.io/apis/regional/v1/agents/authorize \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agt_7f3a9c21",
"transaction_token": "'"$TRANSACTION_TOKEN"'",
"action": "transfer:accounts",
"resource": "account:4821",
"context": { "amount": 100, "currency": "USD", "account_type": "business" }
}'$ACCESS_TOKEN is the agent's access token. agt_7f3a9c21 is its agent ID, shown as "Client id" on the agent's Connect tab. Both requests are explained in Ask before a sensitive action.
{ "data": { "decision": "allow", "reason": "relationship" } }Now break a limit. With the limits above, a transfer of 10,000 is over the amount limit. Send the first request again with "amount": 10000. AuthFI does not bind a token to it, and answers 403:
{ "error": "invalid_body", "error_description": "constraint_violated" }An agent never holds a transaction token for an action outside its limits, so it cannot go on to ask for a decision.
How a limit is evaluated
With the limits and the rule above, the same capability gives different answers for different details.
A field named in max, min or in must be sent, and so must a field limited to one value, such as account_type. A request that leaves it out is denied, so an agent cannot pass a limit by omitting the thing it limits.
The limits are checked again when the agent asks for the decision. If a limit was lowered after the token was bound, the answer is deny with a reason such as constraint_violated: amount max.
The decision and its reason
Every decision comes with its reason.
The same reason is written to the audit record, so you can see afterwards which limit stopped which action.
The order of a decision
AuthFI makes each decision in this order. The first check that fails gives the answer.
- Is the agent known and not revoked? If not, the response is
401. - Do the action's details pass the limits on the capability? If not,
deny. - Does a rule deny it? If so,
deny. - Is it granted? If not,
deny. - Does a rule ask for a person? If so,
approval_required. - Otherwise,
allow.
What is checked for a delegated agent
An agent is delegated or autonomous. See Two types of agent.
A delegated agent that acts for a person through the MCP gateway can do only what both of them may do. The agent's grants and the person's grants are both checked. If either one does not allow the call, it is denied.
Troubleshooting
A decision of approval_required is not a failure. The action waits for a person. See Wait for a person.
Next steps
Ask before a sensitive action
Get a decision for one action, and wait for a person when a rule requires one.
The MCP gateway
Grant tools one by one, and apply your rules to every tool call.
Revoke an agent
End an agent's access in one action.
Roles, groups and grants
How grants, groups and rules decide access across the project.