About unsupported resource level permissions of the Amazon EC2 API

IAM

Many Amazon EC2 APIs can control access permission with "Resource-level permissions". However, some actions do not support "Resource-level permissions". Furthermore, these actions tend to be overlooked.

In this post, we will introduce the error contents and workarounds for creating IAM policies that specify actions not supported by "Resource-level permissions".

Example IAM Policy

For example, you create an IAM policy under the following conditions.

  • Resources:specific EC2 instance
  • Actions:stop / start / reboot / CreateImage for EC2 instance
  • Effect: Allow

IAM policy where the error occurred

Suppose you create the following IAM policy using "Policy Generator":

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt000",
            "Effect": "Allow",
            "Action": [
                "ec2:Describe*",
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:RebootInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>"
            ]
        }
    ]
}

At first glance, there seems to be no problem in the above policy. However, the policy contains actions that do not support Resource-level Permissions. If you execute this action, you will see an error message: "You are not authorized to perform this operation."

$ aws ec2 create-image --no-reboot --name "backup-${today}-${instance-id}" --instance-id ${instance-id}

An error occurred (UnauthorizedOperation) when calling the CreateImage operation: You are not authorized to perform this operation.

Thus the IAM policy needs to be adjusted to account for actions that do not support Resource-level Permissions.

Corrected IAM policy

The statement is separated into actions that support Resource-Level Permissions and actions that don't support Resource-Level Permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt000",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:Describe*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Sid": "Stmt001",
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>"
            ]
        }
    ]
}

For easy reference, we list some supported and unsupported Resource-Level Permissions.

Supported Resource-Level Permissions

  • RebootInstances
  • StartInstances
  • StopInstances

The above actions support resource-level permissions. Therefore, these actions are controlled using "Resource element".

{
            "Sid": "Stmt001",
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>"
            ]
        }

Unsupported Resource-Level Permissions

  • CreateSnapshot
  • CreateImage
  • Describe*

The above actions do not support resource-level permissions. Therefore, you must grant a * wildcard for "Resource element".

        {
            "Sid": "Stmt000",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:Describe*"
            ],
            "Resource": [
                "*"
            ]
        },

List of Unsupported Resource-Level Permissions

Granting IAM Users Required Permissions for Amazon EC2 Resources | Unsupported Resource-Level Permissions

The following Amazon EC2 API actions do not support resource-level permissions at this time. Therefore, a * wildcard must be used for "Resource Element" as shown in the Corrected IAM policy.

