Skip to content
Open to board advisory and board seats — 2H 2026, then CY 2027–2028.
See details →
Writing

MCP Is a New Attack Surface: An Operator's IAM Playbook

Every MCP server you stand up is a new identity reaching into your cloud. The control that decides whether that's leverage or liability isn't the model — it's least-privilege IAM on every tool call.

By Michael YorkApril 13, 2026 5 min read 1,088 words All postsTable of contents

There's a comfortable assumption floating around about agentic systems: that the risk lives in the model. We worry about prompt injection, hallucinated commands, jailbreaks — the language layer. That's where the demos go wrong, so that's where the attention goes. I think that's a misread of where the actual blast radius is.

When an agent reaches into AWS through the Model Context Protocol, the model is just the thing that decides what to ask for. The MCP server is the thing that decides what's possible. And what's possible is a function of one boring, decades-old control: the IAM permissions sitting behind that server. MCP didn't invent a new class of vulnerability. It did something more dangerous — it gave a non-deterministic caller a credential and a catalog of tools, and then we mostly handed it the same broad role we hand a CI runner because it was faster.

The real mechanic: a server is an identity, not a feature

Here's the reframe I keep coming back to. People treat an MCP server like a plugin — a convenience layer that lets the assistant "do AWS things." It is not a plugin. It is a new principal in your environment, with a credential, a network path, and a set of capabilities, that takes instructions from a probabilistic process that an outsider may be able to influence through your own data.

Once you see it that way, the whole problem snaps into the discipline we already know. The question is never "is the agent safe?" The question is the same one we ask of every other identity: what can this thing do, on what resources, under what conditions, and can I prove it after the fact? If you can't answer that for an MCP server, you've deployed an unscoped service account with a chat interface. We spent fifteen years killing those. Don't reintroduce them because the wrapper is exciting.

The trap is the convenience role. Someone stands up an MCP server for "read-only AWS access," attaches a managed policy that's read-only in name, and ships it. But ReadOnlyAccess in AWS includes the ability to read Lambda source, Systems Manager parameters, S3 object contents, and a hundred other things that are absolutely not benign to exfiltrate. Read-only is a confidentiality control, not a safety guarantee. An agent that can read everything is an agent that can be talked into describing everything to whoever is steering it.

The playbook: scope at the call, not the server

So here's how I'd wire it. Not theory — the pattern I'd defend in a control review.

One IAM role per server, never a shared one. Each MCP server gets its own principal with its own policy, so its permissions are legible in isolation and its actions are attributable in CloudTrail without forensic guesswork. The moment two servers share a role, you've lost both least privilege and your audit trail.

Use real credentials, not long-lived keys. On AWS that means IAM Roles Anywhere or an OIDC trust to your identity provider, vending short-lived session credentials. A static access key pasted into an MCP config file is the 2026 version of a password in source control. If the server runs in your own compute, give it an instance or task role and let the metadata service do the rotation.

Scope the policy to the tools the server actually exposes. This is the part people skip. If your server offers three tools — list buckets, read a specific config object, describe an RDS instance — the policy should grant exactly those actions on exactly those resource ARNs, and nothing else. The IAM policy and the tool manifest should be readable side by side and tell the same story. When they diverge, the policy is the lie.

Push the conditions you actually have. Least privilege isn't only actions; it's circumstances. Use IAM condition keys — source VPC, source IP, the presence of a session tag, time windows where it makes sense. Layer a permissions boundary or an SCP so that even a misconfigured server policy can't grant beyond a hard ceiling. That ceiling is what saves you when a human inevitably over-grants in a hurry.

Separate read from write, and make write loud. Read tools can run unattended. Tools that mutate state — terminate, delete, modify, put — should live behind a different role with a higher bar: tighter resource scope, narrower conditions, and ideally a human approval step or a change record the action references. The agent can prepare the change. It shouldn't be the sole signatory on the destructive one.

Doing this without killing velocity

The objection I always get is that this is friction, and friction kills the thing that made agents worth adopting. I'd argue the opposite, the same way I'd argue it about any guardrail: scoped permissions are what let you say yes fast. A tightly bounded server is one you can approve in an afternoon because the worst case is knowable. The unscoped one is the one that sits in a security review for three weeks while everyone tries to imagine what it could touch.

So make the safe path the easy path. Ship a baseline IAM module — a policy template, a roles-anywhere trust, a permissions boundary — that every new MCP server inherits, the way you'd template any landing-zone account. Generate the policy from the tool manifest where you can, so least privilege is the default output, not a manual chore someone deprioritizes. And turn the data CloudTrail already gives you into a feedback loop: IAM Access Analyzer will tell you which granted permissions a server never actually used, and that unused set is your next pull request. Velocity comes from the paved road, not from skipping the guardrails.

Running security and platform together at a company serving more than 1,500 financial institutions, I've learned the boring lesson over and over: the new technology rarely brings a new control. It brings an old control to a place we forgot to apply it. MCP is exactly that. The model gets the headlines. The IAM policy decides the outcome.

Here's the challenge. Pick one MCP server you've already deployed against AWS and pull its role. If you can't read the attached policy and recite, line by line, why each permission is there and what tool needs it — you don't have an agent problem. You have an identity you don't understand reaching into your cloud. Fix that one first, then make it the template for the next ten.

Cloud SecurityIAMAWSDevOps