When implementing granular AWS IAM permissions for EC2 security group management, many administrators encounter a common pitfall - policies that appear correct at first glance actually fail during execution. The root cause typically lies in hidden dependencies between EC2 operations and other AWS services.
The example policy attempts to grant security group modification rights through:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1392336685000",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": [
"arn:aws:ec2:us-east-1::security-group/*"
]
}
]
}
This approach fails because:
- EC2 security group operations often require VPC context permissions
- Some API calls need additional Describe permissions
- Cross-service dependencies exist with services like CloudWatch
Here's a functional policy that grants security group modification rights without full EC2 access:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:CreateSecurityGroup",
"ec2:DeleteSecurityGroup",
"ec2:DescribeSecurityGroups",
"ec2:DescribeVpcs",
"ec2:DescribeInstances"
],
"Resource": "*"
}
]
}
1. The Describe
permissions are essential for the AWS console to function properly
2. VPC-related permissions ensure operations work in both EC2-Classic and VPC environments
3. The wildcard resource specification is often necessary due to API call dependencies
For organizations requiring region-specific restrictions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroups",
"ec2:DescribeVpcs",
"ec2:CreateSecurityGroup"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress",
"ec2:DeleteSecurityGroup"
],
"Resource": "arn:aws:ec2:us-east-1:123456789012:security-group/*"
}
]
}
When working with AWS Identity and Access Management (IAM), one common frustration is granting granular permissions for EC2 Security Groups without providing full EC2 access. The default EC2 full access policy is too permissive for most operational scenarios.
The example policy you provided attempts to restrict access using resource-level permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1392336685000",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Resource": [
"arn:aws:ec2:us-east-1::security-group/*"
]
}
]
}
This approach fails because many EC2 API actions don't support resource-level permissions for security groups. The wildcard ec2:*
includes actions that require broader permissions.
Here's a working policy that grants necessary permissions while maintaining security:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:CreateSecurityGroup",
"ec2:DeleteSecurityGroup",
"ec2:DescribeSecurityGroups",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeVpcs",
"ec2:DescribeRegions",
"ec2:DescribeAvailabilityZones"
],
"Resource": "*"
}
]
}
- The
Describe*
actions are required for the AWS console to function properly - Security group operations often need VPC context, hence the VPC describe permissions
- Region and AZ descriptions are needed for cross-region operations
For more granular control, implement tag-based conditions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress"
],
"Resource": "arn:aws:ec2:region:account:security-group/*",
"Condition": {
"StringEquals": {"aws:ResourceTag/Team": "network"}
}
}
]
}