Agent in Production
FeaturesLong read

Least Privilege IAM Policies for AI Coding Agents

Agents need dynamic permissions tied to specific tasks, not static roles designed for humans.

Editor at Large · · 11 min read
Cover illustration for “Least Privilege IAM Policies for AI Coding Agents”
Features · September 4, 2026 · 11 min read · 2,535 words

Least privilege for a human hire is a static negotiation. Someone in IT assigns a role at onboarding, that role maps to a job function, and the permissions rarely change until the person switches teams. Static service accounts follow the same logic: a backend process gets a fixed set of API scopes and keeps them for the life of the service.

Agents strain both models at once. Treating them like scaled-up service accounts is a mistake teams commonly make, and it's the mistake most agent security failures trace back to once you dig into the postmortem. The permissions an agent needs shift by task: reviewing a pull request calls for a different access surface than running a database migration or triaging a production incident. They shift by session too, since the same agent doing nominally the same job might touch a different repo or a different cloud environment each time it runs. Within one workflow, the build phase, the test phase, and the deploy phase each warrant their own scope; collapsing all three into a single role is how an agent ends up holding deploy access it only ever needed for testing.

Layered on top of that is a data problem that has nothing to do with actions at all. An agent cleared to call an internal API gets whatever that API returns, and APIs have a habit of returning more than the calling context needs: customer PII sitting next to a status field, billing details bundled into a metadata response. Trace a single "read-only" grant back to the response payload it actually produces, and it's rarely as narrow as the permission name suggests. Least privilege for agents has to account for the data behind the action, not just the action itself.

Delegation is the part of this problem most consistently underrated, and most security reviews stop looking before they get there. When an orchestrator agent spawns a sub-agent to handle part of a task, the sub-agent's permissions can compound with, or in some frameworks inherit wholesale from, the parent's scope. That creates escalation paths that simply don't exist in a single-agent model. Industry surveys on AI monitoring have found that only a minority of organizations monitor AI traffic end-to-end across prompts, tool calls, and outputs, and fewer still track agent-to-agent interactions continuously. Most teams lack the telemetry to know what permissions their agents are exercising right now, let alone what a sub-agent inherited three delegation hops downstream. A policy nobody can observe carries little practical weight, whatever it says on paper.

Building a capability matrix before writing a single IAM policy

Diagram: Capability Matrix: Four Columns Before Any IAM Policy. Visualizes: Visualize the four-column capability matrix structure described in the article as a concrete design tool agents must define before any IAM policy is written.

The fix starts before anyone opens the IAM console. Skipping this step is a common reason agent policies end up too loose or too brittle, and no amount of careful JSON fixes a matrix nobody built. Define, in writing, what the agent is supposed to do and, just as important, what it must never do, before a single policy gets drafted.

A capability matrix forces four columns for every agent: what it must read (repositories, logs, test results, deployment metadata), what it must execute (build commands, test runners, linters), what it must write or create (PR comments, draft tickets, status updates), and what it must never touch under any circumstance. That last column carries as much weight as the other three combined. For an agent scoped to reviewing a.NET application, the matrix might grant read access to repository files, permission to run dotnet build and dotnet test, and read access to application logs, while explicitly denying database deletion, IAM role modification, user creation, billing configuration changes, log disabling, and any change to production networking.

An agent that reviews code should not be able to deploy it, full stop. Workflows get modified constantly, tools get added, models get swapped out, and a matrix written with that boundary in mind holds up under all of it, because the boundary was a decision rather than an accident of scope.

Treat the matrix as the artifact of record: something a security reviewer can read and sign off on without parsing a wall of policy JSON. It belongs in version control next to the agent's configuration, not sketched on a whiteboard or buried in a wiki page nobody opens again after the first deployment.

Scoping credentials to the session: workload identity and just-in-time access

A long-lived API key sitting in an environment variable is a standing privilege. It exists whether the agent is running or not, which means it can be leaked, copied, or reused by anyone who finds it, independent of whether the agent ever needed that access at 3 a.m. on a Tuesday. Standing credentials carry risk by default; the migration speed off them is a fair proxy for how seriously an organization takes agent security, full stop.

