KevinBytes
Back to writing
4 min readAI Security

How to Evaluate Tools for Securing Production AI Agents

Give a vendor a support workflow and inspect what reaches the resource APIs. Test changed approvals, alternate paths, retries, and outages.

By Kevin O'Connor

Last reviewed

I'd give an agent-security vendor a small application to work with before sending a questionnaire. Let a support agent read a ticket, retrieve an attachment, draft a reply, and request a refund. Then ask the vendor to show where its product can stop an unauthorized action.

That makes the conversation much more specific. A prompt filter can examine an attachment's text. It may have no say over the credential used to retrieve that attachment, or whether the payment service accepts the refund. The evaluation needs to follow the request far enough to see which component makes each decision.

Draw the paths the agent can actually use

For the support application, I'd start with this sketch:

User --> Support agent --> Tool dispatcher --> Ticket and attachment APIs
                                  |
                                  +---------> Refund API --> Payment service

Add any paths outside the dispatcher: shell commands, direct SDK calls, browser sessions, queued work, and retry workers. If the agent can reach the same API another way, the candidate control needs to account for that route or the deployment needs to remove it.

Then place each control on the drawing. Content inspection belongs where untrusted material enters the model's context. Authorization belongs where a request can be denied before the resource is read or changed. A sandbox limits the process's access to its environment. An egress rule controls destinations.

This is an application of the separation between policy decisions and enforcement described in NIST SP 800-207. For an agent, the model's proposed action becomes another request that needs an identity, a resource, and an enforceable permission rule.

Build a fixture with observable results

Use invented customers and a disposable support application. The refund endpoint can return a simulated receipt instead of moving money. Give each request an operation ID and retain the result at the service so the evaluator can distinguish a proposed call from an accepted operation.

I'd put these cases into the lab before inviting vendors to demonstrate against it:

CaseWhat to inspect
Customer A requests B's attachmentThe resource API rejects the read using the authenticated tenant, even when the object ID is valid.
The attachment tells the agent to issue a refundThe refund still needs the required authority and approval.
The amount changes after approvalThe previous approval cannot authorize the changed request.
An approved request is retriedThe final service state contains the intended operation once.
A direct SDK call bypasses the dispatcherThe resource policy still applies, or the alternate route is unavailable.
A permitted URL redirects to a blocked destinationDestination checks cover the connection made after the redirect.
Policy lookup times outThe documented behavior is visible for that operation.
The log destination stops accepting recordsBuffering, rejection, or degraded operation follows the configured rule.

Run the legitimate cases alongside those failures. Customer A should retrieve A's attachment. A correctly approved refund should complete. Otherwise a disconnected tool could appear to enforce every denial.

For systems using MCP over HTTP, check the claimed protocol revision. The 2025-11-25 authorization specification includes token audience validation and resource indicators. Those requirements help bind credentials to the intended service. The attachment service still needs to check which customer's object the caller may read.

Keep approval bound to the operation

The refund approval should identify the customer, transaction, amount, currency, approver, expiry, and allowed execution count. At execution, those values need to match the request being authorized.

I'd test changes to the recipient and amount separately, then put the approved job in a queue long enough for the approval to expire. I'd also remove the approver's role before the worker runs and check the behavior against the application's chosen policy. These cases force the team to decide whether approval is evaluated at submission, execution, or both.

Credentials need the same level of attention. Follow where they are issued, which worker can read them, and how revocation reaches a running process. Use an inert canary value in the fixture to check whether configuration is copied into model context or debug logs. A redacted settings page only tells you what that page displays.

Measure a complete task

A control can add little latency to successful calls while causing enough retries to make the whole workflow slow. Time the user task from submission to final result, then inspect the individual calls that explain it.

Keep the inputs, model settings, and downstream behavior fixed when comparing candidates. Report successful authorized tasks, denials, errors, and timeouts separately. Measure p50, p95, and p99 added latency over a workload large enough for those percentiles to be meaningful. Separate cold starts and include concurrent work from another synthetic tenant.

Decide the operating budget before looking at the results. The support team may tolerate a delayed draft while a refund must wait for fresh authorization. A blanket “fail closed” setting can hide those differences just as easily as an unrestricted fallback can ignore them.

During a policy outage, show the operator which decisions used cached information and when that information expires. Test recovery too. Restoring the service should not silently replay a queue of operations whose approvals are no longer valid.

Make the purchasing decision from the cases

Keep the product edition, configuration, deployment mode, evaluation date, expected result, and observed result with each case. Documentation can explain how a feature is intended to work. A case passes when the configured system produces the required result; unavailable cases remain untested.

Some failures should remove a candidate from consideration. Cross-customer reads and unauthorized payments can't be compensated for by a good dashboard or low latency. Once those requirements are met, compare deployment effort, usability, ongoing maintenance, and cost.

I'd keep the fixture after the purchase. When the support agent gains a new connector or broader permission, rerun the affected cases against the deployed configuration. That is much easier to maintain than a feature spreadsheet whose answers stop being useful as soon as the integration changes.

Email updates

Get new research by email

In-depth notes on AI security, threat research, and practical defensive work.

Confirm your email to subscribe. Occasional research updates, with an unsubscribe link in every email.