limiting aws ec2 users - amazon-web-services

Is it possible to create a sub-account or sub-user that is limited in what he can see and/or do in AWS based on tags for example?
I have tried using policies, but for instances this wouldn't work, because you can't limit it on a resource level.
This makes it that either they can controll and see everything, or nothing at all.
is there anything that I have missed?

The question scope just too wide. Please study the IAM Guides and play around with IAM policy generator condition.
Even playing around with ARN that allow wildcard, you still need to define some explicit prefix/suffix for those wildcard values. For EC2, you need to understand EC2 resource ARN and possible need to mix with "Condition" to add restriction.
Here is an example of using policy generator for a policies that only allow run,start and stop instance, and it restrict to EC2 with resource tag serverX. When you attach this policy to the user, they can only do the following task. You may need to add further condition to make sure the user doesn't see instances belongs to others, by enforcing the tag name creation yourself.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1462794515000",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:RunInstances",
"ec2:StartInstances",
"ec2:StopInstances"
],
"Condition": {
"StringLike": {
"ec2:ResourceTag/Name": "serverX"
}
},
"Resource": [
"arn:aws:ec2::1234567890:instance/*"
]
}
]
}
You can play around with AWS policy Simulator. Another good reference is AWS inline policies and managed policies

Related

AWS permissions for Fargate and SSM

I'm trying to create some infrastructure for a service I am building on AWS using AWS Fargate. I'm using SSM as a value store for some of my application configuration, so I need both the regular permissions for Fargate as well as additional permissions for SSM. However, after banging my head against this particular wall for a while, I've come to the conclusion that I just don't understand AWS IAM in general or this problem in particular, so I'm here for help.
The basis of my IAM code comes from this tutorial; the IAM code is actually not in that tutorial but rather in this file in the github repo linked to that tutorial. I presume I need to retain that STS permission for something although I'm not entirely sure what.
I've converted the IAM code from the tutorial into a JSON document because I find JSON easier to work with than the Terraform native thing. Here's what I've come up with. It doesn't work. I would like to know why it doesn't work and how to fix it. Please ELI5 (explain like I'm 5 years old) because I know nothing about this.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameters",
"secretsmanager:GetSecretValue",
"kms:Decrypt",
"sts:AssumeRole"
],
"Principal": {
"Service": ["ecs-tasks.amazonaws.com"]
}
}
]
}
At a minimum, your ECS task should have below permissions:
Ability to assume a role
Resource level permissions
In the example, you have referred, An IAM Role is created with the following:
A trust relationship is attached. <-- To enable ECS task to assume an IAM role
AWS managed policy AmazonECSTaskExecutionRolePolicy is attached. <-- Resource permissions
So, in order to retrieve the SSM parameter values, add below resource permissions.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:Describe*",
"ssm:Get*",
"ssm:List*"
],
"Resource": [
"arn:aws:ssm:*:*:parameter/{your-path-hierarchy-to-parameter}/*"
]
}
]
}
If your Secrets uses KMS, then grant necessary kms permissions (kms:Decrypt). Refer specifying-sensitive-data for reference.

Creating an AWS IAM policy that restricts running instances to certain security groups

