Why can't I access my bucket from an assumed role? - amazon-web-services

I have an S3 bucket with no attached ACLs or policies. It was created by terraform like so:
resource "aws_s3_bucket" "runners_cache" {
bucket = var.runners_cache.bucket
}
I created a role and attached a policy to it; see the following console log for details
$ aws iam get-role --role-name bootstrap-test-bootstrapper
{
"Role": {
{
"Role": {
"Path": "/bootstrap-test/",
"RoleName": "bootstrap-test-bootstrapper",
"RoleId": "#SNIP",
"Arn": "arn:aws:iam::#SNIP:role/bootstrap-test/bootstrap-test-bootstrapper",
... #SNIP
$ aws iam list-attached-role-policies --role-name bootstrap-test-bootstrapper
{
"AttachedPolicies": [
{
"PolicyName": "bootstrap-test-bootstrapper",
"PolicyArn": "arn:aws:iam::#SNIP:policy/bootstrap-test/bootstrap-test-bootstrapper"
},
... #SNIP
$ aws iam get-policy --policy-arn arn:aws:iam::#SNIP:policy/bootstrap-test/bootstrap-test-runner
{
"Policy": {
"PolicyName": "bootstrap-test-runner",
"PolicyId": "#SNIP",
"Arn": "arn:aws:iam::#SNIP:policy/bootstrap-test/bootstrap-test-runner",
"Path": "/bootstrap-test/",
"DefaultVersionId": "v7",
... #SNIP
$ aws iam get-policy-version --policy-arn arn:aws:iam::#SNIP:policy/bootstrap-test/bootstrap-test-runner --version-id v7
{
"PolicyVersion": {
"Document": {
"Statement": [
{
"Action": [
"s3:AbortMultipartUpload",
"s3:CompleteMultipartUpload",
"s3:ListBucket",
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:PutObjectAcl"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::#SNIP-runners-cache/*",
"arn:aws:s3:::#SNIP-cloud-infrastructure-terraform-states/*"
]
},
{
"Action": [
"s3:*"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::*"
]
}
],
"Version": "2012-10-17"
},
"VersionId": "v7",
"IsDefaultVersion": true,
"CreateDate": "2022-08-18T14:16:33+00:00"
}
}
tl;dr this role has an attached policy that allows full access to s3 within the account.
I can successfully assume this role:
$ aws sts assume-role --role-arn arn:aws:iam::#SNIP:role/bootstrap-test/bootstrap-test-bootstrapper --role-session-name test123
{ ... #REDACTED }
$ export AWS_ACCESS_KEY_ID=ASIA2 #REDACTED
$ export AWS_SECRET_ACCESS_KEY=8 #REDACTED
$ export AWS_SESSION_TOKEN=IQoJb #REDACTED
$ aws sts get-caller-identity
{
"UserId": "#SNIP",
"Account": "#SNIP",
"Arn": "arn:aws:sts::#SNIP:assumed-role/bootstrap-test-bootstrapper/test123"
}
However, once I do this, I no longer have access to S3:
$ aws s3 ls #SNIP-runners-cache
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
$ aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
What am I missing? Is there some default behavior that prevents access to S3? How should I go about debugging these 403 errors?

It is easy to get over-obsessed with the details of the policy and forget about the role itself. In this case the permissions boundary went unnoticed in the CLI, but it is quite easy to see in the web console:
Indeed, #luk2302 was right, the limiting factor was a permissions boundary. After removing it from the role, access to S3 was restored.

Related

I'm able to assume AWS role in Console but not in cli

I have AWS organization with users (id: 111111111111) and dev (id: 222222222222) accounts. Users first login to the users account, and then able to switch to the dev account.
The problem: Users are able to switch role via console (website), but NOT via the CLI...
This is how I switch via the CLI:
export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" \
$(aws sts assume-role \
--role-arn arn:aws:iam::222222222222:role/administrator \
--role-session-name TestSessionName \
--query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
--output text))
And I get the following error:
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::111111111111:user/gitlab-ci-user is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::222222222222:role/administrator
Made sure which user i'm logged in via cli:
> aws sts get-caller-identity
{
"UserId": "...",
"Account": "111111111111",
"Arn": "arn:aws:iam::111111111111:user/gitlab-ci-user"
}
The user gitlab-ci-user is member of the AdminsDevAssumeRole group, and the following policy:
{
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": [
"arn:aws:iam::222222222222:role/administrator"
]
}
],
"Version": "2012-10-17"
}
In the dev account (222222222222), I got role administrator, with the following trust relationship:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
Any idea why i'm not able to switch role via cli (but do in console)?

How to require users to set their role_session_name with scp

Using scp, I would like to require role_session_name to users who assume roles in my organization accounts when running terraform template. The role_session_name value need to be equals to their iam username.
I have attached below scp in my organization
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "sts:AssumeRole",
"Resource": "*",
"Condition": {
"StringNotLike": {
"sts:RoleSessionName": [
"${aws:username}"
]
}
}
}
]
}
Below the ~/.aws/config file content
[profile my_profile]
region = us-west-3
role_arn = arn:aws:iam:ACOUNT_ID:role/role_name
output = json
below provider section of terraform template
provider "aws" {
shared_credentials = "~/.aws/credentials"
region = "eu-west-3"
profile = "my_profile"
}
Without specifying role_session_name = my_aws_user_name` inside the config file, I am able to run the template without being blocked by the scp.
How to achieve this please ?
Thanks
EDIT
I finally setup an AWS organization to test. The SCP as you now have is working fine. Role is in account A. SCP attached to account B:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "sts:AssumeRole",
"Resource": "*",
"Condition": {
"StringNotLike": {
"sts:RoleSessionName": [
"${aws:username}"
]
}
}
}
]
}
Using a user in account B, I tried to assume a Role in Account A using a random session name. Got access denied.
>aws sts assume-role --profile accountB --role-arn arn:aws:iam::<account-A>:role/<rolename> --role-session-name abc
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::<account-B>:user/<username> is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::<account-A>:role/<rolename>
But when I use a session name that is same as my username, I am able to.
>aws sts assume-role --profile accountB --role-arn arn:aws:iam::<account-A>:role/<rolename> --role-session-name username
{
"Credentials": {
"AccessKeyId": "xxx",
"SecretAccessKey": "xxx",
"SessionToken": "xxx",
"Expiration": "2022-03-23T10:31:52Z"
},
"AssumedRoleUser": {
"AssumedRoleId": "xxx:username",
"Arn": "arn:aws:sts::xxx:assumed-role/xxx/yyy"
}
}
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam:::user/ is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam:::role/T
this issue is your profile account doesnt has permission attach policy for other account, so I give the IAM full access of role then run fine.

Accessing S3 bucket from a dedicated user ( policy failure ? )

I'm trying to create an S3 bucket with a dedicated user for upload/download using terraform.
For some reason the user that is being created is unable to access the bucket:
$ aws iam list-attached-user-policies --user-name csgoserver
{
"AttachedPolicies": [
{
"PolicyName": "AllowUsercsgoserverAccessTocsgofiles",
"PolicyArn": "arn:aws:iam::370179080679:policy/AllowUsercsgoserverAccessTocsgofiles"
}
]
}
$ aws s3 cp bucket.tf s3://csgofiles --profile test
upload failed: .\bucket.tf to s3://csgofiles/bucket.tf An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
$ aws iam get-user-policy --user-name csgoserver --policy-name AllowUsercsgoserverAccessTocsgofiles
An error occurred (NoSuchEntity) when calling the GetUserPolicy operation: The user policy with name AllowUsercsgoserverAccessTocsgofiles cannot be found.
user.tf:
resource "aws_iam_user" "s3user" {
name = var.user_name
force_destroy = true
}
data "aws_iam_policy_document" "default" {
statement {
sid = "AllowUser${var.user_name}AccessTo${var.bucket_name}"
actions = ["s3:*"]
resources = ["arn:aws:s3:::${var.bucket_name}"]
effect = "Allow"
}
}
resource "aws_iam_user_policy" "s3user_policy" {
name = aws_iam_user.s3user.name
user = aws_iam_user.s3user.name
policy = join("", data.aws_iam_policy_document.default.*.json)
}
resource "aws_iam_access_key" "s3user_ak" {
user = aws_iam_user.s3user.name
}
There is one more thing I do not understand. The aws iam get-policy doesn't work on that policy:
$ aws iam list-policies --max-items 2
{
"Policies": [
{
"PolicyName": "AllowUsercsgoserverAccessTocsgofiles",
"PolicyId": "ANPAVMMDEQHTRE4NG3N2E",
"Arn": "arn:aws:iam::370179080679:policy/AllowUsercsgoserverAccessTocsgofiles",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2021-11-26T22:17:52+00:00",
"UpdateDate": "2021-11-26T22:17:52+00:00"
},
{
"PolicyName": "eks-full-access-policy",
"PolicyId": "ANPAVMMDEQHTR4C65WFT6",
"Arn": "arn:aws:iam::370179080679:policy/eks-full-access-policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2021-03-30T09:57:04+00:00",
"UpdateDate": "2021-03-30T09:57:04+00:00"
}
],
"NextToken": "eyJNYXJrZXIiOiBudWxsLCAiYm90b190cnVuY2F0ZV9hbW91bnQiOiAyfQ=="
}
$ aws iam get-policy --policy-arn arn:aws:iam::370179080679:policy/AllowUsercsgoserverAccessTocsgofile
An error occurred (NoSuchEntity) when calling the GetPolicy operation: Policy arn:aws:iam::370179080679:policy/AllowUsercsgoserverAccessTocsgofile was not found.
$ aws iam get-policy --policy-arn arn:aws:iam::370179080679:policy/eks-full-access-policy
{
"Policy": {
"PolicyName": "eks-full-access-policy",
"PolicyId": "ANPAVMMDEQHTR4C65WFT6",
"Arn": "arn:aws:iam::370179080679:policy/eks-full-access-policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2021-03-30T09:57:04+00:00",
"UpdateDate": "2021-03-30T09:57:04+00:00"
}
}
I don't think your IAM policy is valid.
You could use something similar to the below:
{
"Id": "Policy1638106306386",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1638106302079",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::examplebucket",
"Principal": {
"AWS": [
"370179080679"
]
}
}
]
}
I would also suggest putting the policy inline in your aws_iam_user_policy resource rather than using a data source.
And looking at the documentation it does seem policy is a required field within the aws_iam_user_policy resource.
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_user_policy
Maybe like the below:
resource "aws_iam_user_policy" "s3user_policy" {
name = aws_iam_user.s3user.name
user = aws_iam_user.s3user.name
policy = jsonencode ({
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1638106302079",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::examplebucket/*",
}
]
})
I was missing two characters in the Resource key at the end /* ...
data "aws_iam_policy_document" "default" {
statement {
sid = "AllowUser${var.user_name}AccessTo${var.bucket_name}"
actions = ["s3:*"]
resources = ["arn:aws:s3:::${var.bucket_name}/*"]
effect = "Allow"
}
}

Access Denied from S3 Bucket [pendente]

In Account A I created a s3 bucket with cloudformation, and a CodeBuild builds an artifact and uploads to this bucket. In Account B I try to create a stack with cloudformation, and use the artifact from Account A's bucket to deploy my Lambda function. But, I get an Access Denied error. Does anyone know the solution? Thanks...
"TestBucket": {
"Type": "AWS::S3::Bucket",
"DeletionPolicy": "Retain",
"Properties": {
"AccessControl": "BucketOwnerFullControl"
}
},
"IAMPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "TestBucket"
},
"PolicyDocument": {
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::xxxxxxxxxxxx:root",
"arn:aws:iam::xxxxxxxxxxxx:root"
]
},
"Action": [
"s3:GetObject"
],
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "TestBucket"
},
"/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "TestBucket"
}
]
]
}
]
}
]
}
}
}
Assuming that the xxxxx in below statement is the account number of Account B:
"AWS": [
"arn:aws:iam::xxxxxxxxxxxx:root",
"arn:aws:iam::xxxxxxxxxxxx:root"
]
You are saying that this bucket grants the access to Account B on the basis of IAM permissions/policies held by them in Account B IAM service.
So essentially all the users/instance profile/policy that have explicit S3 access will be able to access this bucket of Account A. This means that perhaps the IAM policy that you are attaching to the lambda role in Account B doesn't have explicit S3 access.
I would suggest giving S3 access to your Lambda function and this should work.
Please be aware that in future if you want to write to S3 bucket of Account A from Account B, you would have to make sure that you put the bucket-owner-full-control acl so that the objects are available across all the accounts.
Example:
Using CLI:
$ aws s3api put-object --acl bucket-owner-full-control --bucket my-test-bucket --key dir/my_object.txt --body /path/to/my_object.txt
Instead of "arn:aws:iam::xxxxxxxxxxxx:root" granting access to the root role only, try granting access to all identities in the account by specifying just the account ID as the item within the Principal/AWS object: "xxxxxxxxxxxx".
See Using a Resource-based Policy to Delegate Access to an Amazon S3 Bucket in Another Account for more details.

AWS malformed policy error

I am trying to set an AWS group policy via the AWS CLI like so:
aws iam put-group-policy --group-name my-group --policy-name \
s3-full-access --policy-document /tmp/policy.json
This is the content of /tmp/policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListAllMyBuckets"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::*"
},
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-bucket*"
}
]
}
I keep getting the following error:
A client error (MalformedPolicyDocument) occurred when calling the PutGroupPolicy operation: The policy is not in the valid JSON format.
I do not know how to proceed, the error is too unspecific. Anyone able to help?
Solved this riddle!
There has to be a file:// prefix in front of the policy file name:
aws iam put-group-policy --group-name my-group --policy-name s3-full-access --policy-document file:///tmp/policy.json
The original error message is very misleading, as you get the same message if you provide a filename that does not exist at all.
So it is not the syntax of the policy in the file but the fact that the CLI does not see the file at all, that causes the error.
I was facing the same issue on window 10 and this help me.
**file** : followed by **two Forward slash** like :"file://"
**Path on window 10** : followed by **Backward slash** like
:"c:\Users\Anand\Desktop\anand-jan19.json"
C:\Users\Anand>aws iam create-policy --policy-name anand-jan19 --policy-document file://c:\Users\Anand\Desktop\anand-jan19.json
{
"Policy": {
"PolicyName": "anand-jan19",
"PolicyId": "EQWEQBV33ewrwYCRCS",
"Arn": "arn:aws:iam::56433378:policy/anand-jan19",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2019-02-10T04:03:32Z",
"UpdateDate": "2019-02-10T04:03:32Z"
}
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PS command: Example 1.
aws iam create-role --role-name vmimport --assume-role-policy-document file:///policy/trust-policy.json
****Actual path******: C:\policy\trust-policy.json
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PS command: Example 2.
aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file:///policy/role-policy.json
****Actual path******: C:\policy\role-policy.json
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++