It’s been recommended for over 5 years now that S3 buckets be configured using bucket policies rather than per-object ACLs, unless there is a really good reason for the latter.
I’ve got a bucket with CloudFront sat in front of it, so I don’t need my objects to be public. Yes, I can set config.s3Options.params.ACL to 'private', but our various security tooling will still complain that objects could be uploaded to the bucket with a public access ACL set, even if no objects are being.
I tried configuring the bucket with object ownership as “bucket owner enforced”, which disables the use of ACLs entirely, but that gives an error from Strapi when trying to upload a new image (The bucket does not allow ACLs).
From what I can see in the codebase, and the use of lodash/fp getOr, if I explicitly set config.s3Options.params.ACL to undefined it’ll fall back to public-read, because lodash is checking if the value is defined rather than if the key is.
So how do I tell the plugin to not try and set an ACL at all, because I’m overriding it with a bucket policy?
OK, I’m not sure whether it’s the AWS API or the JavaScript SDK, but it seems if you set ACL: 'private', which the API docs list as the default, then it works. Either the SDK knows it’s the default and doesn’t set the header, or the API knows it’s the default so ignores the header when it has that value.
Hi @DanM , I have been trying for a week to achieve exactly what you are doing here, but with no luck so far. I keep running into this:
error: The request signature we calculated does not match the signature you provided. Check your key and signing method.
I have restricted the s3 bucket to only allow access from the cloudfront. And also created an IAM account that has permissions to access the s3 bucket.
Also tried following this post but getting the same error.
How are you defining permissions for Strapi to access the bucket? I’m running it from an EKS pod where the IAM role it’s running as has permissions to access the bucket, so my config in Strapi doesn’t contain an access or secret key. Could be you’ve got a typo or space or similar in one of those. Other than that, I’ve seen that error before (but not with Strapi, completely unrelated to anything I was doing here) when object names contain UTF8 characters outside of the regular ASCII set and the library I was using wasn’t encoding them correctly.
I’ve not done anything ‘special’, when I actually tried it with config.s3Options.params.ACL = 'private' it Just Worked when the bucket was configured to disallow access from anything apart from CloudFront and the IAM role the pod was running as.
Have you definitely created the IAM account permissions correctly? Have you tested them outside of Strapi? The role will need the relevant s3:XXX IAM permissions but the S3 bucket policy will also need to explicitly grant access to the role.
Hey I realise this is a really late reply. The issue at the time was…
I had an environment variable set to the same name on my machine level from a project many years ago, so even though I had an env file with the correct credentials, the environment variable being read was the machine level one.
You can imagine the facepalm moment I had when I finally tracked down the cause.