0

I have hosted a loopback api on ec-2 server which will download the contents of an s3 bucket folder. When the bucket policy has

    "Principal": {
        "AWS": "*"
     },

The download will work this way, but on changing the principle to

    "Principal": {
      "AWS": "arn:aws:iam::<account-number>:role/<ec2-role>"
     },

the server throws, access denied error with code 403.

My bucket policy is as:

    {
"Version": "2012-10-17",
"Id": "Policy1566920715903",
"Statement": [
    {
        "Sid": "Stmt1566920713528",
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::<account-number>:role/<ec2-role>"
        },
        "Action": "s3:*",
        "Resource": "arn:aws:s3:::<bucket-name>/*"
    }
]
}

The "block all public access" on my bucket is turned off. The ec2 role that I have attached to my instance has full s3 access. The uploader of the bucket object I am trying to access is my account itself. The ACL for bucket owner has all the permissions turned on. The IAM user running the ec2 instance also has s3 full access.

I have read various questions here on stack overflow including : AWS bucket policy- permission denied

AWS S3 Bucket Access from EC2

Grant EC2 instance access to S3 Bucket

also, https://aws.amazon.com/premiumsupport/knowledge-center/s3-troubleshoot-403/

https://aws.amazon.com/blogs/security/iam-policies-and-bucket-policies-and-acls-oh-my-controlling-access-to-s3-resources/

and checked on countless AWS documentation, but nothing seems to work.

Error on the server:

    message: 'Access Denied',
    code: 'AccessDenied',
    region: null,
    time: 2019-08-29T11:14:30.083Z,
    requestId: '98B0580B0D2A00F3',
    extendedRequestId:'s5K0fPsew96Mf8c2d3R8xj0M85ICY/gNL5wu0ZthpTwO1jgLAccfVee/J7QXZDSXXLmXioVNQwE=',
     cfId: undefined,
     statusCode: 403,
     retryable: false,
     retryDelay: 89.70255005732741 }

The code to download from s3 bucket:

    module.exports = function(app) {
    var myParser = require('body-parser');
    app.use(myParser.urlencoded({extended: true}));
    app.post('/downloadZip', function(request, response) {
    const s3Zip = require('s3-zip');
    const AWS = require('aws-sdk');
    const region = 'us-east-1';
    const bucket = '<bucket-name';
    const filename = new Date().toISOString().replace(/:/g,'-').replace(/T|Z/g,'_') + '_recordings_dump.zip';
    const folder =request.body.userId + '/';
    const fileArray = JSON.parse(request.body.files);
    console.log('Request body=', request.body);
    response.set('content-type', 'application/zip');
    response.set('Content-Disposition', 'attachment; filename=' + filename);
    s3Zip.archive({region: region, bucket: bucket, preserveFolderStructure: true, debug: true },folder, fileArray).pipe(response);
     });
     };

I dont want to keep the bucket items have public access.

  • Can you edit your question to show us the code that is downloading from Amazon S3? Is it using an S3 API call, or just a normal curl/wget? This will impact whether S3 is receiving the identity of the requester. – John Rotenstein Aug 29 '19 at 13:27
  • Yes, just edited it! – snehi pachchigar Aug 29 '19 at 13:34
  • Which line is actually calling AWS? I can't see where the code is using the AWS SDK to call S3. It probably isn't passing the user credentials, so S3 cannot identify who is making the request. I suggest using a normal SDK call, rather than trying to construct the request yourself. – John Rotenstein Aug 29 '19 at 13:39
  • Yes, I was using the SDK for a different purpose. The credentials are stored using 'aws-configure' which is working fine. – snehi pachchigar Aug 29 '19 at 13:47

0 Answers0