Never give a coding agent long-lived AWS keys. Either (a) build a dedicated, least-privilege IAM role with short-lived credentials and accept that you have no approvals or undo, or (b) put a governed broker between the agent and AWS so the agent holds no credentials at all and every action is typed, approved, audited, and reversible. Start read-only in both cases.
Claude Code is very good at operating AWS. It will happily diagnose a misbehaving ECS service, fix the task definition, and roll the deployment, as long as it can reach your account. The question is how it reaches your account.
The three ways people do it today
1. The ambient keys. The agent runs in your shell, your shell has
~/.aws/credentials, done. This is the default, and it’s the worst option.
The agent inherits everything you can do, forever, with no audit
distinction between you and it. And every prompt injection in every README
the agent reads becomes a potential operator of your AWS account.
2. The shared “agent” IAM user. A long-lived access key in a .env
file, often with AdministratorAccess “temporarily”. Only slightly better
than #1, because at least you can revoke it. But access keys leak. It’s the
single most common AWS incident pattern. A long-lived key sitting next to a
program that reads untrusted text all day is a leak waiting for a place to
happen.
3. The scoped role. A dedicated IAM role with least-privilege policies,
assumed with short-lived credentials (SSO or aws sts assume-role). This
is real progress, and we’ll walk through it below. But notice what it still
lacks: no approval step, no per-agent attribution, no undo.
What “safe” actually requires
Whatever mechanism you pick, safety comes from five properties:
- No long-lived credentials within the agent’s reach. Short-lived STS sessions only.
- Least privilege, defined by the task, not “read-only-ish admin”.
- A human gate for writes. The agent proposes; someone approves.
- Attribution. Your CloudTrail should tell the agent apart from you.
That’s what
sts:SourceIdentityis for. - Reversibility. Know what “undo” is before approving the change.
Option A: DIY, the scoped-role checklist
If you want to stay hands-on, do at least this:
- Create a dedicated role, e.g.
agent-operator, with a policy scoped to the services the agent actually needs. Start withReadOnlyAccessand subtract. Don’t start with admin and promise to narrow it later. - Never mint an IAM user access key for it. Assume the role from your own SSO session so credentials expire in minutes:
aws sts assume-role \
--role-arn arn:aws:iam::<account>:role/agent-operator \
--role-session-name claude-code \
--source-identity claude-code \
--duration-seconds 900
- Run the agent with only those session variables exported, in a shell that has no other credential chain.
- Alert on the role’s activity in CloudTrail, filtered by the
SourceIdentityyou set.
This gets you least privilege and expiry. It does not get you approval workflows, typed operations, tamper-evident audit, or rollback. You’re still trusting the model’s judgment for every write it’s allowed to make.
Option B: a governed broker (what Mesoplane does)
The structural fix is to take credentials out of the agent’s world entirely. With Mesoplane, the agent talks to a control plane, never to AWS:
- Connect the account with a CloudFormation quick-create stack that creates one IAM role in your account, trusted via AssumeRole with a per-workspace ExternalId. No keys change hands, and the connection starts in a read-only observe tier.
- The agent calls typed operations through Claude Code skills, the HTTP API, or an MCP facade. “Reboot this RDS instance” is a registered, risk-tiered operation, not a free-form shell command.
- Policy decides what happens. Reads run instantly. Risky writes pause
in an approvals inbox until an admin clicks approve. Every action lands
on a tamper-evident ledger, attributed to the agent seat via
SourceIdentity, and destructive fixes capture rollback envelopes. - You keep the kill switch. The role lives in your account. Delete the stack and Mesoplane’s access ends instantly, no ticket required.
Which should you choose?
| Ambient keys | Scoped role (DIY) | Governed broker | |
|---|---|---|---|
| Credentials near the agent | Long-lived | Short-lived | None |
| Least privilege | ✗ | ✓ | ✓ (typed ops + tiers) |
| Human approval for writes | ✗ | ✗ | ✓ |
| Agent-level attribution | ✗ | Manual | ✓ automatic |
| Tamper-evident audit + undo | ✗ | ✗ | ✓ |
| Setup effort | none | hours, per account | ~5 minutes |
If the agent only ever reads, a scoped role may be enough. The moment you want it to fix things (restart services, patch security groups, run remediations), use the broker pattern. It’s the only one where a confused or compromised agent physically can’t exceed the governance around it. For the reasoning behind that architecture, see what AI agent governance actually means and our security model.
Frequently asked questions
Does Claude Code store my AWS credentials?
Claude Code runs on your machine and uses whatever AWS credentials your shell already has: the standard credential chain (~/.aws, environment variables, SSO cache). It doesn't need to 'store' anything to be dangerous. If your shell can delete a database, so can any tool call the agent makes. The safest setups never expose raw credentials to the agent's environment at all.
What is the ExternalId in the AssumeRole pattern for?
It's AWS's standard defense against the confused-deputy problem. When a multi-tenant service assumes roles in many customer accounts, the ExternalId makes sure a role can only be assumed for the tenant it was created for. Someone who guesses your role ARN still can't get in through the service.
Can I let an agent read AWS but not change anything?
Yes, and you should start there. With raw credentials, that means attaching a read-only policy to a dedicated role. With a governed broker like Mesoplane it's the default: connections start in a read-only observe tier, and write access is a deliberate upgrade with approvals attached.
Let your agents operate the cloud, governed
Mesoplane turns agent requests into typed, approved, audited, reversible cloud operations. Connect an AWS account read-only in minutes.
Get started free