AWS IAM Policy grant permissions for some EC2 instances - amazon-web-services

I want to restrict access for a specific user to see just few EC2 instances. I created a new user in IAM Roles and I attached a new Policy to it. The content of that Policy is attached below. I tried to look over documentation and to do it myself like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": [
"arn:aws:ec2:eu-west-1:ACCOUNT_ID:instance/i-INSTANCE_ID1",
"arn:aws:ec2:eu-west-1:ACCOUNT_ID:instance/i-INSTANCE_ID2"
]
}
]
}
I placed my region,ACCOUNT_ID(the owner id, not of the new user created) and instance-id, but when I connect with that user and I go to list all Instances I got this An error occurred fetching instance data: You are not authorized to perform this operation..
After I placed the code in JSON editor, in Policy Review step I got this message:
This policy defines some actions, resources, or conditions that do not
provide permissions. To grant access, policies must have an action
that has an applicable resource or condition. For details, choose Show
remaining Learn more
The AWS documentation mention exactly the same configuration or these examples.

I assume you connect as that user in the console (but it would be the same with CLI) Here is what I think is happening:
To list all the instances, the console most probably calls the DescribeInstances API. As per the list of action/resources/tags that can be used in IAM policy, this API does not support the resource filter in IAM.
This means your user has no authorization to list instances and they will not be shown in the console. You can validate this theory by using the CLI to request the details of a specific instance id, if my hypothesis is correct, it will be authorized.
As DescribeInstances can not be restricted by resource or tags, I don't think it is possible to filter the instance list for a user.
To have the console working, you'll need to add the following statement in your IAM policy
"Statement": [
{ your existing statement },
{
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*"
}
]
Please report if I was right :-) The example you mentioned in your question shows exactly that : Resources = * on DescribeInstances and Resources specific InstanceId on other operations.

The previous answer is wrong, you can Conditionally allow access to ec2:DescribeInstances by tag names. It's an AWS best practice as well. Also explicitly deny access to the ec2:CreateTags and ec2:DeleteTags actions to prevent users from creating or deleting tags to take control of the instance.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/UserName": "${aws:username}"
}
}
},
{
"Effect": "Deny",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*"
}
]
}

DescribeInstances action does not support condition.
https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html

Related

AWS Assume Role: "Invalid information in one or more fields."

I am planning to implement AssumeRole scenario so below is scenario
user will have ability to create/stop Ec2 instances but not terminate.
To terminate he has to assume role (role to be assumed Ec2FullAccess)
I have done the following
Create a user Test1 with permission to start/stop/launch Ec2 instance and have provided permission to assume role (EC2FullAccess) below is the Policy for user
{
"Version": "2012-10-17",
"Statement": [<br>
{
"Action": "ec2:*",
"Effect": "Allow",
"Resource": "*"
},
{
"Effect": "Deny",
"Action": "ec2:TerminateInstances",
"Resource": "*"
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "arn:aws:iam::226904037275:role/EC2FullAccess"
}
]
}
Create a role in same account with name EC2FullAccess which would give permission to terminate Ec2 instance
Ec2FullAccess uses AmazonEC2FullAccess Permission Policy below is its Trust Policy
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Now when i login as IAM user Test1 and then click on switch role ,i provide below details
Account: 1234
Role: EC2FullAccess
When i click on Switch Role i get Below error
Invalid information in one or more fields. Check your information or contact your administrator.
What is that I am missing
You can create the Role this way:
Create Role
For Type of Trusted Entity, select Another AWS Account and enter the Account ID for the same account (it is displayed in the same menu as the 'Switch Role' command) -- This might seem odd, but it creates the correct principal in the Trust Policy.
Attach desired policies and Save
Then, use Switch Role.
By the way, assigning EC2FullAccess is probably overkill -- it gives permission to do anything in EC2, including deleting VPCs, deleting Amazon EBS volumes, changing network settings, etc. I suggest you create a specific policy that grants TerminateInstances permission, and possibly even reduce that down to specific instances (eg by tag or VPC).

EC2 Instance profile to access DynamoDB

I want to use ec2 instance profile to allow my python program to access a DynamoDb table. I have tested a policy by directly assigning to the user. Now I assign this same policy as a Instance Profile to ec2 instance where my job is running.
This is the policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:*"
],
"Resource": "arn:aws:dynamodb:us-east-2:913580688765:table/users"
}
]
}
Additionally I assigned a policy to the user to be able to Pass the ec2 role.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AssociateIamInstanceProfile",
"ec2:ReplaceIamInstanceProfileAssociation"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "ec2:DescribeIamInstanceProfileAssociations",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*"
}
]
}
But this does not work.
What am I missing here?
I don't have the exact answer for you but I have advice on how you can progress. First off, lets recap (and can you please double check all this):
1) You have an EC2 instance running, it's assigned to an IAM role.
2) The IAM Role trust relationship contains ec2.amazonaws.com.
3) The policy granting "dynamodb:*" is attached to the role.
If this is done, that means everything should be configured properly.
At this point, i would suggest you ssh to the EC2 instance and test out the permissions. This can be done by using the AWS CLI's dynamodb API to make a list/describe/get API calls to confirm they work on the instance. If they works, it means the instance has permissions to access dynamodb and there might be something wrong with how you're using the instance profile.
It's worthy to note that not all operations are going to work on "arn:aws:dynamodb:us-east-2:913580688765:table/users" since it's a specific table rather than all the tables e.g. "arn:aws:dynamodb:us-east-2:913580688765:table/*". API calls such as list-tables won't work if the resource is a specific table. You can find a list of dynamodb api calls and weather or not they support a specific table or not in the documentation here.

AWS IAM grant user read access to specific VPC only

I have tried to limit access to a VPC without success. Maybe approaching the issue from the other side is a better idea, but I can't get that to work either.
I have tried:
Limit by tags as shown here:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/client": "<client>"
}
}
}
]
}
Limit by VPC as suggested here:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1508450090000",
"Effect": "Allow",
"Action": [
"ec2:Describe*"
],
"Resource": [
"arn:aws:ec2:<region>:<account>:subnet/*"
],
"Condition": {
"StringEquals": {
"ec2:Vpc": "arn:aws:ec2:<region>:<account>:vpc/<vpc_id>"
}
}
}
]
}
Both policies result in not even listing any instances, see screenshot.
This seems to be a very obvious and commonly needed policy to me.
Any help is appreciated.
According to the documentation: http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_IAM.html#readonlyvpciam
The following policy grants users permission to list your VPCs and
their components. They can't create, update, or delete them.
{
"Version": "2012-10-17",
"Statement":[{
"Effect":"Allow",
"Action":["ec2:DescribeVpcs",
"ec2:DescribeSubnets",
"ec2:DescribeInternetGateways",
"ec2:DescribeEgressOnlyInternetGateways",
"ec2:DescribeVpcEndpoints",
"ec2:DescribeNatGateways",
"ec2:DescribeCustomerGateways",
"ec2:DescribeVpnGateways",
"ec2:DescribeVpnConnections",
"ec2:DescribeRouteTables",
"ec2:DescribeAddresses",
"ec2:DescribeSecurityGroups",
"ec2:DescribeNetworkAcls",
"ec2:DescribeDhcpOptions",
"ec2:DescribeTags",
"ec2:DescribeInstances"],
"Resource":"*"
}
]
}
Further, if you have multiple VPCs that you do not want them to even see, perhaps you should consider creating a sub-account with only the portion of your network that they should have visibility across:
Setup Consolidated Billing
As a first step, log into your AWS account and click the "Sign up for Consolidated Billing" button.
Create a new account
From a non-logged in browser, you will then want to sign up again to AWS again like this:
Give this new account the appropriate name for your client. Note the email address you signed up with.
Link the accounts
In your main account, head back to ConsolidatedBilling and click the Send a Request button. Provide the email address for your new sub-account.
You should receive an email to the email address for your new sub-account. Copy the activation link and paste it into your browser logged in to the sub-account.
Your accounts are now linked!
Create your clients VPC and enable the services that the client requires.
Next, you can create the VPC & services the client requires, and restrict their access via the policy above.
You cannot restrict Describe* calls in the manner you want.
Calls that create resources can be restricted (eg give permission to launch an instance in a particular VPC), but calls that list resources cannot be restricted.
If you require the ability to prevent certain users from listing resources, then you'll either need to build your own front-end that filters the information before presenting it to users, or use multiple AWS accounts since they are fully isolated from each other.

AWS IAM SSM - Restrict Documents that Instances can run