AcceptReservedInstancesExchangeQuote
AllocateAddress
AllocateHosts
AssignIpv6Addresses
AssignPrivateIpAddresses
AssociateAddress
AssociateDhcpOptions
AssociateRouteTable
AssociateSubnetCidrBlock
AssociateVpcCidrblock
AttachInternetGateway
AttachNetworkInterface
AttachVpnGateway
BundleInstance
CancelBundleTask
CancelConversionTask
CancelExportTask
CancelImportTask
CancelReservedInstancesListing
CancelSpotFleetRequests
CancelSpotInstanceRequests
ConfirmProductInstance
CopyImage
CopySnapshot
CreateCustomerGateway
CreateDefaultVpc
CreateDhcpOptions
CreateEgressOnlyInternetGateway
CreateFlowLogs
CreateFpgaImage
CreateImage
CreateInstanceExportTask
CreateInternetGateway
CreateKeyPair
CreateNatGateway
CreateNetworkAcl
CreateNetworkAclEntry
CreateNetworkInterface
CreateNetworkInterfacePermission
CreatePlacementGroup
CreateReservedInstancesListing
CreateRoute
CreateRouteTable
CreateSecurityGroup
CreateSnapshot
CreateSpotDatafeedSubscription
CreateSubnet
CreateVpc
CreateVpcEndpoint
CreateVpnConnection
CreateVpnConnectionRoute
CreateVpnGateway
DeleteEgressOnlyInternetGateway
DeleteFlowLogs
DeleteKeyPair
DeleteNatGateways
DeleteNetworkInterface
DeleteNetworkInterfacePermission
DeletePlacementGroup
DeleteSnapshot
DeleteSpotDatafeedSubscription
DeleteSubnet
DeleteVpc
DeleteVpcEndpoints
DeleteVpnConnection
DeleteVpnConnectionRoute
DeleteVpnGateway
DeregisterImage
DescribeAccountAttributes
DescribeAddresses
DescribeAvailabilityZones
DescribeBundleTasks
DescribeClassicLinkInstances
DescribeConversionTasks
DescribeCustomerGateways
DescribeDhcpOptions
DescribeEgressOnlyInternetGateways
DescribeElasticGpus
DescribeExportTasks
DescribeFlowLogs
DescribeFpgaImages
DescribeHosts
DescribeIamInstanceProfileAssociations
DescribeIdentityIdFormat
DescribeIdFormat
DescribeImageAttribute
DescribeImages
DescribeImportImageTasks
DescribeImportSnapshotTasks
DescribeInstanceAttribute
DescribeInstances
DescribeInstanceStatus
DescribeInternetGateways
DescribeKeyPairs
DescribeMovingAddresses
DescribeNatGateways
DescribeNetworkAcls
DescribeNetworkInterfaceAttribute
DescribeNetworkInterfacePermissions
DescribeNetworkInterfaces
DescribePlacementGroups
DescribePrefixLists
DescribeRegions
DescribeReservedInstances
DescribeReservedInstancesListings
DescribeReservedInstancesModifications
DescribeReservedInstancesOfferings
DescribeRouteTables
DescribeScheduledInstanceAvailability
DescribeScheduledInstances
DescribeSecurityGroupReferences
DescribeSecurityGroups
DescribeSnapshotAttribute
DescribeSnapshots
DescribeSpotDatafeedSubscription
DescribeSpotFleetInstances
DescribeSpotFleetRequestHistory
DescribeSpotFleetRequests
DescribeSpotInstanceRequests
DescribeSpotPriceHistory
DescribeStaleSecurityGroups
DescribeSubnets
DescribeTags
DescribeVolumeAttribute
DescribeVolumes
DescribeVolumesModifications
DescribeVolumeStatus
DescribeVpcAttribute
DescribeVpcClassicLink
DescribeVpcClassicLinkDnsSupport
DescribeVpcEndpoints
DescribeVpcEndpointServices
DescribeVpcPeeringConnections
DescribeVpcs
DescribeVpnConnections
DescribeVpnGateways
DetachInternetGateway
DetachNetworkInterface
DetachVpnGateway
DisableVgwRoutePropagation
DisableVpcClassicLinkDnsSupport
DisassociateAddress
DisassociateRouteTable
DisassociateSubnetCidrBlock
DisassociateVpcCidrBlock
EnableVgwRoutePropagation
EnableVolumeIO
EnableVpcClassicLinkDnsSupport
GetConsoleOutput
GetHostReservationPurchasePreview
GetPasswordData
GetReservedInstancesExchangeQuote
ImportImage
ImportInstance
ImportKeyPair
ImportSnapshot
ImportVolume
ModifyHosts
ModifyIdentityIdFormat
ModifyIdFormat
ModifyImageAttribute
ModifyInstanceAttribute
ModifyInstancePlacement
ModifyNetworkInterfaceAttribute
ModifyReservedInstances
ModifySnapshotAttribute
ModifySpotFleetRequest
ModifySubnetAttribute
ModifyVolume
ModifyVolumeAttribute
ModifyVpcAttribute
ModifyVpcEndpoint
ModifyVpcPeeringConnectionOptions
MonitorInstances
MoveAddressToVpc
PurchaseHostReservation
PurchaseReservedInstancesOffering
PurchaseScheduledInstances
RegisterImage
ReleaseAddress
ReleaseHosts
ReplaceNetworkAclAssociation
ReplaceNetworkAclEntry
ReplaceRoute
ReplaceRouteTableAssociation
ReportInstanceStatus
RequestSpotFleet
RequestSpotInstances
ResetImageAttribute
ResetInstanceAttribute
ResetNetworkInterfaceAttribute
ResetSnapshotAttribute
RestoreAddressToClassic
RunScheduledInstances
UnassignIpv6Addresses
UnassignPrivateIpAddresses
UnmonitorInstances

Conclusion

This post introduced error contents and workarounds when creating IAM policies that use "Resource-based permissions".Amazon EC2 APIs that support resource level permissions and those that do not were listed.When creating IAM policies, the differences in support for "Resource-Level Permissions" should be considered.

References

Granting IAM Users Required Permissions for Amazon EC2 Resources Demystifying EC2 Resource-Level Permissions

- yusuke;