When deploying a lambda function to a VPC you're required to grant a bunch of network interface related permissions to lambda's execution role. AWS manuals advice to use AWSLambdaVPCAccessExecutionRole managed policy for this, which looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface",
"ec2:AssignPrivateIpAddresses",
"ec2:UnassignPrivateIpAddresses"
],
"Resource": "*"
}
]
}
As one can see, this policy doesn't restrict network interfaces that the lambda can modify, thus potentially allowing it to mess with networking outside its own VPC. I'd like to limit the actions that the lambda can do to the VPC or subnets that it's actually deployed into. However, so far I failed to come with a working policy for that.
I tried to check the VPC in the policy like this:
"Condition": {"StringEquals": {"ec2:Vpc": "${my_vpc_arn}" }}
but still got permission denied.
CloudTrail event contains the following authorization message) decoded with aws sts decode-authorization-message): https://pastebin.com/P9t3QWEY where I can't see any useful keys to check.
So is it possible to restrict a VPC-deployed lambda to only modify particular network interfaces?
You can't restrict the policy to individual NIs, as you don't know their ids until after you create them. But you should be able to restrict access to a specific VPC using the following lambda execution policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AccessToSpecificVPC",
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:UnassignPrivateIpAddresses",
"ec2:AssignPrivateIpAddresses",
"ec2:DescribeNetworkInterfaces"
],
"Resource": "*",
"Condition": {
"ArnLikeIfExists": {
"ec2:Vpc": "arn:aws:ec2:<your-region>:<your-account-id>:vpc/<vpc-id>"
}
}
},
{
"Sid": "CWLogsPermissions",
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:CreateLogGroup",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
The Lambda Service needs to be able to create and remove network interfaces in your VPC. That's because a shared ENI will be deployed in the VPC. Once all execution contexts are terminated this shared ENI will be removed again. This also explains why the describe permissions are needed, because the service probably needs to figure out if a shared ENI is already deployed for the specific lambda function.
Unfortunately that means you can't restrict the delete/modify operations to any particular ENIs as those are created and removed dynamically.
According to the documentation the specific permissions the Role needs are:
ec2:CreateNetworkInterface
ec2:DescribeNetworkInterfaces
ec2:DeleteNetworkInterface
I checked the documentation and the Create + Delete actions allow (among others) the following conditions:
ec2:Subnet
ec2:Vpc
This means it should be possible. Maybe separating the ec2:* permissions into their own statement with the aforementioned conditions could help you.
Related
It is possible to allow pulling from but not pushing to the Docker API VPC Endpoint (com.amazonaws.<region>.ecr.dkr) in its attached policy?
I can't find a reference for any supported actions other than "*", is there a way to specify pull only? Or something via a condition?
Yes, you can achieve this with a VPC endpoint policy.
Here's an example from the documentation. This policy enables a specific IAM role to pull images from Amazon ECR:
{
"Statement": [{
"Sid": "AllowPull",
"Principal": {
"AWS": "arn:aws:iam::1234567890:role/role_name"
},
"Action": [
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"ecr:GetAuthorizationToken"
],
"Effect": "Allow",
"Resource": "*"
}]
}
In AWS Console, add security groups that your instances (maybe all possible security groups) are using to the VPC endpoints.
I want to create a power-user who has all the permission on the existing instance, but he isn't able to create a new instance.
Which permission would manage that that problem.
I am assuming "PowerUser" means all permissions, then you might want to try this permission
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "*"
}
]
}
The first statement gives full permission to your user (please adapt to your definition of "PowerUser"). The second statement explicitly denies to call the EC2 API RunInstances (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html)
You can learn more about IAM Policies at http://docs.aws.amazon.com/IAM/latest/UserGuide/PoliciesOverview.html
I'm assuming you are discussing EC2 permissions. To prevent creation of new instances, the EC2 policy action associated with this is EC2:RunInstances.
To specify a single instance, I'd suggest using a condition block with a ec2:ResourceTag/. That gives more flexibility than hardcoding it in another manner. However, this will take some thought to prevent privilege escalation.
What policy templates should an AWS IAM user have in order to deploy and maintain an EB application (e.g. website code from a client machine)? IAMReadOnlyAccess plus PowerUserAccess seem sufficient, but I'm wondering whether the latter is overkill. Can I restrict policies to a single EB instance or application?
When you create an IAM role in the Web Console, there is a pre-defined role called ElasticBeanstalkFullAccess. This will give you full permission to all underlying resources that elastic beanstalk needs. You can see the general doc on this.
Restricting to specific environments or applications is much harder, but doable. It requires you to restrict the user to specific resources using arn's, including all underlying resources and their arn's. See the doc on this.
For reference, the full elastic beanstalk policy looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"elasticbeanstalk:*",
"ec2:*",
"elasticloadbalancing:*",
"autoscaling:*",
"cloudwatch:*",
"s3:*",
"sns:*",
"cloudformation:*",
"rds:*",
"sqs:*",
"iam:PassRole"
],
"Resource": "*"
}
]
}
I'm using the following set of IAM permissions for my AWS account. The goal is to allow our developers access to any "development" resources...launching from our AMIs, starting instances, stopping them, etc. As such, we've tagged the volume snapshots and the AMIs themselves. However, when I log in with a developer account in the group, I'm unable to see anything that was tagged and therefore can't do anything. Any help would be much appreciated...thanks!
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "ec2:*",
"Effect": "Allow",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/Purpose": "Development"
},
"DateLessThan": {
"aws:CurrentTime": "2016-01-01T00:00:00Z"
}
}
}
]
}
EDIT: I should add that I'm trying to enable them to do this through the console, not the CLI or via the SDK.
I am working on Amazon web services. Designing the custom IAM policies.
I have a user which have restricted access on the instances like he can start,stop the instances. Similarly i want to restrict the user to attach,delete specific volumes.
I have created this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TheseActionsDontSupportResourceLevelPermissions",
"Effect": "Allow",
"Action": ["ec2:DescribeInstances","ec2:DescribeInstanceStatus","ec2:DescribeVolumeAttribute","ec2:DescribeVolumeStatus","ec2:DescribeVolumes"], ,
"Resource": "*"
},
{
"Sid": "TheseActionsSupportResourceLevelPermissions",
"Effect": "Allow",
"Action": [
"ec2:RunInstances",
"ec2:TerminateInstances",
"ec2:StopInstances",
"ec2:StartInstances",
"ec2:AttachVolume",
"ec2:DetachVolume"
],
"Resource": "arn:aws:ec2:us-west-2:AccountID:instance/instanceID",
"Resource": "arn:aws:ec2:us-west-2:AccountID:instance/instanceID",
"Resource": "arn:aws:ec2:us-west-2:AccountID:instance/instanceID",
"Resource": "arn:aws:ec2:us-east-1:123456789012:volume/volID",
"Resource": "arn:aws:ec2:us-east-1:123456789012:volume/volID",
"Resource": "arn:aws:ec2:us-east-1:123456789012:volume/volID"
}
]
}
when I apply this policy it does not show me any volumes.
I get an error:
error fetching the volume details.
Any lead is appreciated
Thanks
Update
The best way to test/debug IAM policies is by means of the fantastic IAM Policy Simulator (see Using the IAM Policy Simulator for the actual link and instructions). With its help, the solution below can easily be verified to be working correctly.
I recommend to add a dedicated test user to your account with no policies attached (i.e. implicit Deny All) and then using the Mode: New Policy to assemble and simulate the policy in question, e.g. for the use case at hand:
use two volumes and allow one via the policy, then simulate the policy with both resources, one will yield denied and the other allowed for AttachVolume and DetachVolume
Once satisfied, you can apply the assembled policy to the entities in your account and recheck via Mode: Existing Policies.
Initial Answer
I wonder how you have been able to apply this IAM policy, insofar it is syntactically invalid JSON (the Action field within the first Statement lacks any value)?
The syntax error aside, that's also the source of your problem:
As indicated by TheseActionsDontSupportResourceLevelPermissions, a few EC2 API actions do not support the comparatively new Resource-Level Permissions for EC2 and RDS Resources yet, see this note from Amazon Resource Names for Amazon EC2:
Important Currently, not all API actions support individual ARNs; we'll add support for additional API actions and ARNs for additional
Amazon EC2 resources later. For information about which ARNs you can
use with which Amazon EC2 API actions, as well as supported condition
keys for each ARN, see Supported Resources and Conditions for Amazon
EC2 API Actions.
You will find that all ec2:Describe* actions are indeed absent still from Supported Resources and Conditions for Amazon EC2 API Actions at the time of this writing. This also includes the ec2:DescribeVolume* actions, which is why you receive the error.
Fixing the first statement as outlined below should remedy the issue:
{
"Statement": [
{
"Sid": "TheseActionsDontSupportResourceLevelPermissions",
"Action": [
"ec2:DescribeVolumeAttribute",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Sid": "TheseActionsSupportResourceLevelPermissions",
"Effect": "Allow",
"Action": [
"ec2:AttachVolume",
"ec2:DetachVolume"
],
"Resource": "arn:aws:ec2:<region>:<account number>:volume/<volume id>"
}
]
}