IAM Access Key permissions override an Explicit Deny in an IAM role? - amazon-web-services

I have an EC2 instance with a role with the following policy applied:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": [
"s3:PutObject"
],
"Resource": "*"
}
]
}
With just the role applied, it works as expected - I can view the bucket contents but can't copy objects to the bucket.
However, if I then add access keys for an IAM user with the AmazonS3FullAccess policy, the instance is able to copy objects to the bucket.
How is this allowed? My understanding is that any explicit deny in any of the associated policies is final.

This happens because hard coded credentials have higher priority then instance profile. Subsequently, your deny is not even considered in your scenario.
It would be better to put such deny in bucket policy, not instance role.

Related

S3 access to only one IAM user

How do I set the S3 read permission to only my IAM User can access? I have my IAM User config in the backend for my hybrid app but I still can't get access to S3 list.
Here is my bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxx:user/xxx#xxx.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-s3-bucket/*"
}
]
}
I tried was s3 ls s3://my-s3-bucket on terminal it is showing the list of items in my s3 bucket but not the backend. If I change the Principal to "*" I can access without any problem. (I want to limit to only my app can access it with the IAM User credential I have).
The error I have
{"code":"InternalError","message":"Access Denied"}
Thank you.
The aws s3 ls command is used to list the contents of a bucket but your policy is only granting permission to GetObject (which means to read the contents of an object).
If you wish to allow listing of the bucket, you would also need to grant s3:ListBucket permissions.
Bucket Policies vs IAM Policies
Typically, Bucket Policies are used to grant public or cross-account access.
If you wish to grant access to a specific IAM User, then it is better to add a policy on the IAM User themselves:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-s3-bucket/*"
}
]
}
However, you say "only one user". This becomes more difficult if any other users have been granted access to ALL S3 buckets with an Admin-like policy. In this situation, it you would need to add a Deny to the Bucket Policy to prevent access by anyone who has been granted access to all Buckets. This starts to get a little tricky because Deny policies have a habit of denying more than you expect.
If the bucket contains sensitive information, another option is to put the bucket in a different AWS Account and then only grant cross-account access to the specific IAM Users who need access. This prevents people gaining Admin-like access and avoids the need to use a Deny policy.
For s3 ls s3://my-s3-bucket to work you need s3:ListBucket permissions along with bucket resource:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxx:user/xxx#xxx.com"
},
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::my-s3-bucket/*",
"arn:aws:s3:::my-s3-bucket"]
}
]
}

how I grant s3 bucket access with this particular role?

I've looked at some other solutions for similar questions, but here's the twist: I was given this and asked to grant s3 bucket for another account to put/get objects:
arn:aws:iam::[account number]:role/CustomerManaged/XMO-Custom-SPEG-DPM-Share-Role
I know the basics of how to change bucket policies in the JSON format. Do I need to create the JSON from this in the s3 bucket policy, or do I add this in IAM? I have seven tabs open for AWS doc pages but am getting lost in the weeds of what to do here.
In account B, which needs to access account A's bucket, set up an IAM role that includes the relevant permissions (e.g. s3:GetObject on s3://bucketa/prefix/*). For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::bucketa/prefix/*"
}
]
}
In account A, which owns the bucket, add an S3 bucket policy to bucketa that gives the relevant permissions to the account B role. For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountb:role/rolename"
},
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::bucketa/prefix/*"
]
}
]
}
Finally, in account B, given the relevant IAM users or roles permission to assume the account B role so that they can get cross-account access to the bucket.
Alternatively, rather then delegate permissions directly to an IAM role in account B, account A can set a principal of "AWS": "arn:aws:iam::accountb:root" in the bucket policy and this will allow account B administrators to delegate permission as they choose (see example).
For more, see How can I provide cross-account access to objects that are in Amazon S3 buckets?
It appears that your requirement is:
An IAM Role (Role-A) in Account-A wants to access...
An Amazon S3 Bucket (Bucket-B) in Account-B
You are an Administrator in Account-B
The simplest way to permit such access is to add a Bucket Policy to Bucket-B:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-A:role/CustomerManaged/XMO-Custom-SPEG-DPM-Share-Role"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::bucket-name/*"
]
}
]
}
This policy says:
Allow the given IAM Role
Permission to put/get objects
In this bucket
There is no need to assume roles. Simply adding this bucket policy on Bucket-B allows Role-A to access the bucket.
Oh, and Role-A also needs to be granted sufficient S3 permissions to access the bucket, which might be via generic permissions (eg s3:GetObject on a Principal of *), or it could be specific to this bucket. Basically, Account-A has to grant it permission (via IAM), AND Account-B has to grant it permission (via the bucket policy).

Bucket policy to prevent bucket delete

I am looking for a bucket policy which allows only the root account user and the bucket creator to delete the bucket. something like below. Please suggest. How to restrict to only bucket creator and root?
{
"Version": "2012-10-17",
"Id": "PutObjBucketPolicy",
"Statement": [
{
"Sid": "Prevent bucket delete",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxx:root"
},
"Action": "s3:DeleteBucket",
"Resource": "arn:aws:s3:::test-bucket-s3"
},
{
"Sid": "Prevent bucket delete",
"Effect": "Deny",
"Principal": *,
"Action": "s3:DeleteBucket",
"Resource": "arn:aws:s3:::test-bucket-s3"
}
]
}
A Deny always beats an Allow. Therefore, with this policy, nobody would be allowed to delete the bucket. (I assume, however, that the root user would be able to do so, since it exists outside of IAM.)
There is no need to assign permissions to the root, since it can always do anything.
Also, there is no concept of the "bucket creator". It belongs to the account, not a user.
Therefore:
Remove the Allow section (it does nothing)
Test whether the policy prevents non-root users from deleting it
Test whether the policy still permits the root user to delete it
There are 2 different type of permission in S3.
Resource Based policies
User Policies
So Bucket policies and access control lists (ACLs) are part of Resource Based and which attached to the bucket.
if all users are in same aws account. you can consider user policy which is attached to user or role.
if you are dealing with multiple aws accounts, Bucket policies or ACL is better.
only different is, Bucket policies allows you grant or deny access and apply too all object in the bucket.
ACL is grant basic read or write permission and can't add conditional check.

can we restrict policies of role in child aws account to be used by only organization aws account

I have organization root aws account named cloud. below is the policy attached to it.
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::XXXXXXXXX:role/Account-accessROle"
]
}
}
I have role Accountaccessrole created in child accounts. this role have trust relationship with organization account such that only cloud user can assume this role.
it's trust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::{ROOTACCOUNT}:user/cloud"
},
"Action": "sts:AssumeRole"
}
]
}
its attached policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "EC2:*",
"Resource": "*",
}
}
]
}
this is sorted. but the users from child account (XXXXX) can use this role in lambda to do something....I want to restrict it....no one from child account should do any thing with this role...how to restrict this??
tried adding the condition for policy in child account roles..but could not find any specific
If you are showing correct trust policy then users can't pass this role to a Lambda function because there is no trust between Lambda service and your role.
Second things is that users in your child account (or any account for that matter) do not have rights to assume any role by default (they do not have right to do anything by default) which means that someone granted them that privilege.
Easy solution would be to remove this privilege from them. If that is not feasible due to amount of work it would require then you can simple create IAM policy which denies sts:AssumeRole for that particular resource (the IAM role that you want to restrict) and apply this role to a group where you can place all your users. This will however not prevent root user of the child account (or any user with permissions to IAM service) from bypassing this restriction.
Another option is to deny the above mentioned action in SCP and apply that SCP to the child account. You can either modify your current SCP if possible or you can create new one and apply it directly to the child account (note that you can apply multiple SCPs to an account/OU and explicit deny will overrule any existing allow statements).

AWS S3 bucket access control

In AWS, I (joe.doe#accountXYZ) created a S3 bucket, thus I am this s3 bucket owner.
I want to configure this S3 bucket based on the IAM role, thus only some IAM roles, such as [role_xyz, role_abc, role_cde], can can read this bucket.
From the AWS console, it seems that I can not configure it.
Can anyone tell me whether it is possible to do that?
========
I understand that from the IAM role side you can configure a policy for this s3 resource. But my question here is on the s3 resource side, whether I can define a access policy based IAM roles.
It appears that your requirement is to permit certain specific roles access to a particular Amazon S3 bucket.
There are two ways to do this:
Option 1: Add permissions to the Role
This is the preferred option. You can add a policy to the IAM Role that grants access to the bucket. It would look similar to:
{
"Id": "Policy1",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
}
]
}
This is a good method because you just add the policy to the desired Role(s), without having to touch the actual buckets.
Option 2: Add a Bucket Policy
This involves putting the permissions on the bucket, which grants access to a specific role. This is less desirable because you would have to put the policy on every bucket and refer to every Role.
It would look something like:
{
"Id": "Policy1",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::my-bucket/*"
],
"Principal": "arn:aws:iam::123456789012:role/my-role"
}
]
}
Please note that these policies are granting s3:* permissions on the bucket, that might be too wide for your purposes. It is always best to only grant the specific, required permissions rather than granting all permissions.