The rogue agent panic
Open social media or tech news right now, and you will find a wave of breathless panic about autonomous AI agents. Developers share stories of multi-agent swarms gossiping on private message protocols, agents colluding across channels, subagents attempting to break out of Docker sandboxes, and autonomous loops burning through thousands of dollars in minutes.
The instinct from many teams is either to pull the emergency plug or to wrap the agent in fragile, heuristic regex filters.
Both responses miss the real architectural failure. The problem is not that LLMs have agency. The problem is that we are deploying autonomous software with ambient, unowned, unmonitored credentials.
Yet, when an AI agent is spun up (an autonomous entity capable of querying databases, refactoring repositories, reading customer records, and triggering downstream APIs), it gets treated like a stray shell script. It runs with an ambient API key sitting in plain text in a .env file.
If an agent acts with agency, executes tools, and consumes budget, it is not a script. It is an Agentic Employee. It needs the exact same Zero Trust identity architecture we give human employees.
This is the core problem Langfuse co-founder Mark Klingen spotlighted: how do corporate security teams approve personal agents, keep an authoritative audit log in Okta/Auth0, and immediately kill suspicious behavior?
Agent Identity Gateway is a working, open-source reference implementation that proves how to do it.
The dual-layer observability thesis
Security teams often think observability is just network logs. AI engineers think observability is just prompt traces. Both are blind to half the system.
To govern an autonomous agent, you must bind two distinct layers:
Layer 1: Identity Plane (Auth0)
Proves WHO ran and under what enterprise authorization.
- Registered Machine-to-Machine (M2M) application in the IdP
- Approval gate controlled by security admins in the IdP dashboard
- Tenant audit log (
seccft) recorded on every token grant - Downscoped, role-based OAuth 2.0 scopes
- Instant grant revocation via the Management API
Layer 2: Execution Plane (Langfuse)
Proves WHAT the agent did with that authorization.
- Node-by-node execution spans with precise latency
- Every input prompt, system context, and model generation
- Token counts (input, output, reasoning)
- Exact per-step dollar cost tracking on Gemini / Vertex AI
- Deep-linked trace URL for full post-run forensics
System architecture: Zero Trust fail-closed topology
The gateway is built on LangGraph as a deterministic state machine. Security approval is treated as a hard gate before any model computation begins:
Core Zero Trust Principles Applied
-
Approval as Data, Not Code: Security administrators govern the agent live from the Auth0 dashboard. Toggling
security_approvedimmediately permits or blocks runs without changing a single line of code or restarting a container. - Fail-Closed by Default: If the metadata flag is false, if the metadata key is missing, or if the IdP Management API is unreachable, execution halts instantly.
-
Explicit HTTP Boundaries: The identity layer uses raw
httpxrequests. There are no opaque SDK layers hiding token refreshes, swallowed exceptions, or unvetted retries. - Unconditional Evidence Generation: Every run (completed, blocked, kill-switched, or crashed) emits a permanent JSON record. In an enterprise security model, an unlogged failure is an unacceptable blind spot.
The approval gate in action
Let us look at how this behaves in practice. An engineer attempts to trigger an unapproved agent run:
╭─────────────────────────── approval gate ───────────────────────────╮
│ BLOCKED │
│ security_approved = false │
│ Agent is pending approval: set security_approved=true in Auth0 │
│ │
│ Approve here: │
│ https://manage.auth0.com/dashboard/us/dev-tenant/applications/... │
│ → Application Metadata → security_approved = true │
╰─────────────────────────────────────────────────────────────────────╯
Evidence file : evidence/run_097ff8f7.json
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AGENT IDENTITY GATEWAY: Run 097ff8f7
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Auth0 Identity : dev-26hkl488x5wkdykr.us.auth0.com
Client ID : JMeTKUdhICoe3hHTjG2fudA1QTh9STLj
Approved : ✗ NO (security_approved=false)
Outcome : REJECTED
Total Cost : $0.0000
Evidence File : evidence/run_097ff8f7.json
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Notice what happened:
- The agent authenticated its identity, but the gate blocked downstream execution before calling any LLM.
- Zero LLM tokens were consumed ($0.0000 cost).
- An auditable evidence record was immediately written, giving SecOps full visibility into the rejected attempt.
Now, the security admin opens Auth0, inspects the requested scopes, navigates to Application Metadata, and sets security_approved = true. Without touching the agent runtime, we re-run:
╭─────────────────────────── approval gate ───────────────────────────╮
│ APPROVED: Agent is approved (security_approved=true in Auth0) │
╰─────────────────────────────────────────────────────────────────────╯
Evidence file : evidence/run_f44a18a9.json
Langfuse trace : https://us.cloud.langfuse.com/trace/f685413b4d3b4bc5a484931005fad66c
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
AGENT IDENTITY GATEWAY: Run f44a18a9
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Auth0 Identity : dev-26hkl488x5wkdykr.us.auth0.com
Client ID : JMeTKUdhICoe3hHTjG2fudA1QTh9STLj
Approved : ✓ YES (security_approved=true)
Task : Zero Trust for AI Agents
Outcome : COMPLETED
Total Cost : $0.0003
Langfuse Trace : https://us.cloud.langfuse.com/trace/f685413b...
Evidence File : evidence/run_f44a18a9.json
Killswitch : NOT FIRED
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Summary:
• Replace static API keys with short-lived machine credentials via SPIFFE/SPIRE.
• Enforce dynamic Policy-as-Code and downscoped OAuth token delegation.
• Eliminate static secrets and implement continuous behavioral monitoring.
The evidence record: Correlating identity with execution
Blog readers do not need 50 lines of raw JSON curly braces. What matters is the correlation between the enterprise identity log and the cognitive execution trace:
At 05:52:49.760Z, Auth0 logged the seccft event for client credentials exchange. Immediately following, Langfuse recorded prompt and completion spans across Gemini 3.7 Flash, totaling exactly $0.000256.
If an internal auditor reviews this run months later, there is zero guesswork. The Auth0 audit log and the Langfuse execution trace confirm each other.
The kill switch: Stopping runaway behavior
What happens when an agent starts looping or spamming downstream APIs?
In typical setups, rate limits kick in or API bills quietly escalate. With the Agent Identity Gateway, anomalous traffic triggers an automated, identity-level revocation:
│
├──► DELETE /api/v2/client-grants/{grant_id} (Revokes OAuth grant in Auth0)
│
├──► PATCH /api/v2/clients/{id} metadata (Flips security_approved to false)
│
└──► WRITE EVIDENCE >> OUTCOME: KILLSWITCH (Zero further model execution)
The gateway revokes the agent's OAuth 2.0 client grant via Auth0's Management API and sets security_approved = false. Even if the process remains active in memory, it cannot refresh tokens or access enterprise resources.
To protect developer environments, the kill switch defaults to dry-run mode (KILLSWITCH_DRY_RUN=true), identifying the targeted grant without deleting it. Setting KILLSWITCH_DRY_RUN=false arms real grant deletion.
What each stakeholder gets
Enterprise governance works when it aligns with the priorities of every team involved:
| Stakeholder | Core Problem Today | What Agent Identity Gateway Delivers |
|---|---|---|
| CISO & SecOps | Ambient API keys proliferating across dev laptops with no ownership or revocation path. | Agents as first-class M2M applications in Auth0, with instant approval and revocation from the IdP dashboard. |
| AI Platform Engineer | Hardcoding custom auth logic, token stores, and fragile rate checks into every agent. | A clean LangGraph pipeline contract where authentication and gating reside in separate, testable nodes. |
| Compliance & Audit | Fragmented terminal logs when answering who authorized an LLM action. | A single evidence record per run binding the official Auth0 audit event (seccft) to the Langfuse trace. |
| FinOps & Finance | Aggregate cloud bills with zero visibility into which team or agent drove costs. | Per-run dollar attribution linked directly to the registered M2M client ID ($0.000256 per execution). |
| AI Developer | Lengthy security reviews because agent architectures are seen as ungoverned black boxes. | A compliant blueprint ready on day one. Run python main.py --approve and share the URL with security. |
Engineering takeaways
Building this reference implementation surfaced three practical engineering realities:
1. Avoid heavy SDK abstractions in the security perimeter
When handling identity exchanges, pulling in heavyweight SDKs can introduce opaque token caching, hidden retries, and swallowed exceptions. In auth0/auth.py and auth0/lifecycle.py, we used raw httpx requests. Every header, timeout, and status code remains visible and testable.
2. Never log tokens, always log metadata
Developers often leak bearer tokens into console logs when debugging agent failures. Our test suite includes explicit assertions confirming that raw token strings are never written to stdout or evidence files, recording only token types, expiry durations, and granted scopes.
3. Failures are first-class evidence
If an agent crashes without writing an audit record, the observability system failed. Our runtime guarantees that whether a run halts at the approval gate, trips the kill switch, or encounters an upstream model error, an evidence record is always written.
The lesson
The complete code, test suite (14 passing unit tests covering all gates, kill switches, and edge cases), and live evidence files are open source on GitHub.