Skip to content

IAM permissions

The agent has two distinct AWS identities depending on the deployment path:

  • The task role (Fargate, ECS task JSON), instance profile (EC2), or assumed role (Local) is the identity the agent process runs under at scan time. It needs the discovery policy.
  • The execution role is used only on Fargate and ECS task JSON paths. It is what ECS itself uses at task launch to pull the image, fetch the enrollment token from Secrets Manager, and write to CloudWatch Logs. The agent process never assumes it. It needs the execution-role policy.

Cloud (managed) Fargate and EC2 templates create both roles for you. Cloud (DIY) Terraform creates them via the deploy-argus module. Cloud (DIY) ECS task JSON and Local paths require you to create the roles by hand using the JSON below.

Discovery policy (task role / instance profile)

Section titled “Discovery policy (task role / instance profile)”

The policy the agent process uses at scan time. It is read-only; the agent never mutates anything in your account.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ArgusDiscoveryRead",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation",
"s3:GetBucketTagging",
"s3:GetBucketPolicy",
"s3:GetBucketAcl",
"s3:GetBucketEncryption",
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketVersioning",
"s3:ListBucket",
"s3:GetObject",
"rds:DescribeDBInstances",
"rds:DescribeDBClusters",
"rds:ListTagsForResource",
"dynamodb:ListTables",
"dynamodb:DescribeTable",
"dynamodb:ListTagsOfResource",
"ec2:DescribeVolumes",
"ec2:DescribeRegions",
"sts:GetCallerIdentity",
"ssm:GetParameter"
],
"Resource": "*"
}
]
}

Resource: "*" is the recommended starting point for first-deploy validation. For least-privilege at scale, narrow the Resource field on per-service Sids (for example, restrict s3:GetObject and s3:ListBucket to specific bucket ARNs).

The sts:GetCallerIdentity call is what the agent uses to assert it is running inside the AWS account you registered (the “cross account guard”). Without it, the agent refuses to persist scan results.

Execution-role policy (Fargate / ECS task JSON only)

Section titled “Execution-role policy (Fargate / ECS task JSON only)”

Attached in addition to the AWS-managed AmazonECSTaskExecutionRolePolicy (which lets ECS pull the image and emit log events).

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadEnrollmentTokenSecret",
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "<TOKEN_SECRET_ARN>"
},
{
"Sid": "CloudWatchLogsForAgentTaskDef",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "<LOG_GROUP_ARN_PATTERN>"
}
]
}

Substitute:

  • <TOKEN_SECRET_ARN> with the ARN returned by aws secretsmanager create-secret (looks like arn:aws:secretsmanager:us-east-2:111122223333:secret:argus-agent/enrollment-token-xxxxxx).
  • <LOG_GROUP_ARN_PATTERN> with the ARN of the log group your task definition’s awslogs-group references. Use a literal ARN (arn:aws:logs:us-east-2:111122223333:log-group:/ecs/argus-agent:*) or a wildcard prefix (arn:aws:logs:us-east-2:111122223333:log-group:/ecs/*).

Both roles need a trust policy declaring which AWS principal can assume them.

ECS task role and execution role (Fargate, ECS task JSON):

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "ecs-tasks.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}

EC2 instance profile role (Cloud managed EC2):

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}
]
}

Local-path assumed role (agent on a laptop / on-prem VM assuming a role inside the target account):

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::<source-account-id>:user/<source-iam-user>" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "<your-external-id>" }
}
}
]
}

Generate a random external ID per role you create. The agent passes whatever you set as AWS_EXTERNAL_ID in the AssumeRole call, and this Condition ensures only callers with the matching value can assume the role.

The dashboard’s Cloud (DIY) > IAM policy tab is reference content, not a deploy. It emits the same two policy documents shown above. Use it when your platform team needs the JSON for security review, when you are writing your own IaC (CDK, Pulumi, CloudFormation), or when you are auditing what Argus needs in your account.