RBAC for AI Agents: Why Least Privilege Matters More Than You Think
When a human joins your team, you don’t give them admin access to everything on day one. You give them the access they need to do their job, and expand it as they demonstrate judgment and need. This principle — least privilege — is fundamental to security for exactly one reason: if something goes wrong, the damage is bounded.
AI agents deserve the same treatment. They often don’t get it.
Why Agent RBAC Is Harder Than Human RBAC
With humans, access control is mostly about identity and role. Jordan is a developer, so Jordan gets developer access. Developers can push to feature branches but not main. Simple.
With agents, it’s more complicated for three reasons:
Agents are more prolific. A developer might make 20 git operations in a day. An agent might make 200 in an hour. The blast radius of a permissive policy scales with operation volume.
Agents don’t exercise judgment about scope. A developer who accidentally has access to a sensitive bucket will usually notice it’s not relevant to their work and leave it alone. An agent tasked with “find all CSV files” will find them everywhere it has access, without the social inhibitions that keep humans from overreaching.
Agent intent is harder to audit post-hoc. With humans, “Jordan deleted that table” is a starting point for a conversation. With an agent, “claude-ops-01 deleted that table” starts a reconstruction exercise. Better controls reduce the need for reconstruction.
The Structure of an Agent Policy
A well-designed agent policy specifies four things:
What services the agent can call. AWS, GitHub, Stripe, custom internal APIs, specific tools. Not “everything” — the specific services the agent’s job requires.
What actions within those services. s3:GetObject not s3:*. git:push not git:admin. charges:read not charges:write. This is where most policies are too permissive — it’s easier to write wildcards than to enumerate specific actions.
What resources those actions apply to. arn:aws:s3:::invoice-data/processed/* not arn:aws:s3:::*. The specific bucket prefix, the specific git repository, the specific Stripe resource type. Resources are where you contain blast radius.
What requires approval. The subset of allowed actions that are high enough risk to require human confirmation before execution. Pushing to protected branches. Deleting anything. External communications.
Here’s a realistic example:
project: invoice-processor
agents:
claude-invoice-01:
# Git: read any repo, push only to feature branches of invoice repos
allow:
- service: git
actions: [clone, pull, fetch]
resources: ["acme/*"]
- service: git
actions: [push]
resources: ["acme/billing", "acme/invoices"]
branches: ["feature/*", "fix/*"]
# S3: read raw invoices, write processed output
allow:
- service: aws
actions: ["s3:GetObject", "s3:ListBucket"]
resources: ["arn:aws:s3:::invoice-data/raw/*"]
- service: aws
actions: ["s3:PutObject"]
resources: ["arn:aws:s3:::invoice-data/processed/*"]
# Stripe: read-only
allow:
- service: stripe
actions: ["invoices:read", "customers:read"]
# These require human approval
require_approval:
- service: git
actions: [push]
branches: ["main", "staging"]
- service: aws
actions: ["s3:DeleteObject"]
# Hard limits
deny:
- service: aws
actions: ["iam:*", "ec2:*", "rds:*"]
- service: stripe
actions: ["charges:create", "refunds:create", "customers:delete"]
This policy lets the agent do its job completely. It can’t do significant damage beyond its scope, even if it makes a mistake or is prompted maliciously.
Common Over-Permissioning Mistakes
s3:* on *.
The most common AWS mistake. Every AWS action on every bucket. The agent only uses s3:GetObject, but you gave it s3:DeleteBucket just in case. This is how “clean up temp files” becomes “delete production data.”
Push access to all branches.
Giving an agent push access to every branch, including main and release/*. The agent only touches feature branches in practice, but nothing stops it from pushing to main when it decides it’s done.
Shared credentials across agents. Ten agents, one set of credentials. Impossible to audit which agent took which action. Impossible to revoke one agent’s access without revoking all of them.
No resource constraints.
Policies that specify action but not resource: “allow s3:GetObject” with no bucket specification. The agent can read any bucket it can discover.
Forget about tools, not just APIs. Policies that scope AWS and git but forget about custom tool integrations. If the agent can call arbitrary bash commands, or has a tool that can query any database table, the service-level policies are irrelevant.
Testing Your Policies
Write a policy, then try to break it. Prompt the agent to:
- “Find all CSV files across all S3 buckets”
- “Push the current state of main to the production server”
- “Delete the temp files in the data directory”
- “Check if there are any IAM users with admin access”
A well-scoped policy should result in 403 responses and “access denied” audit entries — not successful operations. If the agent can do these things, your policy is too broad.
Policy Version Control
Treat agent policies the same way you treat infrastructure code: version control, code review, change history.
A policy change is a security change. It should go through the same review process as any other security-relevant code. “Claude asked for more access so I gave it to him” is not an audit trail. A pull request with the requester, the rationale, and the reviewer is.
Sentrely enforces policies from YAML files committed to your project repository. Every policy change creates a git commit, which means every change has an author, a timestamp, and a diff.
The Minimum Viable Policy
If you’re starting from scratch and need a policy today, here’s the floor:
- No wildcard actions. List specific actions, even if the list is long.
- No wildcard resources. Scope to the specific buckets, repos, and resources the agent needs.
- Push to main requires approval. Always.
- Data deletion requires approval. Always.
- No IAM actions. Ever. Unless IAM management is the agent’s explicit job.
These five rules eliminate the most common blast radius scenarios while leaving most agent workflows intact. Start here and tighten from experience.
Put this into practice with Sentrely
Everything covered in this article is built into Sentrely's managed control plane. Get early access and have it running against your Claude agents in minutes.