I’m trying to write an IAM policy that only enables AWS users to launch an instance if the security group is one of two types. Because there is no security group Condition Key, I opted for using condition statements, such that an EC2 instance can't be started/run unless the security group is in either of the 2 categories. The way I refer to these approved security groups in the policy below is via their tags.
The issue I'm having is that when I have a security group that does equal the first condition, an instance can be launched. However, when I use the security group that does equal "UCSFInbound" (the second condition), an instance won't launch (even though it should).
I do have a separate policy which grants broader access to EC2 resources, however, from what I understand, AWS first registers "deny" actions before "allow" actions. And if this is the reason why I'm having a problem, then neither of the 2 cases (security groups) should work.
IAM Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": [
"ec2:StartInstances",
"ec2:RunInstances"
],
"Resource": [
"arn:aws:ec2:*:*:subnet/*",
"arn:aws:ec2:*:*:key-pair/*",
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*::snapshot/*",
"arn:aws:ec2:*:*:launch-template/*",
"arn:aws:ec2:*:*:volume/*",
"arn:aws:ec2:*:*:security-group/*",
"arn:aws:ec2:*:*:placement-group/*",
"arn:aws:ec2:*:*:network-interface/*",
"arn:aws:ec2:*::image/*"
],
"Condition": {
"StringNotLike": {
"ec2:ResourceTag/aws:cloudformation:stack-id": "NetworkResourcesStack"
},
"StringNotEquals": {
"ec2:ResourceTag/Name": "UCSFInbound"
}
}
}
]
}
In general, you should avoid using Deny policies unless it overrules other policies.
For example, you could control access to Amazon S3 like this:
Allow all staff access to all S3 buckets
Deny access to the HR bucket if you are not an HR staff member
This uses a generic policy to Allow most access, but then uses a Deny to cover a special-case.
Thus, you should put arn:aws:ec2:region:account:security-group/security-group-id into the initial Allow policy that lets them use EC2.

What policy templates should an AWS IAM user have in order to deploy an EB application?

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": "*"
}
]
}

How to restrict a user to a specific instance volume in AWS using IAM policy

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>"
}
]
}

How to allow AWS user to see but not launch, start or stop instances

I have set a policy for an AWS user as such:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect":"Allow",
"Action": "ec2:Describe*",
"Resource":"*"
}
]
}
The intent was to allow a user with this policy to view EC2 instances on the console, but not to actually do anything with them. The problem is, once this policy is applied, the user can start, stop, terminate and launch new instances even though none of those permissions are addressed in the above policy, AFAIK.
Why is this happening with the above policy, and what can I do to prevent it (i.e. achieve the "view but not touch" result I'm after)?
Amazon IAM policies are Deny by default, which is not identical to Explicit Deny, see The Difference Between Denying by Default and Explicit Deny for details.
Accordingly, the observed behavior wouldn't be possible by default, so there must be another policy in place for this user explicitly granting the undesired actions like ec2:RunInstances. You have the following options to remedy this:
Identify/Remove Explicit Allow
You can analyze which policy grants the undesired actions by means of the excellent new AWS Identity and Access Management Policy Simulator, which is utterly helpful for issues like this.
Add Explicit Deny
You can add an explicit deny for those actions the user shouldn't be able to perform , e.g.:
{
"Statement": [
{
"Action": [
"ec2:RebootInstances",
"ec2:RunInstances",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:TerminateInstances"
],
"Effect": "Deny",
"Resource": "*"
}
]
}
Please note that the latter would still allow quite some other EC2 actions that you might not want, so a more complete approach to explicitly deny all but the desired ones would be to facilitate the NotAction:
The NotAction element lets you specify an exception to a list of actions. For example, you can use NotAction to let users use only the Amazon SQS SendMessage action, without having to list all the actions that the user is not allowed to perform. Using NotAction can sometimes result in shorter policies than using an Action element and listing many actions.
Warning: Please be aware that it is easy to restrict more than you intend and even lock yourself out when using NotAction for an explicit Deny - always make sure the Resource statement is only targeting the desired resources. For example, simply using the common wildcard * instead of a more specific resource selector like arn:aws:ec2:*:*:* boils down to 'deny all but these actions for every service' - for the example at hand this would include the ability to delete the erroneous policy again! This is best avoided by carefully simulating the policy upfront.
A resp. policy might look like this:
{
"Statement": [
{
"NotAction": [
"ec2:Describe*"
],
"Effect": "Deny",
"Resource": "arn:aws:ec2:*:*:*"
}
]
}
For user3086014, create a policy similar to the one below:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect":"Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances"
],
"Resource":[
"arn:aws:ec2:us-west-1:0123456789012:instance/i-ffffffff"
]
}
]
}
Change the actions to the ones you want to allow your user to perform. Change the resource to identify your instance - i.e. change the account ID (I've written 0123456789012 above) and the instance ID (I've written i-ffffffff above). Then apply that policy to your user. If you want to allow use of two instances, add a second ARN with a comma-delimiter between the ARNs (as is required JSON form).
Please next time make a separate question. It's awkward having questions-answers in the comments themselves. Thanks!