-
-
Admin dashboard with agent overview, activity feed, and governance metrics.
-
Agent Registry showing each agent's permissions, provider, and high-stakes actions.
-
Agent settings with effective access summary, inter-agent access, and scope toggles.
-
Inter-agent permission matrix enforced at runtime. Click any cell to configure.
-
Configuring permitted actions between two agents with inline enforcement testing.
-
Live test results confirming inter-agent enforcement for Calendar to Gmail actions.
-
Security audit log with filters, status badges, and Security Report Agent controls.
-
Autonomous Agents page with Stale Issue Monitor, scan/act controls, and test mode.
-
Stale Issue Monitor results with CIBA approval required before acting on issues.
-
Dynamic evaluation suite generates tests from live permission state automatically.
-
Slack bot triggers Guardian push notification for high-stakes email send.
-
Multi-agent meeting prep: Calendar, Gmail, and Drive agents with inter-agent enforcement.
Inspiration
At my workplace, we use several AI agents. Each one manages its own dashboard, its own credentials, its own access controls. If I want to check what an agent did last week, I have to go into that specific agent's dashboard. If I want to revoke access, I have to find the right settings page for that specific agent. Multiply that by four agents and it gets old fast.
When I saw the Authorized to Act hackathon, it clicked. The problem I'd been living with every day at work had an actual solution shape. No shared audit trail. No centralized permission management. No way to say "this agent can read emails but not send them" without digging into each agent's individual config. Each agent was its own island, and nobody had a map.
That's where ctrlAI came from. Why can't I manage all my AI agents from one place? One dashboard where I can see every agent's identity, toggle their permissions, control which agents can talk to each other, and review a single audit trail of everything that happened. And thanks to Auth0's Token Vault, I didn't have to build the entire OAuth and token management layer from scratch. Token Vault handled the credential storage and token exchange, which let me focus on the governance layer on top of it.
What It Does
ctrlAI is an identity and permission control plane for AI agents. It governs six agents (Gmail, Drive, Calendar, GitHub, Security Report, and Stale Issue Monitor) from a single dashboard.
Here's what a single request looks like end to end: an employee messages the Slack bot "Send an email to Sam about the meeting." The LangGraph orchestrator routes it to Gmail Agent, checks that Gmail Agent is active and has the send_emails scope, retrieves a token from Token Vault, detects that sending email is a high-stakes action, fires a CIBA request through Auth0, and the admin gets a Guardian push notification on their phone. The agent waits. If the admin approves, the email gets sent. If not, nothing happens. The entire sequence is logged to the audit trail and visible on the admin dashboard.
The control plane: A Streamlit admin dashboard (Dashboard password: auth0) where you manage the entire agent ecosystem. Toggle scopes on and off, suspend agents with one click, edit the inter-agent permission matrix, view a filterable audit log, run the dynamic eval suite, and trigger autonomous agents. The dashboard has 7 pages and every permission change takes effect immediately on the next request.
Employee access: In this demo, employees interact with agents through a Slack bot using natural language. Slack is just one channel. The same governance applies regardless of how employees reach the agents.
How I Built It
The backbone is Auth0 Token Vault. Every agent gets its OAuth token from Token Vault at execution time, only after the permission layer confirms the agent is allowed to perform the requested action. Three Google agents share one OAuth connection and two GitHub agents share another, but each agent has independently scoped permissions. The governance happens at the agent identity level, not the provider level.
A quick note on how Token Vault fits in: the agents use Token Vault's token exchange to get provider access tokens at runtime. The Connected Accounts linking step (where a user connects their Google or GitHub account to Auth0) originally used the /me/v1/connected-accounts endpoint, but that was in Limited Early Access during the hackathon. I implemented that specific step using the Management API with read:user_idp_tokens as a workaround. The token exchange that agents use at runtime is Token Vault's standard flow.
The orchestrator is a LangGraph state machine with six nodes: router, permission gate, token retrieval, CIBA checkpoint, agent executor, and response formatter. Conditional edges route to error handling if any check fails. The permission gate is the critical node. It runs a chain on every request: does this agent exist, is it active, has it exceeded rate limits, does it have the required scope, does it have a temporary grant. All of this happens before any API call is made.
For high-stakes actions (sending email, deleting files, posting public comments, creating events), the system uses Auth0 CIBA with Guardian push notifications. The agent pauses, the admin gets a push on their phone, and the agent only proceeds after explicit approval.
Inter-agent communication is governed by a deny-by-default permission matrix. I'm really proud of this one. The idea came from thinking about how microservices communicate in production. You don't let Service A call Service B without an explicit contract. Why should agents be different? The meeting-prep workflow demonstrates this: Calendar Agent asks Gmail Agent for email context (allowed), then asks Drive Agent for related files (denied, not in the matrix). The final briefing transparently reports both.
The eval suite generates tests dynamically from the live permission state. Change a permission, run evals, and the test suite adapts. Four enforcement tests actually mutate live state (revoke a scope, suspend an agent, remove inter-agent access) to prove the system responds correctly, then restore everything in try/finally blocks.
Challenges I Faced
Token Vault's Connected Accounts endpoint was in Limited Early Access. The /me/v1/connected-accounts endpoint returned 404 on my free tier tenant with no indication that the feature wasn't available on the free tier. Once I confirmed it was a platform limitation (not a code issue), I implemented the Connected Accounts linking using the Management API with the read:user_idp_tokens scope instead. The workaround actually gave me a deeper understanding of how Token Vault handles token exchange under the hood.
Cross-process state sharing for real-time permission enforcement. The Slack bot and Streamlit dashboard run as separate processes. When an admin revokes a scope on the dashboard, the next employee message through Slack has to be denied immediately. Not after a restart, not after a cache expires. I solved this with JSON file persistence that both processes read on every request. The design problem wasn't the storage mechanism. It was ensuring that permission enforcement is always consistent across processes in real time.
What I Learned
I went deep on the authorization side of AI agents and came out understanding something I didn't before: giving agents access to APIs is the easy part. Keeping track of what each agent can do, what it actually did, and being able to revoke access instantly is where it gets hard.
I also learned a lot about inter-agent communication as a security surface. Most agent frameworks treat agent-to-agent calls as trusted internal behavior. But if Agent A can freely ask Agent B to do anything, you've created an internal attack surface that no one is monitoring. The deny-by-default matrix was the answer, and building it changed how I think about multi-agent systems.
Working with CIBA was eye-opening. Most agent frameworks support human-in-the-loop, but it's usually a confirmation button in the same UI. CIBA is different. The approval goes through Auth0's identity infrastructure, the admin gets a Guardian push notification on their phone, and the agent waits for an identity-verified response. The user doesn't even need to be in the same interface.
What's Next
ctrlAI currently governs six agents across two OAuth providers. The architecture is built to handle more. The roadmap includes dynamic agent registration (no code changes to add new agents), role-based policy rules instead of per-agent matrix entries, database-backed persistence with SIEM integration, and natural language permission management from the Slack interface.
Organizations are adopting AI agents because they genuinely help. But without governance, you end up where I was at work: four agents, four dashboards, four separate permission systems, and no unified view. That's the problem ctrlAI solves.
Bonus Blog Post
Building Agent Governance on Auth0 Token Vault: Patterns and Discoveries
Most conversations about AI agents focus on what agents can do. This post is about what happens when you flip that question: what should agents be allowed to do, and who decides?
When I started building ctrlAI, I assumed Token Vault was a secure credential store. It is, but there's a more interesting property hiding underneath. Token Vault adds a layer of indirection between the agent and the credential. The agent doesn't hold the token. It requests one through a token exchange at runtime. That indirection is what makes governance architecturally possible. If every credential request goes through a gateway, you can put policy enforcement at that gateway. That's the core pattern ctrlAI is built on.
The most surprising discovery was how the Connected Accounts flow works (and doesn't work, if you're on a free tier). The /me/v1/connected-accounts endpoint was in Limited Early Access, which meant my tenant got a 404 with no explanation. After debugging, posting on the hackathon Discord, and reading through the Auth0 Management API docs more carefully than I ever expected to, I used the Management API read:user_idp_tokens path as a fallback for provider token retrieval when the Connected Accounts flow on my tenant returned 404. What I learned is that Token Vault's runtime token exchange and the Connected Accounts linking flow are two separate operations. Understanding that separation was key to making the whole architecture work.
CIBA (Client-Initiated Backchannel Authentication) was the integration I'm most proud of. In most agent frameworks, human-in-the-loop means a button in the UI. Auth0's CIBA sends a Guardian push notification to the admin's phone, and the agent pauses until an identity-verified approval comes back. The approval is tied to the user's Auth0 identity, not a session cookie or a UI state. That's a fundamentally different trust model than what most agent frameworks offer.
The pattern I want to highlight for the Auth0 community: agent-level scope governance on top of shared provider connections. In ctrlAI, three agents share a single Google OAuth connection through Token Vault, but each agent has different permitted scopes enforced at the application layer. Gmail Agent can read and send. Drive Agent can list and delete. Calendar Agent can read and create. The provider token is the same. The governance is different.
If Token Vault natively supported per-identity scope restrictions on shared connections, meaning the vault itself could return tokens scoped to what a specific agent identity is allowed to do, it would eliminate the need for application-level governance entirely. That would be a powerful primitive for anyone building multi-agent systems on Auth0.
One more observation: inter-agent communication is an underexplored security surface. Most frameworks treat agent-to-agent calls as trusted. ctrlAI treats them as governed. Every inter-agent request is checked against a deny-by-default permission matrix, logged, and blocked if not explicitly permitted. I think this pattern matters as multi-agent systems grow in complexity, and I'd love to see Auth0 explore identity-based inter-agent authorization as a first-class feature.
That's what I took away from building ctrlAI. Token Vault gave me the credential layer. The governance on top of it was the interesting part to build, and I think it's a pattern worth exploring further.
Log in or sign up for Devpost to join the conversation.