AI Engineer World's Fair 2025
Securing Agents with Open Standards
About this talk
Auth0 engineers Bobby Tiernay and Kam Sween explain how production AI agents can avoid excessive permissions, exposed secrets, and untraceable actions by tying authorization to individual users. They describe short-lived OAuth tokens, token exchange, fine-grained retrieval-layer authorization, and CIBA-based asynchronous approvals, then demonstrate standards-based agent authorization and Auth0 Token Vault.
Chapters
- 0:00Presenters, Auth0, and production-agent security risks
- 2:51Replacing shared API keys with user-bound OAuth tokens
- 5:47RAG authorization and CIBA approval flows
- 8:04Agent authorization demo, Token Vault, and standards recap
Talk transcript
- 0:00
[on-hold music] Hi, everybody.
- 0:16
I'm Bobby, this is Kam.
- 0:17
Hi.
- 0:17
And, uh, we're both engineers here at Auth0, and we've both been working a lot in this, uh, the AI space lately, um, trying to come up with clear ways for identity and access control that's designed for a world where agents are center stage.
- 0:34
So that's included our work on our Auth for Gen AI platform, our Auth0 MCP server, and our own first-party agent called Tenant Security Manager. And just like everyone here, we're learning from the community as well as we do this.
- 0:47
Just the main thing is trying to get to grips with what delegation and access means in a world where agents are acting on users' behalf. Um, and today, we wanna share some of those lessons that we've learned in this journey, and, um, what's actually worked, what hasn't worked, and a few practical ways that you can get started
- 1:06
with identity and access right from the start.
- 1:10
But, uh, I had to splash this slide 'cause we were shown-- [laughs] we were told we could have opinions as long as we showed it. So here we go. To kick things off, let's talk about, uh, the security challenges of smarter agents, um, as they start to do more things in the real world.
- 1:27
And once they're moving behind-- beyond chat and actually doing things in the, in the real world, cla- cracks are starting to appear, and it's pretty clear. Secrets end up in prompts, scopes get too broad, and troubleshooting gets really, really hard when you don't have the right visibility.
- 1:43
So agents are out there making decisions, taking actions on behalf of users, but it's very easy to lose track of what's really going on. Uh, things might look fine on the surface right up until there's a security incident, and you realize you don't have enough data to trace what actually happened.
- 2:01
This is where a lot of the gen AI risks begin. The OWASP, OWASP calls it excessive agency, but really that's just a fancy way of saying giving agents too much access without guardrails.
- 2:13
And access here means calling APIs, pulling data, using tokens, touching credentials and keys. If that access isn't scoped, monitored, and tied to a real user, you're wide open to abuse and unintended behavior.
- 2:27
And there's other OWASP risks too, like sensitive data exposure, but that often comes back to the same root cause. If an agent reaches into something it shouldn't, it's usually because no one told it not to.
- 2:39
And if you've been listening to the talks here, it's pretty clear that agents aren't just responding to prompts anymore. They're actually doing real things, calling APIs, kicking off workflows, changing your systems.
- 2:51
And that means they're moving through your stack, touching real user data, interacting with real external systems. And it all needs to happen under the right context, not just on behalf of your app, but on behalf of your users, individuals.
- 3:07
Here's what this looks like in practice. Uh, on the left, you see a pattern that's very common, and an agent calling an API using a shared p-- uh, key pulled from an environmental variable.
- 3:18
Um, that key probably gets reused across users, environments, maybe even different services. It works, but it's fragile. You can't tell who did what, and rotating s- uh, secrets and keys is manual and risky, and the access is way too broad.
- 3:34
On the right, things are looking better. Instead of a shared static key, the agent asks your backend for a token that's just for the one user and one API.
- 3:43
The backend uses something like token exchange to hand out short-lived token, and the agent can safely use that. Now you've got a real record of who did what, and you can easily rotate tokens, support multiple upstream systems, and manage up-- uh, all of this in a centralized way.
- 4:00
And we've seen that this, uh, approach scales much better, even if you have dozens or hundreds of agents. It's a small tweak in your flow, but a big step up in how you handle risk.
- 4:12
So we've talked about the secrets and shared credentials problem, but underneath it all is identity. If your agent doesn't have identity, it doesn't matter how well you scope your tokens or rotate tokens, you still have-- don't have real control here.
- 4:25
And identity is what connects actions to users. It lets you understand what happened, trace the activity, and decide what should happen next. But before we talk about delegation and scope, we need to get identity right.
- 4:38
So if identity is the part we're often missing, the next question is, who is the agent actually working for? If you don't have a clear answer, chances are it's just running as a service account, and that's how you get the confused deputy problem that you've been hearing a lot about, uh, this week.
- 4:53
The agent has access, but it doesn't know who it's acting for, what it should avoid. The fix is to anchor that behavior into real users using standard flows like OAuth 2.1, RAR, uh, and token exchange to tightly control what the agent can do.
- 5:08
Um, that includes refreshing tokens properly, properly and preserving upstream identity. And here's how it works in practice. When an agent needs to act, it doesn't grab a key from a static config.
- 5:20
Instead, it, uh, asks your backend for help. The backend reaches into a vault, fetches a credential, and uses token exchange to, uh, to s-- to mint a token that's short-lived just for this user and API.
- 5:33
That token never sits with the agent. It's handed off, used, and gone. And this keeps your agent focused on doing its job, not carrying around secrets. And it lines up with familiar OWASP standards, so you're not inventing the wheel, what you should never do with identity.
- 5:47
And let's shift gears now to the RAG systems. When you're using RAG, you're not just handing data to the model, you're making choices about what it sees. And not every user should unlock the same data context.
- 5:59
This is where fine-grained authorization matters. You don't want the agent deciding access inside your LLM. You want that enforced much earlier at the retrieval layer where policy enforment-- uh, uh, enforcement can kick in.
- 6:12
So you wanna do this so that none of your sensitive data leaks out, and You keep your company and your users secure. Um, early we covered how to scope the access which agent can see, but sometimes that's not enough.
- 6:27
You also need to control when and how that a- access is provisioned. That's where Client-Initiated Backchannel Authentication, which is a mouthful, or CIBA comes in. Instead of showing a UI, the agent sends a request to the authorization server.
- 6:43
The server reaches out to the user on a trusted device via something like a push notification, and then the user decides whether to approve, deny, or ask for more information.
- 6:54
Um, this pattern is really great for agents running in the background or in scenarios where there's no screen to direct a user to. And Kam's gonna show the demo where this really comes to life.
- 7:04
So keep this flow in the back of your mind when you see that. And of course, we can't talk about secure agent execution without talking about MCP. Um, MCP servers are showing up everywhere these days.
- 7:16
What started as local standard IO input on your, on your laptop is quickly turning into a core part of remote distributed systems. And once you put it on the network, security can't be an afterthought.
- 7:30
This pattern here uses, um, OAuth 2.1 flow. The user signs in through the browser. MCP server handles the token minting behind the scenes. Agent gets scoped and bound up front, and the token is issued.
- 7:43
Client never exposes third-party credentials. The key takeaway is that when every tool and action runs on a shared server, the need for solid guarantees about who's making each request and doing what they're actually doing becomes critical.
- 7:56
All right. So to bring this all together, Kam's gonna show what this looks like in practice. He's gonna go through the, the CIBA flow and example. Kam, over to you.
- 8:04
Sweet. Thanks, Bobby. Um, lot of talking points. This is, uh, gonna be a challenging demo. Uh, so thanks for outlining some of the, uh, security and identity challenges that are facing production-grade, uh, API agent or AI agents.
- 8:16
Building on that overview, um, you can actually find this demo, uh, alongside of a ton of other really great working demos, um, at the following URL that I've got highlighted in the package JSON of this little application.
- 8:26
Um, for our scenario, we're gonna do a, a local AI trading assistant that's gonna make local tool calls to a broker service in order to buy stock, right? Uh, we tried to make this, uh, as applicable as possible.
- 8:37
Uh, the AI agent is gonna initiate the request, but the user is gonna have to explicitly approve it before, uh, it's executed. I don't have enough screens, so I'm gonna pull another one up.
- 8:44
This'll be really fun. Bear with me. All right. So, um, this is gonna really, um, emphasize three critical components for us. So we're gonna have user identification and context, which is gonna identify the user so that the agent can act on their behalf.
- 8:57
Uh, we're gonna use the token vault to, uh, prevent us from embedding any kind of like, you know, secrets or, uh, sensitive data inside of our actual code. And then we're gonna use CIBA or Client-Initiated Backchannel Authentication, uh, to request user consent before the agent executes, uh, sensitive actions.
- 9:11
It's worth highlighting, uh, this is gonna require an identity provider that supports CIBA. Um, you know, our Auth0 is the company we w- work for. Um, but importantly, like CIBA is part of the OIDC specification, so this is gonna become more ubiquitous over time.
- 9:23
Uh, so taking a look at the app that's driving this demo, um, [lip smacks]
- 9:28
zoom out a couple here. Gotta love IntelliJ. I'm gonna hide this too. There we go. Okay, so we're using a pretty simple TypeScript CLI application. Anybody speak TypeScript in the room?
- 9:40
Show of hands. Few. Okay. All right. Uh, the Python demo will come later. Um, so [chuckles] um, this is basically just gonna expose a command line interface on, uh, f- for the user, uh, which is configured with a stock trading, um, tool.
- 9:53
Let me make sure that a couple of prereqs that I need are true.
- 9:59
Bear with me one second. All right. Um, I do not see what I'm looking for,
- 10:09
but that should be fine, hopefully. Um, so, um, rolling back, um, in a more mature trading environment, it would probably look something like this. Um, so you'll have this user who's gonna specify, you know, buy some stock, um, at a certain threshold, which will get dispensed as a user action that'll interface with your, um, chatbot.
- 10:27
There'd be some sort of polling s- system that would be capable of understanding what like the real-time value of that stock trade is over time. And then it would, um, at the time where whatever threshold is defined, at that point, it would then execute the trade, and prior to executing the trade, it would dispatch a CIBA request
- 10:41
to make sure that the user is able to authenticate that, right at the, at the last mile. Um, now with today's stock volatility being what it is, it'd be a real challenge to define any reliable trade rule based on vibes and Truth Social posts.
- 10:52
So we're gonna elide, uh, certain elements of this stack. That was a joke. I hope you enjoyed that. Um, [chuckles] let's stay on the script now. Um, so we're gonna take a look at the actual application.
- 11:01
So this is the primary agent configuration and runtime definition, um, inside of this stack. You can see it's, um, bifurcated into two primary methods. You've got the generateMessages method, which is basically the handler that's interfacing between the LLM and the user.
- 11:14
Here we're passing in this buy tool, which we're gonna dig into a little bit more. [lip smacks] Um, then subsequent to that, you have the main method, which is gonna run on the main thread.
- 11:21
Here's where we're going to define the context and bind it to a particular thread for this particular session. This is gonna give us the ability to, um, durably identify who, uh, who is using this particular, um, uh, session.
- 11:35
Um, so within that, let's take a look at the actual tool call. Um, so here we have, uh, the definition of a tool call inside of, uh, this application.
- 11:45
Um, you'll note that it's wrapped in two higher order component, uh, functions. So there's this useDeviceFlow. Taking a look at that, um, this is basically how it is, um, that we are, uh, bootstrapping the OIDC, uh, wrapper within this application.
- 11:59
That's gonna enable us to have an auth client bootstrap for the application. This enables me to use access tokens on behalf of a user, basically. So there's a whole lot of configuration that goes into that.
- 12:08
Stepping back, there's another handler, this useCIBA, um, higher order component. So this is basically gonna enable, um, this application to, um, intercept a tool call in which we want the user to be able to approve or deny behavior, and that's really the h- the heart of CIBA.
- 12:22
It's also where we provide configuration information to our identity provider about how we're gonna use the resources. So in our case, we're using a blocking callback down here. Um- Which is going to, um, actually pause the application while it's running in order to wait for the approval.
- 12:36
Um, you could wire this up with an asynchronous flow or polling or however you wanted to. Um, but for the sake of this demo, this was a lot easier.
- 12:43
Uh, one last thing that I'll highlight here, uh, inside of the buy tool call, uh, the way that we're handling credentials here on line 28, um, this prevents us from embedding, um, client secrets directly inside of the code, which is a nice utility, uh, method.
- 12:56
In Auth0, we call this our token vault. Uh, it's dissimilar from like, um, like [REDACTED:password] or like a credential manager. This is managing tokens, not credentials. So, uh, just a little bit of a note there.
- 13:06
So let's get these services running. Uh, fingers crossed we don't run into, uh, any super fun Wi-Fi issues.
- 13:13
May the Wi-Fi gods be forever on our side. As that comes up, um, so even with local AI a- agents, identity matters, especially when you're using, um, multiple users with multiple agents involved, um, or if the agent has access to, you know, user data or user files, right?
- 13:28
So it's crucial to know who the, um, who is interacting with what and at what time, uh, especially like once compliance gets into this, it gets a lot more, um, robust.
- 13:36
So we're, uh, not using a fully stateful service to preserve and persist the user's identity. Um, so instead, we're gonna authenticate the users through the UI. So you'll notice that, um, little blurb will pop up.
- 13:45
After that, when the AI agent needs to perform a sensitive action, like executing a trade, we're gonna rely on CIBA. That means no additional user-facing UI is required after the u- user has given us their tokens, and I'll give you a little bit of a demo of that.
- 13:56
So we're definitely aware that identity standards like OAuth 2, OIDC, CIBA, these are not always top of mind or super interesting for developers when you're building great applications. That's why we're highlighting that there are solutions to these problems.
- 14:07
There's open standards that are evolving over time, um, and a lot of those are live today. Um, so that can be something to be thought of, uh, in the pr- progenation of an application instead of as an afterthought.
- 14:17
So one thing that we run into repeatedly while building this demo is determining just how much complexity is needed to effectively showcase, um, you know, these sorts of scenarios.
- 14:26
Um, please let us know how we struck that balance. Uh, you can email Bobby directly. Uh, he loves feedback. All right, uh, so now [chuckles] for the fun part. Let's try and buy some stocks with this, uh, if the Wi-Fi gods are on our side.
- 14:37
So, um, buy me 10 stocks of SECO, just, uh, some company. So what this is gonna do, um, is the LLM is gonna process the intent, and it's gonna select the buy stock tool.
- 14:48
The agent is going to send, uh, [laughs] I love Wi-Fi. It's my favorite thing. Um, let's see if there isn't a way around... Um, I can just sort of talk through this at a high level.
- 15:00
We'll take a look at, um, this piece of our demo. So, um, what would, what would have h- you know, ideally happened is we would execute that trade. Because we have bootstrapped our middleware inside of this application, it would prompt me to log in, and once I logged in, then the agent would have tokens to use on
- 15:16
my behalf as a user. That would then execute a trade. It's not actually executing a trade. I have like a local trade service running, so you're not missing many highlights, don't worry.
- 15:24
Um, and then once the trade, um, or once I authenticated, then CIBA would immediately dispatch a notification to Auth0's backend, and it would blow up my phone, and I would get a little notification that's like, "Hey, would you like to approve and authorize this trade?"
- 15:38
One nice thing about the notification that I get is it's not just gonna tell me, "Hey, something happened. Would you like to approve it?" And I'm just gonna be left generically in the middle of the ether trying to figure out where this notification came from.
- 15:48
It's actually gonna say, "This agent tried to do this a- action," which in this case is purchasing 10 shares of something, "on your behalf. Would you like to approve that downstream flow?"
- 15:57
And then I have the autonomy as an end user to, to determine whether or not I'm going to advance that flow or cancel that flow. Uh, one other thing that I would've shown is once I've authenticated the agent to act on my behalf, subsequent trades no longer need me, um, in the loop outside of the CIBA flow.
- 16:11
So once I've authentic- or yeah, once I've authenticated in, the authorization flow is then just dispatched to CIBA, which is pretty cool. Um, so going back to my notes, I'm gonna see how many things that I missed.
- 16:23
A bunch of things, but that's okay. Um, so in summary, we saw, well, kind of, I talked through how an agent can identify and act on behalf of a specific user, how to store and access credentials securely, um, and how to use CIBA to get explicit user approval for high-risk actions like trading without a brigh- browser to
- 16:39
be required. Um, so these patterns are live. Um, they exist in defined standards like OIDC, CIBA, um, Rich Authorization Requests. Auth0, um, developer previews have like, um, attempts at a lot of these things or actual production versions of a lot of these things, so I'd encourage you guys to check some of those things out.
- 16:55
Um, and some of these are GA. Like our, uh, CIBA, I believe, is GA or at least in early access, um, inside of our platform, so that's pretty cool.
- 17:01
Um, thanks. That's, uh, my demo.
- 17:04
All right. So just moving back here. Go to the next slide.
- 17:08
Cool.
- 17:10
As Kam was saying, like we're, we're trying to make this easier for, for developers. Um, the standards are great. It means you're not reinventing things over and over again.
- 17:19
But there's still a lot of building blocks that you would have to build. The Auth0, other platforms have similar things, but we're, we're trying to wrap this all up in a nice experience for developers.
- 17:29
So the async user confirmation with CIBA is like a very key component here, uh, as well as calling APIs on behalf of users, things like token exchange and token vault, as well as fine-grained authorization for RAG.
- 17:43
You don't have to use our platform for this. We have OpenFGA that can snap into this type of thing as well. Um, and user authentication and authorization generally is, is something that we do, we think deeply about.
- 17:57
And with that, here's what you can take with you. There's a nice QR code, and we'd love to talk to anyone who's struggling with these challenges, what you've hit, uh, in your, in your, in your d- day-to-day life.
- 18:12
Just come talk to us after the talk. Um, I'm, I'm also part of the Open MCP spec, uh, driving some of those discussion as well. We're very interested in improving that for everybody, so it's not just about Auth0.
- 18:25
Working with other, um, open source libraries like MCP Auth, which is another great thing. So very deeply interested in this space.
- 18:34
Thanks everyone.
- 18:34
Thank you