I have created a s3 bucket and along with it i added a policy to the bucket saying to deny ListBucket action for a canonical user. Here canonical user is nothing but me. Below is my code..
s3_client.create_bucket(Bucket=bucket_name)
bucket_policy = {
'Version': '2012-10-17',
'Statement': [{
'Sid': 'AddPerm',
'Effect': 'Deny',
'Principal':
#I am denying ListBucket access to this canonical user id.
{"CanonicalUser":"1234567777777777777777544444444466666ac73d5bc7cd43619"},
'Action': ['s3:ListBucket'],
'Resource': f'arn:aws:s3:::{bucket_name}',
}]
}
# Convert the policy from JSON dict to string
bucket_policy = json.dumps(bucket_policy)
s3_client.put_bucket_policy(Bucket=bucket_name, Policy=bucket_policy)
s3_client.put_object(Bucket=bucket_name, Key="a/b/c/abc.txt")
#Still i am getting response for this list_objects operation.
response = s3_client.list_objects(Bucket=bucket_name)
print(response)
How can I remove a specific s3 bucket permission to a root user?
Thanks
Based on comments, the question was to deny root user access to resources within the same account, which is not recommended as well.
You can only use an AWS Organizations service control policy (SCP) to limit the permissions of the root user
Below approach described is for cross account access.
As per the documentation you can address root user in the following format
"Principal":{"AWS":"arn:aws:iam::AccountNumber-WithoutHyphens:root"}
"Principal":{"AWS":["arn:aws:iam::AccountNumber1-WithoutHyphens:root","arn:aws:iam::AccountNumber2-WithoutHyphens:root"]}
Grant permissions to an AWS Account
For example
{
"Id": "Policy1616693279544",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt161669321",
"Action": [
"s3:ListBucket"
],
"Effect": "Deny",
"Resource": "arn:aws:s3:::mybucketname",
"Principal": {
"AWS": [
"arn:aws:iam::1234567890:root"
]
}
}
]
}
If you don want to stress about correct policy generation you can cross verify with this tool here
AWS Policy Generator
Your AWS account identifiers
Related
{
"Version": "2012-10-17",
"Id": "Policy1612574490300",
"Statement": [
{
"Sid": "Stmt1612574488073",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:ec2:us-east-1:258977512672:instance/i-041123c1993c370ba"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::my_bucket",
"arn:aws:s3:::my_bucket/*"
]
}
]
}
response is Invalid Principal. I dont see why it's invalid.
An EC2 instance isn't a valid principal. I think what you actually need to do here is use the ARN of the IAM role assigned to the EC2 instance.
You can specify following Principal in a policy
AWS account and root user
IAM users
Federated users (using web identity or SAML federation)
IAM roles
Assumed-role sessions
AWS services
Anonymous users (not recommended)
S3 Documentation Principal
AWS JSON policy elements: Principal
If you wanna give that instant access to the bucket then you can use Instance profiles
Allow access from IAM Role in AccountA to given S3 buckets only if they are present in AWS AccountB (using Account Number).
Here is my Role policy in AccountA which currently has following permission. How can I update it to only access S3 bucket in AccountB.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"s3:Put*"
],
"Resource": [
"arn:aws:s3:::kul-my-bucket/my-dir/*"
]
},
{
"Sid": "ListBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::kul-my-bucket"
]
}
]
}
Wondering if it is possible or should I try it differently?
Is anything similar to this possible for my case by providing the condition in the policy:
"Condition": {
"StringLike": {
"aws:accountId": [
"111111111111"
]
}
}
I need this because on the S3 bucket in AccountB it allows root access to AccountA. Hence I want to put restriction on Role policy in AccountA.
I do not think it is possible to grant/deny access to an Amazon S3 bucket based on an AWS Account number. This is because Amazon S3 ARNs exclude the Account ID and instead use the unique bucket name.
You would need to grant Allow access specifically to each bucket by name.
I have seen this situation before where the requirement was to grant S3 permission to access buckets only in other accounts, but not the account owning the IAM User themselves. We could not determine a way to do this without also granting permission to access the "same account" S3 buckets.
Try to use cognitoIdentityService.listUsers with a role running ec2 machine and it works great in the local org (orgA).
I also want the same role to listUser in another org (orgB).
I created a a role with trust in the orgB with orgA in the Trust relationship and gave it Cognito permissions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxxxxxxx:root"
},
"Action": "sts:AssumeRole"
}
]
}
Then in orgA i added an inline policy to the role i want to give access
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::xxxxxxxxxxxx:role/orgBCognitoAccess"
}
}
I pass the REGION and USERPOOLID to my function.
const params = {
"UserPoolId": UserPoolId,
"Filter": `email = \"${email}\"`,
"Limit": 1
}
cognitoIdentityService.listUsers(params, (err, data) => {
But all i get in return is an error. Should it be switch roles when it sees the userpool does not exist? Is that logic I have to write in or can it be done at all?
{"message":"User pool ca-central-1_BBBBBBBB does not exist.","code":"ResourceNotFoundException","time":"2021-01-18T18:01:29.279Z","requestId":"acc14424-9f1d-411a-95f2-1a302e5773f8","statusCode":400,"retryable":false,"retryDelay":21.27495199615266}
Thanks
Yes, you have given permissions and everything to the roles, but you are still using role in OrgA, so to make the API call you to have to switch role in OrgB and use those credentials for making the client and eventually make the call.
sts_client = boto3.client('sts')
# Call the assume_role method of the STSConnection object and pass the role
# ARN and a role session name.
assumed_role_object=sts_client.assume_role(
RoleArn="arn:aws:iam::account-of-role-to-assume:role/name-of-role",
RoleSessionName="AssumeRoleSession1"
)
# From the response that contains the assumed role, get the temporary
# credentials that can be used to make subsequent API calls
credentials=assumed_role_object['Credentials']
# Use the temporary credentials that AssumeRole returns to make a
# connection to Amazon S3
s3_resource=boto3.resource(
's3',
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken'],
)
# Use the Amazon S3 resource object that is now configured with the
# credentials to access your S3 buckets.
for bucket in s3_resource.buckets.all():
print(bucket.name)
you can find more details in the documentation
To verify this during the testing you can make GetCallerIdentity this gives you enough details.
{
"UserId": "AIDASAMPLEUSERID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/DevAdmin"
}
I am the root user of my account and i created one new user and trying to give access to s3 via s3 bucket policy:
Here is my policy details :-
{ "Id": "Policy1542998309644", "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1542998308012", "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": "arn:aws:s3:::aws-bucket-demo-1", "Principal": { "AWS": [ "arn:aws:iam::213171387512:user/Dave" ] } } ]}
in IAM i have not given any access to the new user. I want to provide him access to s3 via s3 bucket policy. Actually i would like to achieve this : https://aws.amazon.com/premiumsupport/knowledge-center/s3-console-access-certain-bucket/ But not from IAM , I want to use only s3 bucket policy.
Based on the following AWS blog post (the blog shows IAM policy, but it can be adapted to a bucket policy):
How can I grant a user Amazon S3 console access to only a certain bucket?
you can make the following bucket policy:
{
"Id": "Policy1589632516440",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1589632482887",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::aws-bucket-demo-1",
"Principal": {
"AWS": [
"arn:aws:iam::213171387512:user/Dave"
]
}
},
{
"Sid": "Stmt1589632515136",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::aws-bucket-demo-1/*",
"Principal": {
"AWS": [
"arn:aws:iam::213171387512:user/Dave"
]
}
}
]
}
This will require user to url directly to the bucket:
https://s3.console.aws.amazon.com/s3/buckets/aws-bucket-demo-1/
The reason is that the user does not have permissions to list all buckets available. Thus he/she has to go directly to the one you specify.
Obviously the IAM user needs to have AWS Management Console access enabled when you create him/her in the IAM service. With Programmatic access only, IAM users can't use console and no bucket policy can change that.
You will need to use ListBuckets.
It seems like you want this user to only be able to see your bucket but not access anything in it.
What I want is to let groups (families) of aws cognito users to read/write to S3 buckets which should be only available for those families of users.
I created a user with boto3 python library. Now I need to grant this user access to their folder in the bucket.
I found a few posts which suggested to create bucket policy like this:
policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Grant user access to his folder",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::BUCKET/users/${cognito-identity.amazonaws.com:sub}",
"Condition": {
"StringLike": {
"cognito-identity.amazonaws.com:sub": [
"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
"us-east-1:yyyyyyyy-xxxx-xxxx-xxxx-xxxxxxxxxx"
]
}
}
}
]}
But it turns out we can not specify "cognito-identity.amazonaws.com:sub" in bucket's policy condition.
Any help is highly appreciated.
I think the policy you have above needs to be in the IAM role for an authenticated user, not part of a bucket policy.