Just-in-time access binds credentials to the session instead of to the identity. The agent authenticates through a cryptographic workload identity, receives a narrowly scoped, ephemeral credential for one task or one bounded session, and that credential expires or gets revoked the moment the task ends. The goal is zero standing privilege: no secret sits around between sessions for an attacker to go looking for.

AWS IAM Roles Anywhere, GCP Workload Identity Federation, and Azure Managed Identity each implement versions of the same pattern: an identity bound to the workload itself, the specific task, trigger, or pipeline run, rather than to a person or a shared account. Credentials get minted fresh at session start and revoked on completion, so the session boundary and the credential boundary are the same boundary.

Sub-agents need the same discipline applied recursively. When an orchestrator spawns a sub-agent, that sub-agent should receive a credential narrowed further than the parent's scope, never one that matches or exceeds it. Frameworks that default to wholesale inheritance down a delegation chain are trading security for convenience, and it's a bad trade: none of the session-scoping work above matters if a secret gets checked into a config file or baked into a container image, because a hardcoded secret doesn't expire when the session does.

The side benefit is cleaner accountability. Every session has a credential lifetime, and that lifetime maps directly to a bounded set of logged actions, which makes attribution far simpler than reconstructing who did what from a shared, long-lived token.

Intent-based authorization and policy evaluation at runtime

Role-based access control answers exactly one question: does the role have the permission, yes or no. That single check is the ceiling of what RBAC can do for an agent, and it's not enough, because an agent operating strictly within its assigned role can still do something catastrophic if the role itself was scoped too broadly to begin with. Most teams don't discover that ceiling until something breaks in production.

Intent-based authorization asks richer questions alongside that baseline check. What tool is the agent trying to invoke right now? Which dataset or resource is actually in scope for this session? Does the action match the workflow this agent type is declared to run? Is the action reversible, and if it isn't, has someone explicitly signed off on it? Is the request even arriving from the execution context it's supposed to, the sandbox or pipeline it was launched inside, rather than from somewhere else entirely?

Policy-as-code frameworks like Open Policy Agent let these checks get written as versioned, testable rules evaluated at the exact moment of each tool call. This runtime-evaluation model lines up with the direction of NIST's Cybersecurity Framework 2.0 and the Cloud Security Alliance's MAESTRO threat-modeling framework for agentic systems, both of which treat agent authorization as a continuous decision process rather than a one-time grant.

Human-in-the-loop approval belongs in this structure as a policy primitive, built into the design rather than bolted on for optics. High-risk or irreversible actions, merging to main, deleting a resource, modifying an IAM role, get gated behind an explicit approval step instead of a blanket allow or deny. The agent pauses, surfaces the pending action to a person, and waits.

This is also where the line between observation and execution earns its keep. A DevOps agent that reads logs, summarizes alerts, and opens tickets carries a fundamentally different risk profile than one with direct rights to deploy, roll back, or scale infrastructure down, even when both agents run on the same underlying model. Treating them as equivalent because they share a model is a category error, and a common one at that. Every evaluation, allow or deny, should produce a log entry naming the action requested, the policy applied, and the decision reached, tied back to the session identity that triggered it.

Hardening policies through iterative access analysis, not upfront guessing

Writing a complete least-privilege policy from a blank page requires knowing, in advance, every API call an agent will ever make. Nobody actually knows that in full, and teams that pretend otherwise land in one of two ditches: locking an agent out of tasks it legitimately needs, or leaving a door open they never meant to. Guessing the final policy upfront tends to fail, no matter how well the person guessing knows the workload.

The better approach starts wider than instinct suggests it should and narrows from there. Begin with a broader, but still controlled, policy in a non-production environment, permissive enough that the agent can complete representative tasks without hitting artificial walls. Run a realistic batch of those tasks, record every API action actually invoked, then strip out whatever never got used. Run the tightened policy again and confirm the agent still completes its work correctly. Only promote to production once that loop has converged and stopped producing surprises.

Cloud providers have built tooling around exactly this workflow: AWS IAM Access Analyzer generates policy suggestions from CloudTrail activity, GCP's Policy Intelligence and Azure's unused-permissions recommendations do the equivalent. The starting point is observed access, what an agent actually did, weighed against a guess about what it might need someday.

