Your AI agent has your production credentials. That's the actual problem.
In December 2025, Amazon's internal AI coding assistant Kiro deleted a production environment in AWS Cost Explorer. The outage lasted 13 hours and hit services across mainland China. Kiro decided the fastest path to fixing a bug was to tear down the environment and rebuild it from scratch. Efficient reasoning, catastrophic outcome.
The root cause wasn't an AI gone rogue. Kiro normally requires sign-off from two engineers before touching production. But a human operator had granted the agent their own elevated access credentials. Kiro inherited those permissions, skipped the two-person approval gate, and executed with the full authority of a senior engineer.
Amazon called it human error. Sure. The human made the mistake. But the failure mode, an agent inheriting overprivileged credentials from the person who invoked it, is how most agent deployments work today. The mistake isn't that someone misconfigured Kiro. The mistake is that the default configuration makes this inevitable.
The identity model is broken
We've spent the last year talking about MCP security in terms of unvetted servers and prompt injection. Those are real problems. But the one that's actually deleting production databases is more mundane: agents act with the wrong identity and the wrong permissions.
An agent needs to call an upstream API. Someone configures a credential, usually a static API key or the invoking user's OAuth token. The agent uses that credential for everything. No scoping. No per-task restriction. No distinction between "read this record" and "delete this environment."
53% of MCP servers still rely on static API keys. A static key can't tell you whose authority the agent is acting under, or with what scope, or for how long. It's a skeleton key in a system that needs a locksmith.
The other 47% aren't much better off. Most pass the invoking user's token straight through to the upstream API. The agent acts as you, with your full permission set. If it gets confused, compromised, or just interprets "clean up old resources" a bit too literally, the blast radius is your entire access footprint.
Permission inheritance is the default failure mode
The Kiro incident wasn't unique. At SaaStr in July 2025, a coding agent deleted a production database because it had write access it didn't need and nobody could revoke it at the right granularity. Static credential, broad permissions. The agent used them.
Wing Security documented a case at a ~1,000-person company where a marketing AI agent on Databricks returned detailed customer churn data to an employee named John. John's own account was explicitly blocked from accessing that data. Didn't matter. The agent operated under a shared service account with broad read access. John asked, the agent fetched. In the audit log, the agent accessed the data. Who actually requested it and whether they were authorized? Invisible.
This keeps happening because it's the default: agents inherit broad credentials, act under a shared identity, and collapse the user-permission boundary that security teams built over decades. It's the same infrastructure gap that kills AI projects, just wearing a different hat. 88% of organizations reported confirmed or suspected AI agent security incidents in the last year. Only 24.4% have visibility into which agents are even communicating with each other.
Why "just use OAuth" is harder than it sounds
The MCP specification adopted OAuth 2.1 for authorization in its June 2025 revision. In theory, problem solved. Except the spec has drawn serious criticism for blurring the line between authorization servers and resource servers, forcing MCP servers to manage token issuance, maintain state, and run secure databases for token storage.
Christian Posta's take is blunt: the spec requires each MCP server to become its own authorization provider. For enterprise deployments where centralized identity management through Okta, Azure AD, or Auth0 is standard, that's a non-starter.
The architecture that works separates these concerns. Your MCP server is a resource server. It validates tokens. It never issues them. An external identity provider handles the login, consent, and token lifecycle. The MCP server just checks the receipt.
But there's a second token relationship that most implementations skip entirely. Your MCP server also needs to call upstream APIs on the user's behalf. That requires a separate credential, obtained through its own OAuth consent flow, scoped to what the user authorized, stored server-side. The user consents once. The server uses that token to execute operations with the user's upstream permissions.
Two tokens, two trust relationships. Token A: the agent authenticates to your MCP server. Token B: your MCP server authenticates to the upstream API on behalf of that specific user. The user's upstream RBAC, audit trail, and permission boundaries apply to every operation. No credential inheritance. No shared service accounts.
What proper agent authorization looks like
Oso, ScaleKit, Stytch, and Microsoft's Entra Agent ID have all published auth models for agents recently. They land in roughly the same place.
The agent doesn't get the user's token. It gets a scoped downstream token issued on the user's behalf, with explicit permission boundaries. The On-Behalf-Of (OBO) flow exists for exactly this. The agent presents the user's token to the identity provider, which issues a new token scoped to what the agent actually needs for this operation. Not the user's full access. Just what's required right now.
Credentials should be just-in-time. Fresh tokens per task, revoked after completion. If the agent needs to read a calendar entry and send an email, it gets a calendar:read token, does the read, then gets an email:send token for the send. Not a permanent credential that covers both.
Audit trails need to trace back to the human. The log should show "user X initiated action Y through agent Z," not just "agent Z did something." The user's identity is embedded in the delegated token. That's what makes this traceable.
And even with all of that, agent code should run in a sandbox. No filesystem, no network, no host access. Tool calls are the only way out, each carrying its scoped credential. If the agent is compromised, there's nothing to escalate to.
We've been working through exactly this at Hintas. Each tenant's MCP server validates JWTs from the customer's own IdP. Upstream API calls use per-user tokens from a separate consent flow, so the customer's existing RBAC applies and we don't need to build a permission layer on top. Agent code runs in V8 isolates with no ambient permissions. Getting this right has been the hardest part of the infrastructure work, honestly, harder than the MCP protocol stuff.
The gap is closing, slowly
Microsoft shipped Zero Trust for AI last week. AWS published Well-Architected guidance for agentic permissions. InfoQ documented a least-privilege gateway pattern using MCP with OPA and ephemeral runners. The guidance exists now.
But guidance published and guidance followed are different things. Most agent deployments still run on static keys and inherited credentials. The Kiro incident made headlines because it hit AWS. The smaller ones, the John-sees-payroll-data cases, the agent-drops-a-staging-table cases, those happen quietly every week.
If you're deploying agents against real APIs today, the question to ask is simple: can your audit trail tell you who asked for an action, or just which service account ran it? If the answer is the latter, you have the same problem Kiro had. You just haven't hit the wrong button yet.
If you're interested in early access, reach out at hintas.com.

