Least Privilege for AI Agents
The single most effective way to prevent AI agent disasters is to limit what they can do. Never give an AI agent more permissions than it needs for the specific task at hand.
Why AI Agents Should NEVER Use Admin Credentials
aws sts get-caller-identity returns an admin role, the agent can delete anything in your account. This is the number one cause of AI agent cloud disasters.Most developers authenticate their local terminal with broad permissions for convenience. When you invoke an AI agent in that terminal, it inherits those permissions. The fix is simple: create dedicated, restricted credentials for agent sessions.
Creating Dedicated Service Accounts
-
Create a Separate IAM Entity for Agent Use
Do not reuse your personal credentials. Create a dedicated IAM user or role specifically for AI agent sessions with a clear naming convention like
ai-agent-readonlyorai-agent-deploy-staging. -
Scope to Environment
Create separate credentials for each environment. An agent working on staging should never have credentials that can touch production resources.
-
Use Named Profiles
Configure AWS CLI profiles, Azure subscriptions, or GCP configurations so you can explicitly switch contexts before launching an agent session.
# Set the agent to use a restricted profile
export AWS_PROFILE=ai-agent-staging-readonly
# Verify the identity (should show restricted role)
aws sts get-caller-identity
# {
# "Arn": "arn:aws:iam::123456789012:role/ai-agent-staging-readonly"
# }
# Now launch your AI coding agent in this terminal
# The agent inherits ONLY the staging read-only permissions
Read-Only Access Patterns
For many AI agent tasks (code review, debugging, log analysis, architecture exploration), read-only access is sufficient:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReadOnly",
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"s3:GetObject",
"s3:ListBucket",
"rds:Describe*",
"logs:GetLogEvents",
"logs:FilterLogEvents",
"cloudwatch:GetMetricData",
"iam:GetRole",
"iam:ListRoles"
],
"Resource": "*"
},
{
"Sid": "ExplicitlyDenyDestructive",
"Effect": "Deny",
"Action": [
"ec2:TerminateInstances",
"ec2:DeleteSecurityGroup",
"s3:DeleteBucket",
"s3:DeleteObject",
"rds:DeleteDBInstance",
"rds:DeleteDBCluster",
"iam:Delete*",
"iam:Put*",
"cloudformation:DeleteStack"
],
"Resource": "*"
}
]
}
Time-Limited Credentials and Session Tokens
Even restricted credentials should be time-limited. If an agent session goes wrong, the damage window is capped:
# Assume a restricted role with a 1-hour session aws sts assume-role \ --role-arn arn:aws:iam::123456789012:role/ai-agent-deploy \ --role-session-name "claude-code-session" \ --duration-seconds 3600 # Export the temporary credentials export AWS_ACCESS_KEY_ID="ASIA..." export AWS_SECRET_ACCESS_KEY="..." export AWS_SESSION_TOKEN="..." # These credentials automatically expire after 1 hour
# Create a service account for agent use gcloud iam service-accounts create ai-agent-deployer \ --display-name="AI Agent Deployer (Staging Only)" # Generate a short-lived access token (1 hour max) gcloud auth print-access-token \ --impersonate-service-account=ai-agent-deployer@project.iam.gserviceaccount.com \ --lifetime=3600s
Permission Boundaries and Guardrails
Permission boundaries act as a ceiling on what any policy can grant. Even if an agent somehow escalates its permissions, the boundary prevents exceeding safe limits:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAllExceptDestructive",
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Sid": "DenyAllDestructiveActions",
"Effect": "Deny",
"Action": [
"ec2:Terminate*",
"rds:Delete*",
"s3:Delete*",
"dynamodb:Delete*",
"cloudformation:Delete*",
"eks:Delete*",
"lambda:Delete*",
"elasticache:Delete*",
"es:Delete*",
"iam:Delete*"
],
"Resource": "*"
}
]
}
Example IAM Policies by Cloud
{
"Name": "AI Agent Deployer - No Delete",
"Description": "Allows resource creation and updates but denies all delete operations",
"Actions": [
"Microsoft.Compute/virtualMachines/read",
"Microsoft.Compute/virtualMachines/write",
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Storage/storageAccounts/read",
"Microsoft.Storage/storageAccounts/write",
"Microsoft.Web/sites/read",
"Microsoft.Web/sites/write"
],
"NotActions": [
"*/delete",
"Microsoft.Authorization/roleAssignments/write",
"Microsoft.Authorization/roleDefinitions/write"
],
"AssignableScopes": [
"/subscriptions/{subscription-id}/resourceGroups/staging-rg"
]
}
# Create custom role that allows create/update but not delete gcloud iam roles create aiAgentDeployer \ --project=my-project \ --title="AI Agent Deployer" \ --description="Create and update resources, no delete" \ --permissions=compute.instances.create,\ compute.instances.get,\ compute.instances.list,\ compute.instances.update,\ compute.instances.setMetadata,\ storage.buckets.create,\ storage.buckets.get,\ storage.buckets.list,\ storage.objects.create,\ storage.objects.get,\ storage.objects.list # Note: compute.instances.delete is NOT included # Note: storage.buckets.delete is NOT included
Lilly Tech Systems