Before any tightened policy goes to production, it needs adversarial testing: a deliberate attempt to make the agent do the things it should never be able to do. Try to get it to delete or modify IAM roles, attach an administrator policy to any identity, pass a production role to a resource it controls, disable logging or monitoring, modify a security group or production network path, or delete a production database or storage bucket. Every one of those attempts should come back with an explicit denial, not a silent failure and not a vague timeout. Each round of tightening gets checked against the original capability matrix, confirming that everything meant to work still works and everything meant to fail still fails.

Observability as the enforcement layer that keeps least privilege honest over time

Policies decay. Tasks evolve, models get updated, someone adds a new tool to the MCP server, and permissions that were correctly scoped at launch start drifting. Sometimes they drift too narrow, causing failures that get "fixed" with a broad emergency grant nobody remembers to walk back. Far more often they drift too wide, because nobody circled back to tighten anything after the initial rollout, and that direction of drift is the one worth worrying about: it's invisible until an audit forces the question, and any team assuming its own policies are tightening over time rather than loosening is misreading its own risk.

Meaningful observability means logging four things without exception. Every tool call needs its name, parameters, and outcome recorded. Every write or diff action needs a record of what changed, in which resource, under which session identity. Every use of a credential needs tracking: which ephemeral token, which action, whether it succeeded or got denied. Every policy evaluation needs the decision, the rule that triggered it, and the context at that moment logged. Each entry needs to trace back to a person or a trigger, the developer who kicked off the run, the GitHub event, the scheduled job, not just to an agent identity floating on its own.

Most organizations aren't there yet. Surveys of AI monitoring practices have found that only a minority of organizations track AI traffic end-to-end, and continuous monitoring of agent-to-agent interaction is rarer still. For teams in that position, a least-privilege policy rests on assumption rather than verification, because nobody's watching closely enough to know whether it's holding up under real use.

An agent behaving unexpectedly, making calls outside its declared workflow, racking up denials, needs a defined quarantine path: revoke the credential, terminate the session, alert the team that owns it. Capability matrices need periodic review on a set schedule, the same way human role assignments do, with any agent configuration change or model update triggering an off-cycle look as well. For organizations under SOC 2 Type 2, this isn't optional bookkeeping: auditors want evidence that controls operated consistently across the entire audit period, and a policy document alone doesn't prove that. The logs serve as the evidence; the policy states the intent, and intent alone doesn't survive an audit.

How managed agent infrastructure handles the credential and logging burden in practice

Running agents on generic cloud VMs or CI runners means owning every layer of this stack directly: workload identity setup, credential minting and revocation, sandbox isolation, policy-as-code deployment, log aggregation, and the audit trail format an auditor will eventually ask to see. That's a lot of infrastructure to get right before an agent ever reviews its first pull request, and it's a large part of why so many agent pilots stall before reaching production, with deployment infrastructure, not model capability, cited as the primary blocker.

The real question isn't which controls matter; it's who carries the burden of keeping all of them consistent, day after day, as agents and tasks multiply. Building that stack from scratch at every company that runs agents is redundant effort with no competitive upside, and it's the reason a managed platform built for coding agents should absorb the burden rather than pass it downstream to whoever's on call. That means per-session sandbox isolation, so no state carries over between runs. It means credentials minted fresh at session start and revoked the moment the task ends, zero standing privilege as the default rather than a setting someone has to remember to flip. It means full logging across every tool call, every diff, every token used, attributable to the session and the person or trigger that started it. Budget caps get enforced at the session, developer, and time-period level, set before spend happens rather than reconciled after the invoice arrives. Agent configuration gets written as versioned YAML, checked into the same repository as the rest of the codebase, reviewed the same way a pull request gets reviewed.

None of this replaces the discipline described above: the capability matrix, the intent-based policy, the iterative hardening loop still have to happen. What managed infrastructure changes is where that discipline lives, on a foundation that doesn't depend on a platform team rebuilding workload identity federation from scratch on a deadline. The governance work remains either way. What managed infrastructure settles is whether every team building on agents has to solve credential scoping and audit logging from first principles, or whether that groundwork comes standard, already tested, already logged.

Sources

  1. okta.com
  2. nhimg.org
  3. c-sharpcorner.com
  4. miniorange.com
  5. nhimg.org
  6. greennode.ai

More in Features