Is there a way to restrict the IAM policy for an EC2 instance s.t. it can only run a short list of Documents - I tried restricting access to ssm:GetDocument like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetDocument"
],
"Resource": [
"arn:aws:ssm:ap-southeast-2:*:document/MyCommand"
]
}
]}
But I can run any command on the instance still including the AWS-RunPowershellScript document.
This link shows how users can be restricted with respect to ssm:sendCommand:
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/delegate-commands.html
I have not found a way to restrict SendCommand based on document. If a user does not have access, you get an error like this:
User: arn:aws:iam::123456789012:user/username is not authorized to perform: ssm:SendCommand on resource: arn:aws:ec2:us-east-1:123456789012:instance/i-01234567890abcdef
This indicates that the Resource in SendCommand can be limited based on instance ids. It would be nice if one of the Conditions was a Document ARN, but so far I haven't found any way to do it (it's not a condition in the policy generator wizard).
Update: I posted this question on the AWS forums, hopefully I'll get a response: https://forums.aws.amazon.com/thread.jspa?threadID=249039
Update 2: I got a response and the solution is that to accomplish this you must use Resource to specify both what instances you allow commands to be run on, and what document the user is allowed to run. For example, this is what I ended up with:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:SendCommand"
],
"Resource": [
"arn:aws:ec2:*:123456789012:instance/*",
"arn:aws:ssm:*:123456789012:document/RestartServices"
]
}
]
}

Giving access to AWS Lambda service with limited policy

I am trying to follow this tutorial to setup a lambda function to shutdown/startup instances with a special tag added to ec2 instances.
The policy assigned to my role by Admin user gives me access to all lambda function e.g by
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:*",
"cognito-identity:ListIdentityPools",
"cognito-sync:GetCognitoEvents",
"cognito-sync:SetCognitoEvents",
"dynamodb:*",
"events:*",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:ListRoles",
"iam:PassRole",
"kinesis:DescribeStream",
"kinesis:ListStreams",
"kinesis:PutRecord",
"lambda:*",
"logs:*",
"s3:*",
"sns:ListSubscriptions",
"sns:ListSubscriptionsByTopic",
"sns:ListTopics",
"sns:Subscribe",
"sns:Unsubscribe"
],
"Resource": "*"
}
]
}
I am stuck as step 6 while setting Lambda function handler and role while selecting "Basic execution role" with error
User: arn:aws:iam::xxxx:user/Yyyy is not authorized to perform:
iam:CreateRole on resource: arn:aws:iam::xxxx:role/lambda_basic_exec
My role policy looked sth like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:Start*",
"ec2:RunInstances",
"ec2:Stop*",
],
"Resource": "*"
}
]
}
That seems reasonable given my limited rights.
What should I ask my Admin to update policy assigned to me, so I can successfully set scheduled event for lambda function as described in tutorial ? Or this can be done in some other way around using IAM e.g by adding new role ? I want only sufficient rights.
As some time has passed since this question was answered and AWS changed a lot, I want to mention a new feature which was launched by AWS in 2018: Permissions Boundaries for IAM Entities [1].
They are used "to delegate permissions management to trusted employees" [2] and other IAM entities (such as roles).
That is, you do not need to grant a specific role admin-like permissions in order to create other roles as the accepted answer states. You may grant the role iam:CreateRole permission with a condition that requires a permission boundary being set on each newly created role: {"StringEquals": {"iam:PermissionsBoundary": "arn:aws:iam::111122223333:policy/XCompanyBoundaries"}}.
The policy which is specified by the permission boundary defines the maximum permission which are effectively assigned to the role. [1]
In order to create a role with a permission boundary you can e.g. use the optional parameter --permissions-boundary for the cli command aws iam create-role. [3]
References
[1] https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html
[2] https://aws.amazon.com/blogs/security/delegate-permission-management-to-developers-using-iam-permissions-boundaries/
[3] https://docs.aws.amazon.com/cli/latest/reference/iam/create-role.html
you have a security constraint, as you would need the "iam:CreateRole" in your policy, along with something like "iam:attachRolePolicy" and "iam:createPolicy". So with that you would basically be admin of your account, as you could create roles with any policy and attach it to an EC2 instance or assume it directly.
What you could do is having your admin create one or several roles for lambda, e.g one for S3 access, one for ec2 commands etc. When you want then to create a lambda function, choose one of these pre-created roles instead of creating a new one.