Skip to content
← Back to blogLatch Journal

What an AI Agent's Token Can Reach

Connect an AI agent to a case system through scoped tools, a central authorization gate, and a request-then-approve default for high-impact actions.

See how it worksPlugin SDK →

An AI agent connects to your ticket system. Most teams ask what the agent can do. Wrong question. The agent can attempt anything its instructions suggest. What it can do is set by the credential it holds and the checks that run when it calls a tool. The token is the boundary, not the prompt.

THE TOKEN, NOT THE PROMPT, IS THE BOUNDARY AI agent scoped token, least privilege Authorization gate role + allow-list + risk ceiling ALLOW · read and draft tickets.search, tickets.get, tickets.comment.create REQUEST actions.request _approval Operator approves, then it executes high-impact: approval required Invocation record every call: tool, decision, case touched, deny reason, policy version

The agent holds a scoped token. The gate runs the same permission check a human would face. It then allows a read-and-draft tool or accepts a request for a high-impact action that needs operator approval. What the agent may run is the operator's configuration. Every call, allowed or denied, is recorded with the policy in force.

A support agent that reads a ticket and drafts a reply is useful. So is one that recommends a next step. Give that agent a credential that can issue a refund, and it is a liability waiting for a bad inference. A credential that can change an account or delete records is no safer. The difference is not how the agent is written. It is what its token reaches.

This Is For Teams That Need a Token Boundary

  • Engineers connecting an AI agent or MCP client to an operations system need to decide what access to grant.
  • Operations leads want AI in the queue without giving it the ability to move money or message customers unattended.
  • Anyone who must answer, after the fact, what an agent did and why a request was refused needs the record.

The Prompt Is Not a Permission Boundary

The fast way to connect an agent is to mint an admin key and paste it into the client. Then rely on the system prompt. That works in a demo. It fails when the model misreads a ticket or follows an injected instruction in an email. It also fails when it generalises past its brief.

A prompt is guidance. A permission is enforcement. An agent that has been told not to issue refunds but holds a credential that can do so will eventually issue one. The instruction is text the model can reinterpret. The permission is code that runs before the action. When they disagree, the permission wins. That is the property you want.

Latch treats an agent as an identity with a scope, not a key with a blast radius. The agent authenticates with a credential. The secret is hashed at rest. The credential has an expiry and can be revoked. Every call is attributed to that identity. What it can reach is a configuration decision, not a matter of trust in the model.

A Scoped Identity Grants Nothing by Default

An agent connects under a profile. The default profile grants nothing until you list what the agent may touch:

  • Tools, by exact name or pattern. Grant tickets.search alone. Use tickets.* for the read-and-draft set. Use api.get.* for read-only access to the wider API.
  • Resources, by pattern, so an agent can be confined to the queues and ticket types it is meant to work.
  • Plugin actions, named as {provider}:{action}, so the external actions an agent may even request are an explicit list rather than everything the system can do.
  • A risk ceiling. Tools generated from the API are rated low, medium or high. A read is low. A write is medium. A delete or a hit on a sensitive path is high. The profile caps the level the agent can reach, so a read-only agent cannot stumble into a destructive one.

There is an admin profile with no restrictions, for trusted internal automation. Most agents should never hold it. The scoped profile is the default. An agent should start with nothing and earn each tool. A new operator does not arrive with every permission switched on.

The Gate Decides Every Call, Not the Tool

Authorisation does not live inside each tool handler. It runs in one place, before any handler executes. When the agent calls tickets.comment.create, the gate resolves the ticket from the call. It builds the agent's identity from role and profile. It runs the same permission check as a human adding a note to that ticket. If the check fails, the call returns a policy denial with a readable reason. The handler never runs.

This holds as the system grows. A new tool added next quarter passes through the same gate. Its author does not need to re-implement the check. The authorisation model lives in one auditable place, not across every handler where one missed check becomes a hole. The agent's role defaults to the lowest one available. An unconfigured agent is harmless, not dangerous.

The same rule applies outside the agent path. Roles, numeric thresholds, policy versions, and denied attempts must remain reviewable as one control model. Authorisation logic audits for case management explains what that evidence needs to preserve.

The Operator Decides What an Agent Can Execute

A plugin runs actions on external systems. In principle a plugin action can do whatever the external system allows. It can issue a refund. It can change an account. It can send a customer a message. The plugin layer does not decide an agent is safe. The operator does, in the profile.

The posture is set per action. An agent can call a low-risk tool on its own: a lookup, a read, an internal comment. A plugin action that touches an external system can require approval. The most the agent does is call actions.request_approval. The request lands in the same workflow as a human-raised request. An operator approves or denies it before anything runs. The safe default for work that moves money or reaches a customer is request-then-approve.

That is what makes it safe to put an agent on high-stakes work. A refund is exactly the action you would never hand to a model unattended. That is why it is worth handing over behind a gate. The agent gathers and proposes. A human approves. The system records both. A human in the loop is not a brake on the agent. It is what lets you point the agent at the hard work.

Every Call Leaves a Record, Including the Denied Ones

Every call the agent makes is recorded. Each one is written to an invocation record: the tool, the outcome, the ticket it touched, the approval request if any, and the reason if denied. The record also carries the policy version in force when the call ran. A reviewer can reconstruct what the agent did and what it was permitted to do at the time. That is the question that comes up when something goes wrong.

Denied attempts are recorded, not silently dropped. A refused request is evidence the boundary held. A run of refusals is a signal the agent is being asked to do work it should not do. An audit that shows only successful actions cannot tell the difference between an agent that never overstepped and one that was stopped every time it tried.

The Control Lives in the Gate, Not the Agent

Because the control lives in the gate, it stays agnostic about the parts that change fastest. Swap the model. Rewrite the prompt. Point a different MCP client at the endpoint. The tools the agent may call do not move. The tickets it may reach do not move. The actions it may request or run do not move. The agent is the part you are meant to iterate on. The boundary should not shift underneath you when you do.

State the rule plainly. An agent gets an identity, not a key. Its reach is a scoped list, not a default of everything. What it may execute is a posture you set per action. The safe default routes high-impact work through human approval. Every call, allowed or denied, is on the record with the policy that decided it.

Three Problems Are Still Open

This model covers a single agent acting as one identity. Delegation across several agents, where one agent hands work to another and permissions travel with it, has no clean answer yet. Risk ratings on generated tools are coarse. A finer model would let teams grant more without granting too much. Proving that the ticket the agent described is the same ticket the operator approved is the same open problem the approval work names. These are the edges. The scoped identity holds today. The central gate holds today. The request-then-approve default for high-impact work holds today.

Continue reading

Continue exploring
Next product pathPlugin SDKAdd plugin actions without hard-coding every downstream workflow into the core product.Related pathProduct OverviewSee how unified triage, approvals, audit trails, and plugins connect.
Related reads
Building a Latch Plugin That Reads Handwritten ChequesA Latch plugin that reads handwritten fields from a cheque — payee, amount, cheque number — validates them, and gates credit or reject actions on the result.Why Approval, Auth, and Audit Logic Must Stay in the CoreWhy approval, authentication, and audit logic belong in the platform core rather than in plugins that can be swapped or misconfigured.Approval Design: Durability, Policy, and PluginsThe configuration underneath an approval gate - durable resume and revalidation, role separation as policy, building gated actions, and the problems still open.
Ready to move beyond reading?

See the same workflow running end to end.

The walkthrough follows one ticket from intake through triage, an approval gate, plugin execution, and the audit record it leaves behind. It runs on the model you choose, inside your own boundary.

Talk to usSee the platform →