When it comes to serving data from S3 buckets using CloudFront, there are numerous tutorials available. However, security is a crucial aspect that needs to be taken care of. There are two ways to achieve this.
- Public Access
- Private Access
Creating a public bucket and mapping it with CloudFront is all that is required for this approach.
If you want to protect your data, you have several options to choose from. Let’s take a look at the restrictions at each component level.
A. S3 level: Creating a bucket with no public access is the first step.
B. CloudFront level: There are a few solutions to achieve private access:
- Create a bucket with no public access
- Create a CloudFront distribution with Origin Access Control (OAC). This will generate a policy, which you can copy and paste into the S3 bucket policy. It means that you are granting permission to CloudFront to access the S3 bucket.
- CloudFront will provide a URL (with or without CNAME) to the S3 content you are serving.
1. If you apply access restrictions, CloudFront will expect a signed URL/signed cookie for each request, or it will deny the request.
2. steps for Signed URL– Generate a public-private key pair on your local machine.
– Create an origin access group at CloudFront and upload public keys.
– Attach that group to the distribution so that it can decrypt the request and check the parameter (which we will send after signing).
– For each signed URL, you can generate a URL of your content and sign the parameters and append them to the URL. CloudFront will decrypt and validate them as the request expires.
– There are libraries available to create signed URLs for a normal URL. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreateURL_PHP.html
At the application level, you need to do much so that each request is signed or you can use signed cookies as well.
More about signed URL
- create CloudFront settings for signed URL : https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html
- Pre-signed URL : https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html
2. Alternatively, you can invoke Lambda on each request, write your custom logic for authenticating the request, and process or deny it.
3. Or, you can simply apply WAF and set a rule to check custom headers, which can be manipulated but can be set up at the server level. For example, a referrer check or any custom header.
using WAF, It is the simplest and easiest way for a NOT A full proof but better than nothing solution.