Machine transcription with reviewed terminology and names. Some recognition errors may remain. Timestamps refer to the livestream; subtitle downloads are timed to the session clips.
3:09:28Today I'm going to talk to you about how your agent is a lethal trifecta and what to do about it.
3:09:34Now we're going to start out right off the bat with a demo.
3:09:38Some context on this demo, we're going to look at an on-call triage agent that reads and writes to an incident pager and resolves or escalates tickets.
3:09:47This agent has full access to a cloud hosting API, a customer data warehouse, as well as a billing database.
3:09:55So here we have our on-call triage agent, and it has an incident queue of tickets that it's going to read.
3:10:02and then if it can resolve them, it's going to call the available services that it has access to
3:10:08and it's going to do so.
3:10:10Things that it can't resolve, it's going to escalate for the morning team.
3:10:14So if we take a look at this first ticket, this is a billing anomaly.
3:10:19It says a batch of customers were overcharged last night.
3:10:23So the first thing the agent does is it directly calls the Incitex API in order to read the ticket.
3:10:28And if you look here, you can see that it authorized access to this API using an API key.
3:10:34It then uses a Snowflake key to query the customer data warehouse, and it's going to decide to escalate the ticket for morning review.
3:10:43And it writes a report for the morning team.
3:10:45And as you can see, it's sharing customer data.
3:10:48These are rows directly pulled from the customer data warehouse, and it is sending personally identifiable information to the team that is going to be on staff in the morning.
3:11:04This next ticket is a backup power supply failed in the server room.
3:11:08The agent is going to read the ticket.
3:11:10Again, it's using an API key to call the ticket API.
3:11:15It determines that this is a physical problem, so it escalates for morning review without calling any additional services.
3:11:26This one is the TLS certificate is expiring soon for the website.
3:11:31It reads the ticket. It determines that the alert is clear.
3:11:34It has access to the cloud hosting API, and it calls that API at the certificate renew endpoint using, again, an API key.
3:11:46It resolves this by renewing the certificate, and it leaves a report for the morning crew by calling the pager incident API as well.
3:11:58This next one is the billing database is broken and payments are failing.
3:12:02So the documented recovery for this is to drop and restore the database.
3:12:09The agent does this using the database connection string that includes the admin password.
3:12:15And then it advises the morning team to make sure that the snapshot recovery worked.
3:12:20Now, this is not something that it has access to directly.
3:12:24So it is essentially assuming that the morning team is going to verify that this did in fact work and the information was restored.
3:12:38Now, an overprivileged agent dropping a production database is basically a nightmare that several companies have actually lived.
3:12:46So this is something that we need to be very careful of.
3:12:50Now, the next one is orders are stuck.
3:12:53Main server is frozen.
3:12:55So the agent is again is going to read the ticket.
3:12:59After reading the ticket, the agent calls the cloud hosting API using again its static
3:13:04API key.
3:13:05It calls the endpoint to restart the server, which brings production offline.
3:13:15Finally, site is failing for one in three visitors.
3:13:20Agent reads the ticket.
3:13:21it determines that
3:13:23it should call the cloud hosting API and scale the service from four pods to 40. It then incurs a charge of $420 per hour for doing this. And then it kindly leaves a note for the morning team informing them that this has happened.
3:13:43Now, what makes an agent useful?
3:13:46Well, typically, we want agents to have a minimum set of capabilities, and often this
3:13:51includes things like the ability to read data that you own or have access to.
3:13:56This might be like your email, your documents, maybe a customer CRM.
3:14:00We want the agent to be able to do its own research, so this might include searching
3:14:04the web, maybe reading documentation, or pulling issues from GitHub.
3:14:09And we usually want it to be able to use external tools, for example, MCP servers or APIs, maybe SAS platforms.
3:14:17useful agents might do these things with a human in the loop, or they might be doing it autonomously in the background.
3:14:23But the things that make agents useful also make them dangerous.
3:14:29In fact, together, these three capabilities make what Simon Willison coined as a lethal trifecta.
3:14:35This is a combination of access to private data, like the on-call agent's ability to query the customer data warehouse and interact with the billing database,
3:14:45exposure to untrusted content, like reading user-submitted tickets or reports from other agents or externally documented processes,
3:14:53and the ability to communicate externally, like reading and writing with third-party APIs or SaaS services.
3:15:00Together, these capabilities throw the doors wide open for attackers.
3:15:06Now, agents are designed to get the job done, and they'll use all the powers that they
3:15:10have to do it, sometimes with very serious consequences.
3:15:15here's the thing.
3:15:16incidents happen because humans give agents way more access than they need.
3:15:23Overprivileged agents can act freely on decisions that they make, even if they do have supervision.
3:15:30Now, forcing a human-in-the-loop approval just kind of passes the access control on to a consent-fatigued user.
3:15:37Now, we've spent decades solving access management for humans, so shifting responsibility to the user just sort of moves the security problem up the chain.
3:15:47So what should we do about the lethal trifecta? How do we address it without compromising the agent's usefulness?
3:15:55Well, just removing one or more of these capabilities is going to cause the agent to be significantly less useful.
3:16:02So how can we keep all three, but still be safe about it?
3:16:06Well, instead of breaking the trifecta by removing capabilities, we really need to control the agent's access so the attack surface is minimized and the blast radius is contained, but the agent still has capability and autonomy.
3:16:21So how do we do that?
3:16:24Well, some options for controlling access, among others, are things like using OAuth, maybe using a vendor MCP gateway, or containing execution in sandboxes.
3:16:36Now, OAuth binds access to a grant. At grant time, the user consents to all of the permissions that the agent could possibly use.
3:16:44Now, consent is granted before any task exists, so if you give a broad grant, then you end up with standing access.
3:16:51your agent is over permissioned for any single specific task. If you narrow the
3:16:57grant and you don't give it very many permissions, then the agent just becomes
3:17:00less capable. Either way, OAuth alone doesn't provide task scoped access
3:17:04control. An enthusiastic agent can both read and write in the same run, even if
3:17:10you only want it to read on this specific task. Now an MCP gateway binds
3:17:17enforcement to a route. You get things like observability and rate limits and
3:17:21you also get one policy decision point at the MCP layer. A policy runs per request,
3:17:27and access is granted per user, but the agent's granted access outlives any single task
3:17:32because the gateway still holds standing credentials.
3:17:36Now a sandbox binds execution to a process. This controls the blast radius, but useful work has to
3:17:42reach outside the sandbox, and when it does so, you end up with standing access again.
3:17:46Now we've also seen plenty of stories about agents breaking sandbox containment.
3:17:52Sandboxes bound what the processes can do, but they don't control what is authorized
3:17:56to act outside the sandbox itself.
3:18:00Now, even if you combined all three of the solutions, the agent still doesn't receive
3:18:05a runtime credential that's downscoped to only one task.
3:18:11let's recap the problems, especially the ones that we saw in the demo.
3:18:14Now, if you remember the audit log, we couldn't tell who was using the API keys.
3:18:20So the first problem is that credentials weren't attributed to a user or an agent's identity.
3:18:26The agent had unrestricted access to any and all permissions that were granted by the API
3:18:31keys.
3:18:32And finally, we can't just slap human in the loop everywhere because humans make mistakes
3:18:37too.
3:18:37Plus many agents run autonomously and they don't even have a human in the loop.
3:18:43So to solve these problems, we can start by using something called token exchange.
3:18:47Now, this is an existing standard that was published in 2020, and it extends OAuth 2.
3:18:54Now, first, we need to know who the user is.
3:18:57Now, an authorization server verifies identities and issues tokens.
3:19:01Identity providers like Google, Okta, Auth0, etc. provide authorization servers.
3:19:06So if we want an identity chain in our agent execution path, then the user has got to log in first.
3:19:14The authorization server is going to prompt the user for consent to delegate access to resources with some subset of their permissions.
3:19:22Now, these permissions are called scopes.
3:19:23This is the first narrowing of access.
3:19:26We're only delegating some of the user's total scopes to the agent.
3:19:32The authorization server issues tokens identifying the user and their level of access.
3:19:38And at this point, we're already doing better than the demo because we actually know who the user is and we actually know what they can access.
3:19:47So this brings us into the agentic execution path.
3:19:52Now we have our authenticated user, so we have a known identity of a person who wants to use an LLM to interact with a resource.
3:20:00Now, in the demo, the resources are the incident pager, the production database, Snowflake, and the cloud hosting service.
3:20:08An agent is a control loop that calls an LLM.
3:20:11Often, we have an MCP server that sits between the agent and its resources, providing defined tools that connect to those downstream services.
3:20:21An MCP client dispatches the agent's proposed tool calls to its MCP server.
3:20:27Now, in the demo, the on-call triage agent called resources directly with long-lived static credentials like API keys or database connection strings.
3:20:37So what we're going to do is we're going to give the on-call agent an MCP server.
3:20:41This is going to provide tools and is also going to serve to broker access to resources.
3:20:50Now, an agent runtime is a process that runs the agent loop and executes calls.
3:20:55The runtime might be a CLI, like Claude Code,
3:20:58or an agent SDK, which might be implemented in a custom application like the on-call agent.
3:21:05So let's follow a prompt through this execution path.
3:21:09The user submits the prompt to the runtime, which calls the model and sends the prompt to the LLM.
3:21:14The model then proposes tool calls, which are dispatched by the MCP client to its MCP server,
3:21:20which executes tools and then calls the resource API.
3:21:26The API returns the response to the MCP server.
3:21:30The MCP client delivers the response to the runtime, which calls the model again.
3:21:35And this loop repeats until the model is satisfied and returns a response to the user.
3:21:43Now, the authenticated user's token becomes what we call a subject token.
3:21:47This identifies who the agent is acting on behalf of, who it acts for.
3:21:54Now, token exchange needs an OAuth client that can execute code.
3:21:58So this might be a gateway that sits between the MCP client and the third-party MCP server.
3:22:05Or it might be your custom app.
3:22:08Now, a custom MCP server can also exchange tokens for downstream resources.
3:22:13The on-call agent's MCP server should provide a defined set of production infrastructure tools.
3:22:21The prompt and the subject token are sent to the runtime.
3:22:24The agent loop runs, and the model proposes a tool call.
3:22:31runtime authenticates with a special authorization server called a security token service.
3:22:36It does this using its app client credentials or workload identity.
3:22:41also sends the subject token that contains the user's identity and access.
3:22:46It creates a token exchange request asking for permission to access the MCP server for that tool call and only that tool call.
3:22:54So now we have three pieces of info that we're missing from the demo.
3:23:00We know the identity of the agent that's requesting access.
3:23:04We know the identity of the user it's acting on behalf of.
3:23:07And we know the level of access that the user granted to the agent.
3:23:11Now we need to decide if the requested token should be issued, and we can do this with
3:23:16governance policy, which is evaluated against what access is requested from what resource,
3:23:23the
3:23:23identity of the agent, and the identity of the user.
3:23:29But policies are ceilings. Agents can do things you didn't intend, even when policy overall allows them.
3:23:38This brings us to something called intent-based authorization, or IBA.
3:23:42Now, IBA checks what you mean before the agent acts.
3:23:47Now, it's not a finalized standard.
3:23:49They're still accepting proposals.
3:23:50So this is Keycard's approach to implementing intent-based authorization.
3:23:57Now, IBA can use a gateway as a policy enforcement point.
3:24:02When you send the prompt to the agent, it proposes a mission.
3:24:07this mission includes a goal, maybe allowed actions, as well as limits to what the agent is allowed to do.
3:24:13So a goal of triage incident 2294 means read that ticket, summarize, or escalate.
3:24:20But don't read other tickets and don't use other services.
3:24:26So the security token service receives this mission.
3:24:29In this case, a low-risk activity like just assessing a ticket might be auto-approved under admin policy.
3:24:37On the other hand, if we've already read the ticket and then we ask to remediate a usage spike, then the mission adds permission to scale the service once, but not use other tools or APIs.
3:24:49Now, in this case, the mission is presented for the user to review and approve.
3:24:56Once approved, the security token service gives the mission an ID, which is sent to the agent.
3:25:03The tool calls include this mission ID and are proxied by the gateway, which uses the ID to ask the security token service if this tool call fits the mission.
3:25:12If it does, then the gateway requests a token exchange for access to the MCP server for that specific tool call.
3:25:21The STS evaluates policy.
3:25:25It evaluates the delegation chain, and it looks at the requested access.
3:25:29Now, if everything looks good, it issues an access token for the MCP server, and it keeps the user subject, as well as adds the app that performed the exchange, which is, in this case, our on-call agent.
3:25:42Now, this token should expire within minutes, and we should never store it. It's ephemeral.
3:25:47The STS sends it to the gateway, which calls the MCP server.
3:25:52The server then validates the token and authorizes the tool call.
3:25:59Now, some tools need external resources.
3:26:01So the MCP server then asks the security token service to exchange the token that it just received for a token for the downstream resource.
3:26:11Now, the STS evaluates the request against policy.
3:26:15if it passes, then it mints a resource token that's scoped again to that tool call.
3:26:21It keeps the user subject, which extends the delegation chain and allows us to be able to track all of the activity.
3:26:32The STS sends the token to the gateway, which proxies the request to the MCP server, which then calls the resource.
3:26:41The resource validates the token and authorizes access.
3:26:45Now, the MCP server should never store the token. It should discard it immediately after the call.
3:26:51The resource response then flows back up and the agentic loop repeats until the model returns the answer to the user.
3:27:02So now we're going to look at the same demo, except we are going to use a security token service to manage agent access control with delegated authorization.
3:27:12The demo uses task-based policy governance, not intent-based authorization.
3:27:18But if you're going to AgentCon later this month, we'll have IBA demos there.
3:27:25Now we also now have an MCP server that establishes tools and it provides brokering access to the resources.
3:27:34So now we're back to our on-call triage agent again, only this time we have authentication.
3:27:40Now I'm going to go ahead and sign into the On-Call Agent Triage app.
3:27:49I'm going to log in with Google to do so.
3:27:57And then you get another login screen.
3:27:59Now this is where I'm going to sign into the Incidex Pager platform.
3:28:08So I get a prompt to grant the on-call agent access to my Incidex account.
3:28:13I'm going to let it escalate incidents on my behalf, post notes and summaries, and read the queue.
3:28:24Now I'm being prompted to log into the cloud hosting platform.
3:28:28So I am going to do that.
3:28:38And I get another consent screen now, which allows me to authorize the agent to access
3:28:43some capabilities of CompuHost on my behalf.
3:28:51Now, finally, I am back on the on-call dashboard.
3:28:55Now we have the same queue of tickets, only now the audit log looks different.
3:28:59The agent is probably going to try to behave the same way it did before,
3:29:03only now every request is going to go through the STS and policy evaluation
3:29:09before a token is granted and the agent will be authorized to act.
3:29:16So we have the same queue of tickets, only now the audit log looks different.
3:29:20And the agent is probably going to behave the same way that it did before,
3:29:24only now every request is going to go through the STS and policy evaluation
3:29:28before a token will be granted and the agent can be authorized to act.
3:29:33So the first ticket is that billing anomaly.
3:29:41Again, the agent tries to read the ticket, and we can see that it is trying to do the same thing that it did before.
3:29:52It tries to query the customer warehouse, but policy doesn't allow a credential to be issued for this.
3:29:58because customer PII doesn't belong in an agent's context or in an incident ticket.
3:30:04So the agent proceeds without the customer data and it escalated it to the morning team.
3:30:23Now we have the website security certificate expiring.
3:30:32Now, this is something that the agent has permission to do.
3:30:35So when it requests credentials to do this from the STS, access is granted, and it can
3:30:41call the Cloud Hosting API and resolve this ticket.
3:30:48Now, you can see all of the calls that it's making and who is making them.
3:30:52So we have the on-call triage agent that is requesting to renew the certificate.
3:30:59It's asking for permission to call the appropriate tool from the Infra MCP server.
3:31:05So it gets a token for that.
3:31:08After that, the MCP server is going to request access to that cloud hosting service in order to renew the certificate using the API.
3:31:24So if we move on to the billing database, it's going to read the ticket through the incident
3:31:33API.
3:31:34It's going to come to the same conclusion that it did before.
3:31:37The agent knows that this is a drop and restore procedure, but this time policy forbids an
3:31:43agent to drop a production database.
3:31:45A human's got to do this manually.
3:31:48And we can see this in the audit log where the STS refused to grant the token exchange for access to the database delete.
3:32:05So now we have our orders are stuck.
3:32:08The main server is frozen.
3:32:10The agent is going to go ahead and read the ticket.
3:32:15it. It wants to restart the main server. This takes production brief fuel offline.
3:32:20It informs me about this, and this time it's actually asking for my approval to do this.
3:32:26So I'm going to click approve. However, this was also blocked by policy, and the reason for this
3:32:32is because my user does not have the role necessary to take this action.
3:32:41So the agent can't do it, but I can't do it either, and the agent is acting on my behalf.
3:32:49If we move to the site failing for one in three users.
3:32:56Again, the agent wants to add more servers, and it's going to ask for permission.
3:33:00It's going to say what we're committing to when we do this.
3:33:06I'm going to go ahead and approve this.
3:33:09And this is something that my role does have the authority to do.
3:33:14So the scale goes through and this ticket is resolved.
3:33:20So we can see that the agent access problems are solved.
3:33:23We
3:33:23know the user and the agent identity all the way down the chain. The agent has task-scoped ephemeral access to the MCP server and downstream resources. And we have human in the loop with access control that's actually backed by policy.
3:33:41Now, access is controlled at the task level by the security token service and policy, and we retain all key capabilities.
3:33:52Now, token exchange is an open standard. It's well-researched and it's public, so anyone can implement it, and it interoperates with existing policy engines and standards-compliant identity providers, as well as things like gateways, sandboxes, OAuth, off-the-shelf and custom agents, CLIs, MCP servers, software factories, agent-to-agent, cross-app access, plus whatever comes out next week.
3:34:16so I hope you'll consider it to make your agents useful, safe, and future-friendly.
3:34:24My name is Kim Maida. I'm the founding GTM engineer and head of DevRel at Keycard.
3:34:31And I really appreciate your time today, so thank you very much.