Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Amazon S3 bucket policy for uploading and viewing pictures

I have an app that users log in with facebook and then can upload images to s3 bucket and view them. I used Cognito service to allow every logged in user to upload and view all files.

I have no idea how to set the correct permissions on the s3 bucket. This is my attempt at it, but I get can't save the policy and get Statement is missing required element - Statement "NO_ID-0" is missing "Principal" element

{
    "Version": "2012-10-17",
    "Id": "Policy1457546546214",
    "Statement": [
        {
            "Sid": "Stmt1475657256771436",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::bucket-name/*"
        },
        {
            "Sid": "Stmt16577654572138125",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": [
                "bucket-name/identity-pool-id*"
            ]
        }
    ]
}

This is the client part, if it helps:

FB.login(function (response) {
    if (response.authResponse) {

      AWS.config.region = 'eu-west-1';
      AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: 'eu-west-1:xxxxxxxxxxx',
        Logins: {
          'graph.facebook.com': response.authResponse.accessToken
        }
      })

      var bucket = new AWS.S3({params: {Bucket: 'name'}})
      var fileChooser = document.getElementById('file-chooser')
      var button = document.getElementById('upload-button')

      button.addEventListener('click', function() {
        var file = fileChooser.files[0]
        var params = {Key: file.name, ContentType: file.type, Body: file}
        bucket.upload(params, function (err, data) {
        ...

Cognito IAM > Roles > Cognito_myappAuth_Role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "cognito-identity:*"
            ],
            "Effect": "Allow",
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::bucket/${cognito-identity.amazonaws.com:sub}/*",
                "arn:aws:s3:::bucket/${cognito-identity.amazonaws.com:sub}"
            ]
        }
    ]
}
like image 313
ilyo Avatar asked Mar 05 '16 20:03

ilyo


People also ask

Can I store images in S3 bucket?

The more efficient and cost-effective option is to use AWS's S3 service for storing the image files. Using S3 is a very low-cost option. Effectively, all you are paying for is transferring files into an S3 bucket and serving those images to your users.

What are bucket policies in the Amazon S3?

A bucket policy is a resource-based policy that you can use to grant access permissions to your bucket and the objects in it. Only the bucket owner can associate a policy with a bucket. The permissions attached to the bucket apply to all of the objects in the bucket that are owned by the bucket owner.

How do I upload pictures to AWS S3?

jpg . Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that you want to upload your folders or files to. Choose Upload.

How many policies can a S3 bucket have?

No, a AWS::S3::BucketPolicy can only have one PolicyDocument .


1 Answers

Have you checked out this blog post? It has a good example of how to set up a role that allows S3 bucket access for users. Cutting out the list bucket part out, the access policy you would link to your identity pool roles might look something like this:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::mybucket/${cognito-identity.amazonaws.com:sub}/*"]
    }
  ]
}

Edit:

Tl;dr from comments for future readers:

  • Apply the policy to the pool's auth role instead of bucket

  • If the app use case requires a common area, use the bucket root directory, otherwise use a directory for each identity defined in the policy (as described in the blog)

  • The role itself doesn't apply until after the authentication occurs. The policy just defines what the credentials given back will have access to do and to what.

like image 165
Jeff Bailey Avatar answered Oct 04 '22 17:10

Jeff Bailey