Skip to content

Instantly share code, notes, and snippets.

@uhop
Created April 20, 2020 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save uhop/d196567de25cd50f5408286981464ed5 to your computer and use it in GitHub Desktop.
Save uhop/d196567de25cd50f5408286981464ed5 to your computer and use it in GitHub Desktop.
Access to S3 bucket by roles

What

We need to setup an S3 bucket so we can use AWS JS SDK to upload files from a web application only for logged in users.

We already have a Cognito user pool, e.g., self-managed, and/or tied to a corporate SSO or social networks. Users may have different permissions depending on custom groups they are on. There is an app client, which is used to authenticate users in our web app.

How

Identity Pool

Create an identity pool in Cognito. Its "authentication provider" should be "Cognito" with the user pool (Pool ID) we already have using the same "App client id" as the one we use to authenticate our users the web application.

"Authentication role selection": "Chose role from token" and "Role resolution" is "DENY".

Roles

We need to create roles with necessary S3 (and possibly other) permissions and assign them to groups. Those roles should have trust relationships described in role-trust.json. The important part is that it should accept the created identity pool (ARN) as "aud".

S3 bucket

In "Permissions":

  • "Block public access" ⇒ all off.
  • "CORS configuration" ⇒ like in S3-cors.xml, just update origins and maybe a list of methods. A list of headers is up to you.
  • "Bucket Policy" (sic!) ⇒ like in S3-bucket-policy.json. It may have different permissions for different roles and unathenticated users. The important part is to use roles (ARNs) we created above as principals.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
},
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": [
"us-east-1_USERPOOL-ID",
"us-east-1:IDENTITY-POOL-UUID"
]
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Public",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::MyBucket/*",
"arn:aws:s3:::MyBucket"
]
},
{
"Sid": "WriterRole",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789012:role/Role1",
"arn:aws:iam::123456789012:role/Role2"
]
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::MyBucket/*",
"arn:aws:s3:::MyBucket"
]
}
]
}
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://127.0.0.1:8080</AllowedOrigin>
<AllowedOrigin>http://localhost:8080</AllowedOrigin>
<AllowedOrigin>https://domain.com</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment