Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hard Coded canned ACL parameter on S3.upload in uploadfs/s3.js copyIn method #55

Open
shaunhurley opened this issue Apr 17, 2020 · 9 comments

Comments

@shaunhurley
Copy link

Hi Team,

Just spent a chunk of time working through an access issue, thought I would share the context. I don't want to have my website assets bucket publicly accessible directly from the bucket. I also don't want Apostrophe linking to images directly via the bucket URL, nor via HTTP (since it causes HTTPS sites to show up as only 'paritally secure' in the browser)

As such my S3 assets bucket has public access turned off, and is being presented through Cloudfront with access restricted via a Cloudfront "Origin Access Identity" to enable public access via HTTPs:// URLs. Apostrophe is configured with an IAM identity (key / secret) to allow uploadfs to process files in and with the options 'https' and 'cdn' parameters in the app.js file apostrophe-attachments/uploadfs module configuration section.

    'apostrophe-attachments': {
      uploadfs: {
        https: true,
        cdn: {
          enabled: true,
          url: 'https://assets.urbanaxes.com'
        },
        backend: 's3',
        secret: '<IAM Secret>',
        key: '<IAM key>',
        bucket: 'assets.urbanaxes.com',
        region: 'us-east-1'
      }
    }

This configuration results in a generic S3 'AccessDenied' error being returned from Apostrophe when trying to upload files through the CMS.

After investigation and verification that the credentials were working, I determined that you cannot apply the 'public-read' canned ACL to an objects in buckets that have all public access restricted.

Uploadfs currently has the 'public-read' ACL hard coded into the client.upload call params in the s3.js copyIn method (circa line 91 or so).

    var params = {
        ACL: 'public-read',
        Key: cleanKey(path),
        Body: inputStream,
        ContentType: contentType
    };

While I haven't exhaustively tested all the available ACL options, changing the ACL to 'private' successfully resolved the issue / prevented the error from recurring.

Longer term, enabling the ACL to be configurable, via the module configuration and possibly via environment variable, would seem like a reasonable approach?

Thanks,

Shaun

@boutell
Copy link
Member

boutell commented Apr 17, 2020 via email

@shaunhurley
Copy link
Author

Not sure I'm understanding you here (or maybe I'm misunderstanding the intent of uploadfs) - the content being uploaded through uploadfs is still publicly accessible, it just has to be accessed through a HTTPS Cloudfront distribution, and not via HTTP / directly from an S3 URL.

These links are all publicly accessible assets (in that there is authentication requirement in front of them) through our Cloudfront distribution:

vs. a direct S3 http link on a public bucket

@boutell
Copy link
Member

boutell commented Apr 17, 2020 via email

@boutell
Copy link
Member

boutell commented Apr 17, 2020 via email

@shaunhurley
Copy link
Author

Yes making it configurable is reasonable. It doesn't need to be publicly readable for cloudfront to pick it up and make it publicly readable?

Nope. Making it private just means that an explicit (internal) authentication is required to retrieve objects from the bucket, not to serve it up in response to a request. Cloudfront receives the original anonymous request(s) from a browser. If the asset is cached, job done. If the result is not already cached, while while retrieving the requested asset from the S3 bucket, it attaches a configured AWS 'Origin Access Identity' to the request. The bucket has a policy statement that explicitly allows the OAI to retrieve objects, per below, allowing the object to be retrieved.

        {
            "Sid": "CloudfrontOAIS3AccessPolicy",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <AAAAAAAAAAAA>"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::assets.urbanaxes.com/*"
        },

@boutell
Copy link
Member

boutell commented Apr 20, 2020

Are you interested in submitting a PR for this one?

@shaunhurley
Copy link
Author

I can take a run at it, however can you point me in the direction of the module that handles parsing environment variables? I was mainly digging directly into uploadfs and hadn't got that far...

@boutell
Copy link
Member

boutell commented Apr 20, 2020 via email

@shaunhurley
Copy link
Author

Are you interested in submitting a PR for this one?

Pull request submitted on uploadfs to address the issue via providing an option, I'll take a look at the environment variable stuff when I get a few minutes spare.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants