简体   繁体   中英

Role isn't evaluated but S3 bucket policy is

End goal

I'm using cognito identity pools to give users permission to read an S3 bucket. The idea is that each user has a "folder" (prefix) that they can read and they shouldn't be able to read anyone elses folder.

General design

The way I have this plumbed up is:

  • Users sign in via a cognito user pool (this works)
  • They use the cognito identity pool to assume a role (after checking the s3 access logs, I also think this works)
  • They hit the s3 endpoint

Now, the s3 bucket has policy and the role also has policy (which is below). The problem is only the s3 policy is being evaluated.

Details

Role

The role is called "S3Stuff"

Role permissions

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::<bucket>",
            "Condition": {
                "StringLike": {
                    "s3:prefix": "${cognito-identity.amazonaws.com:sub}/*"
                }
            }
        }
    ]
}

Role trust relationship

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "cognito-identity.amazonaws.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "cognito-identity.amazonaws.com:aud": "us-east-1:<GUID>"
                },
                "StringLike": {
                    "cognito-identity.amazonaws.com:amr": "authenticated"
                }
            }
        }
    ]
}

S3 Bucket Policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::720911909616:role/S3Stuff"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::<bucket>"
        }
    ]
}

What happens

With the above S3 configuration, when I log into cognito as a user, I can list the entire contents of the bucket. When I add a condition to the s3 bucket policy (like below) it works correctly (ie I can list the part of the bucket I should be able to and can't access what I couldn't be able to). Also before I put the s3 policy on it was denying me access.

Condition

"Condition": {
    "StringLike": {
        "s3:prefix": "${cognito-identity.amazonaws.com:sub}/*"
    }
}

To be clear I know I can just throw everything into the s3 policy but I want to know what's going on and why.

Why is the policy in the role being bypassed

This picture is key. I got it from "Deep Dive with Security: AWS Identity and Access Management" on the AWS Learning thing.

这显示了评估顺序策略。首先是 AWS Organization,然后是 Resource based,然后是 Permission Boundaries,然后是 Session Policy,最后是 Identity-based。基于资源的政策可以立即批准

I was mislead into thinking that the policy that applies to a request is the "least-privilege union" of all the policies. This is very close to being right but it is untrue .

  1. All policies are parsed.
  2. If there is an explicit deny ("Effect": "Deny") then the whole thing is denied.
  3. If there isn't an explicit deny then it starts looking for implicit denies (this is when the policy doesn't have an "Effect": "Allow" clause that lets me do a thing). EXCEPT the resource based policies let you short circuit the search for implicit denies. If a resource explicitly allows you then you skip: permission boundaries, session policy, and identity policy (which includes roles and IAM).

If you have a resource based policy that approves an action the role policies will only have an effect if there is an explicit deny.

Concerning the part where I said that before I put the S3 policy on I was being denied access, It's probably because of the cognito aud. I was using the wrong aud for a while (the cognito aud being refereed to comes from cognito-identity pools not cognito user pools just in case anyone was curious) and eventually figured it out and used the right one. I must have started testing s3 policy before changing the aud to the right thing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM