IAM Policy Examples
Five policy shapes that cover most of what an identity-based policy is asked to do. All use
the reserved documentation address ranges and account ID 123456789012.
1. Read-only access to Amazon S3
Section titled “1. Read-only access to Amazon S3”{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": [ "arn:aws:s3:::example-bucket", "arn:aws:s3:::example-bucket/*" ] } ]}Both ARNs are needed: bucket-level actions such as s3:ListBucket act on the bucket,
object-level actions such as s3:GetObject act on the objects. "Resource": "*" would work
but grants the same access to every bucket in the account.
2. Requiring MFA
Section titled “2. Requiring MFA”{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:*", "Resource": "*", "Condition": { "Bool": { "aws:MultiFactorAuthPresent": "true" } } } ]}Note that aws:MultiFactorAuthPresent is absent — rather than false — for requests made
with long-term credentials such as an access key. A Bool true condition therefore fails
closed for those, which is the intended behaviour here. Writing the inverse as an explicit
Deny with Bool: false does not achieve the same thing, because the key is missing rather
than false.
3. Restricting Regions
Section titled “3. Restricting Regions”{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "NotAction": [ "iam:*", "organizations:*", "cloudfront:*", "route53:*", "support:*", "sts:*" ], "Resource": "*", "Condition": { "StringNotEquals": { "aws:RequestedRegion": ["eu-west-1", "eu-west-2"] } } } ]}The NotAction exclusions are required. Several AWS services are global with endpoints in
us-east-1; denying every action outside the approved Regions without excluding them breaks
IAM, Organizations, CloudFront, Route 53, STS and Support.
4. Access driven by resource tags
Section titled “4. Access driven by resource tags”{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ec2:StartInstances", "ec2:StopInstances"], "Resource": "arn:aws:ec2:*:123456789012:instance/*", "Condition": { "StringEquals": { "aws:ResourceTag/Environment": "Production" } } } ]}Attribute-based access control in its simplest form: the permission follows the tag, so a new instance is covered the moment it is tagged. It depends on tagging being enforced — pair it with an SCP or a Config rule that requires the tag at creation.
5. Restricting by source address
Section titled “5. Restricting by source address”{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": "*", "Resource": "*", "Condition": { "NotIpAddress": { "aws:SourceIp": ["192.0.2.0/24", "203.0.113.0/24"] }, "Bool": { "aws:ViaAWSService": "false" } } } ]}Written as a Deny so it cannot be overridden by another allow. The aws:ViaAWSService
condition is what stops it breaking calls that an AWS service makes on the principal’s
behalf, which do not originate from the office address range.