Learning Behind the Wheel - My Journey Towards Better Understanding AI Governance
- Mike Woodburne
- Jun 21
- 8 min read
"AI agents should be governed as identities"
This has been the refrain from IAM vendors in recent months, and on the surface it makes complete sense. We need to treat AI agents as first-class identities with a clear understanding of what they are capable of doing and in which of our systems they are operating, while maintaining a clear audit trail of not only what they are doing but also who they are doing it for. But how do we do that? Is there a set of tools we can use to accomplish this? And if so, how do we use them?
I will admit to not being the most savvy person out there when it comes to AI, but in recent months I have had a greater need to use AI professionally and I can clearly see how an improperly governed agent could be problematic. With nearly everyone I speak with running some form of agentic workflows in their place of business the likelihood of some of them being ungoverned or improperly governed is high, as is the impact should one of these agents opt to test the boundaries of their access. The risk is high, and that's motivation enough to learn the ropes so I can help others get a handle on their AI problem.
I kicked off my learning journey by identifying what I wanted to learn and how I wanted to learn it. What did I want to learn? I wanted to learn how an AI agent can be governed while following current best practices, and I wanted to be able to demonstrate that an agent can function cleanly without having uncontrolled access to resources. As is often the case with me, I wanted to learn by doing, so I planned on creating a fully functional demo consisting of:
An API protected as an OAuth2 resource server, with endpoints requiring properly scoped access tokens
An agent integrated with an LLM which interprets a user's request, consumes data from the API, and produces a response, while following best practices around least privilege and short time-to-live for access tokens
I intentionally kept the scope for this limited, although in the future I'd like to explore SPIFFE for authenticating the workload and Human-in-the-Loop for high-risk actions
I opted to not implement an MCP server for this, simply to keep things simple. The recent release of Enterprise-Managed Authorization for MCP is definitely something I want to get my hands dirty with, as I think this is a huge change
This agent will be managed in PingOne Advanced Identity Cloud, utilizing the long standing capabilities of OAuth token generation and RFC 8693 token exchange, as well as the newly introduced capabilities for modeling AI Agents as OAuth2 clients with their own identities and privileges
A UI which can be used to orchestrate the demonstration of capabilities, because frankly it makes for a nicer demo than a CLI
Every good demo needs a story to tell, so I laid out some basic story points I wanted to hit on:
A user logs in
A request is made to the PTO endpoint to get PTO details but is denied due to not having a properly scoped token
User exchanges their current token for a newly minted token containing the proper scope
User requests data from the salary endpoint but is denied due to not having a properly scoped token
User exchanges their current token for a newly minted token containing the proper scope
The longer term goal being to turn the flow to:
User logs in
User asks agent to perform various data retrieval actions
Agent identifies the scope needed for each action requested, and for each action performs token exchange to get an appropriately scoped token with a short lifespan
I decided right off the bat that I wanted to keep the core pieces as simple as possible (a noble ideal to lead with, no matter what may come) so I created a couple of basic endpoints capable of returning information about a static employee user object that lives in memory - a get PTO endpoint and a get salary endpoint, with access to each endpoint controlled by a scope (pto.read and payroll.read, respectively). I created these APIs with Python's FastAPI framework, along with some static token objects that I could use via the Swagger UI (passing in static strings as "bearer tokens"). In addition to these functional endpoints I also created a number of endpoints that could be used for demo purposes to showcase details about the selected token, an endpoint for a fake token exchange, and an endpoint integrated with AIC so I could get tokens for a real user. Once I had these built out I started looking at building a basic UI that I can use to call these endpoints with my static tokens.
The UI itself is a very basic HTML page, which started with a dropdown to select a token and some buttons that will call the various endpoints so I could talk through a story, with a section for displaying the JSON response of the various calls being made. A little CSS was added to make the page more presentable, and I had the framework for a demo.
Next up I needed to introduce real security into these endpoints. Rather than relying on hard coded tokens, I wanted to utilize a real OAuth client with real scopes configured in P1AIC. In addition to the OAuth client I configured for my demo UI to enable login, I created an OAuth client which my resource server can use for introspecting opaque tokens and I created it as a regular OAuth client in P1AIC. I knew that I wanted the client that will be used by my agent to be governed appropriately, so I explored the new AI Agent capability in P1AIC.
The AI Agent capability in P1AIC allows you to create a managed object with a named agent complete with an owner (a relationship to a managed user object) and an OAuth client which is configured just like a regular OAuth client. In addition to this, you can assign the agent to an Application (my demo UI), choose who it can act on behalf of (which can be individual users or groups), and most importantly you can identify the Application permissions the agent is allowed to use. This means that I have the ability to use token exchange to take my human subject's access token, my agent actor's access token, and exchange those for a newly minted access token with the appropriate scope assigned to it and - more importantly - the appropriate sub and act claims. This is where the real controls are implemented and where I now have the ability to take my short lived (30 seconds - could be shorter) access token with limited scope and exchange it on behalf of a human actor for another short lived access token with a limited scope.



