1

I'd like to implement the following: a specific Cognito (authenticated) user must have access to a single S3 bucket.

What is the best way to achieve the above?

I have tried the following:

  • Create Cognito User Pool with App integration
  • Create Cognito Identity Pool, which creates a dedicated IAM role on autenticated users

My idea was to update the policy of the Identity-Pool-IAM role to impose restrictions on S3 buckets to specific users only. I would of course have to extend this policy every time I add a new Cognito user (no problem with this).

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*",
                "cognito-identity:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::BUCKET_NAME"
            ],
            "Condition": {
                "StringLike": {
                    "cognito-identity.amazonaws.com:sub": "COGNITO_USER_SUB_UID"
                }
            }
        }
    ]
}

AWS doesn't like the way the S3-related policy above is written. It returns:

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.

Question: am I taking the right approach? If so, what am I doing wrong? If not, how should I solve my (supposedly simple) requirement?

For whatever reason, all the examples I have found seem to restrict access to an S3 folder in a bucket rather than the bucket itself (see here or here).

Andrej
  • 121
  • 10
  • @luk2302 I may be completely wrong but this is not an S3 policy but an IAM policy linked to the Cognito role. The first part is the default value; I have added the second one on S3. But it's not working. I wonder if I should change the "Trust policy" instead? – Andrej Aug 27 '22 at 16:04
  • Good point - the second statement has no effect because the PutObject operates on keys within the bucket, not the bucket itself, meaning that the arn should be arn:aws:s3:::BUCKET_NAME/* if anything. But to get back to the original question: apparently there is no condition key for the bucket, but only for the s3:prefix as you already discovered. You might be able to achieve what you want by adding a condition not on the prefix but on the tags of the bucket. (And tagging the buckets properly) – luk2302 Aug 27 '22 at 16:31
  • As a side note, I have checked the option to rely on tags and it appears that - as of today- S3-related IAM policies cannot be applied to buckets but only to objects. See [here](https://stackoverflow.com/a/53912556/5112505). The only alternative I see is to rely on folders. Will give it a try. – Andrej Sep 01 '22 at 09:35

0 Answers0