AWS

AWS permissions

What the access key needs to be allowed to do, screen by screen, and how to stay read-only.

The key you give DevOps Agent can do exactly what its IAM user is allowed to do, and nothing more. This page tells you what to allow.

The simple answer

Attach the AWS-managed policy ReadOnlyAccess to the IAM user, plus one small inline policy for Cost Explorer:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ce:GetCostAndUsage",
        "ce:GetCostAndUsageWithResources",
        "ce:GetDimensionValues"
      ],
      "Resource": "*"
    }
  ]
}

That gives you every screen in read-only form: dashboard, cost, security findings, IAM review, logs, S3 browsing, CloudFormation viewing. Nothing can be changed, deleted or terminated — by you, by a team member, or by the assistant.

Most people should stop here. Add write permissions later, deliberately, for the specific things you want to do.

If you prefer a minimal policy

These are the calls each area actually makes.

Always needed

sts:GetCallerIdentity, ec2:DescribeRegions

Dashboard

ec2:DescribeInstances, rds:DescribeDBInstances, s3:ListAllMyBuckets, plus the Cost Explorer actions above, plus the security checks below.

Security checks on the dashboard

cloudtrail:DescribeTrails, cloudtrail:GetTrailStatus, cloudtrail:GetEventSelectors, guardduty:ListDetectors, guardduty:GetDetector, iam:GetAccountSummary, iam:ListUsers, iam:ListMFADevices, s3control:GetPublicAccessBlock

Cost and FinOps

ce:GetCostAndUsage, ce:GetCostAndUsageWithResources, ce:GetDimensionValues, and for the inventory behind savings advice: ec2:DescribeInstances, ec2:DescribeVolumes, ec2:DescribeSnapshots, ec2:DescribeAddresses, ec2:DescribeNatGateways, rds:DescribeDBInstances

Users / IAM

iam:ListUsers, iam:GetUser, iam:GetLoginProfile, iam:ListAccessKeys, iam:GetAccessKeyLastUsed, iam:ListMFADevices, iam:ListGroupsForUser, iam:ListAttachedUserPolicies, iam:ListUserPolicies, and for the activity report cloudtrail:LookupEvents

GuardDuty and Inspector

guardduty:ListDetectors, guardduty:ListFindings, guardduty:GetFindings, inspector2:ListFindings

CloudWatch and Logs

logs:DescribeLogGroups, logs:StartQuery, logs:GetQueryResults, cloudwatch:DescribeAlarms, cloudwatch:GetMetricData

S3

Read: s3:ListAllMyBuckets, s3:GetBucketLocation, s3:ListBucket, s3:GetObject, s3:GetBucketVersioning, s3:GetBucketEncryption Write (only if you want upload, new folder, new bucket, delete): s3:PutObject, s3:DeleteObject, s3:CreateBucket

CloudFormation

Read: cloudformation:DescribeStacks, DescribeStackResources, DescribeStackEvents, GetTemplate, ListChangeSets, DescribeChangeSet, DetectStackDrift, ValidateTemplate Write (only if you want to create or change stacks): cloudformation:CreateStack, CreateChangeSet, ExecuteChangeSet, DeleteStack, ContinueUpdateRollback — note that CloudFormation then acts with your key's permissions on whatever the template describes.

EC2 servers

Listing needs ec2:DescribeInstances. Connecting over SSH does not use AWS permissions at all — it uses the PEM key you save.

What "read-only" does and does not protect

Read-only stops anything being created, changed or deleted in AWS. It does not stop things being read, and some reads are sensitive: secretsmanager:GetSecretValue and ssm:GetParameter --with-decryption are both reads, and both are included in ReadOnlyAccess.

That matters because the assistant's Read mode treats AWS get-* calls as reads. If your account holds secrets you would not want appearing in a chat transcript, deny those actions explicitly:

{
  "Effect": "Deny",
  "Action": [
    "secretsmanager:GetSecretValue",
    "ssm:GetParameter",
    "ssm:GetParameters",
    "kms:Decrypt"
  ],
  "Resource": "*"
}

An explicit Deny always beats an Allow, so this is safe to add alongside ReadOnlyAccess.

Common errors and what they mean

Error containsFix
is not authorized to perform: ce:GetCostAndUsageAdd the Cost Explorer policy above. Also enable Cost Explorer once in the AWS billing console
AccessDenied on a regionThe key lacks permission there, or the region is not enabled for your account
InvalidClientTokenIdThe access key is wrong or has been deleted
SignatureDoesNotMatchThe secret key is wrong — usually a copy-paste with a space
OptInRequiredThe region needs enabling in the AWS console

The dashboard reports per-region errors rather than failing silently, so the message usually names the exact call that was refused.

Good practice

  • One IAM user per DevOps Agent project.
  • No console access on that user.
  • Start read-only, add write access deliberately.
  • Rotate the key periodically — replace it in Settings → Project.
  • Never use root account credentials.