Once I had these clients set up the demo was reworked to no longer use endpoints with pretend security and instead utilize tokens minted by P1AIC to access resources, and when the agent's access token lacks permissions to access the payroll endpoint it now has the ability to perform a real token exchange to get a token with the scope needed to complete its task. This is where it felt like a real demo that I could use to showcase how AI agents can have their access granted and managed in a manner that is secure and scalable. This was, of course, not enough for me. I wanted to wire this up to a real LLM.
The first step was to get an OpenAI compliant LLM running locally (because really, who wants to be paying for tokens while learning how this all works?) which I did with LM Studio. I had originally installed it on an old HP zBook with 2 GB vRAM and 16 GB system ram, but that laptop is about 12 years old and the poor thing couldn't handle the work. I learned enough about running a local LLM through that process and I felt comfortable with running one on my primary laptop so I set that up and downloaded the google/gemma-4-e4b model to work with. After a bit of work I had my agent running and interacting with the LLM to generate a plan for how to handle the user's input with the tools made available to it, as well as process the results of the API calls to generate a response for the user. This, combined with some more polish on the UI to showcase what the agent was actually doing, had me fairly convinced that this governance model was a tremendous step in the right direction. Despite the agent being aware of the tools available to it and knowing there is a pathway to delegate tokens, the agent did not attempt to circumvent its own controls and attempt to acquire a broader scoped access token, nor did it attempt to take any actions outside of what it was written to do. At this point I feel that it is worth pointing out a very important point - these guardrails have just as much to do with how the agent was written and the instructional prompts it was given as it has to do with how the agent's identity is controlled within P1AIC. P1AIC does not provide some sort of magical bullet that will prevent AI agents from running amok, but it does provide you with the tools and controls you need to be able to write an agent that operates following best practices while also being governable and auditable.
The demo itself isn't much to write home about if you are looking for pizzazz and high stakes transactions, but it helped me to better understand not only how AI agents interact with a system like P1AIC as well as how P1AIC gives us the tools we need in order to enforce the guardrails we build within our agents.
A few key points I'd like to call out about the flow, which hopefully help drive home the point of the demo:
The agent's initial request for a token uses a scope representing no access. If P1AIC supported requesting a token with no scopes I would have done that to showcase that we are starting from the most limited scope possible.
The agent only exchanges access tokens when necessary, and only for a new token containing the scope needed to perform the requested task
Every time the agent exchanges a token, it does so using the subject token of the logged in user. This ensures that any actions taken using this token can be accurately logged to show the agent was acting on behalf of an authenticated user.

And now, the demo itself.
tl;dr:
While it isn't some sort of magic bullet that prevents your AI agents from running wild, the tooling available in platforms like PingOne Advanced Identity Cloud provide you with the ability to simplify the process of securely exposing your AI agents to functionality that will (hopefully) increase productivity, all while allowing you to easily govern and audit the activity. Developers of these agents are still going to need to understand the concepts around token exchange and should be maintaining their own logging systems to correlate agent activity with your IAM platform's own logs, but platforms like P1AIC are helping to make their jobs a lot easier.
Note:
I'm not going to pretend that I figured out how to wire this all together without a little help. Heck, I'm not even going to pretend that I wrote a lot of this code myself. My approach for all of this has been to work along with an AI tool which provided me with recommendations on design patterns and suggestions on next steps. I prefer this to just letting Claude Code, Codex, or some other tool write all the code without giving me time to review and provide my feedback on what it has suggested, as I find it helps me to better understand the code if I am reviewing it while it is being implemented. The end result is that I am far better prepared to maintain the code going forward, while at the same time accelerating my development process. When it comes to AI (and most things in life, really) - to each their own.

Comments