Suppose you have some assets for your platform which is being served to your customers in form of MP4 videos, PDFs, Etc.
I am assuming that data is important but not that sensitive, so this guide can be applicable for some specific use cases.
For ease of storing and to save some $$$
, you chose to host your content on an AWS S3 bucket. That way you will also be utilizing AWS Global Infrastructure to make sure your assets are highly available.
Let's See, How You created Your Bucket -
Enter a suitable name for your bucket :
Select an Encryption Method (To enable Encryption at Rest) :
and leave everything as it is. Now proceed to create your new shiny bucket.
Create a folder for storing your assets, for example - course-videos
+ maintain the encryption scheme.
Upload the content, for now, I am uploading two videos, see below :
Now, If you try to open your video in the browser using that S3 object URL, you'll see something like this:
and, that is totally fine, by default, your bucket is private and objects can not be accessed directly.
So now what? Ok, let's try to make the objects public and see what happens π€
Note - Click the image to enlarge
So If you were unable to understand, let me help you... Did you observe a checklist (aka Block public access (bucket settings)) while creating the bucket?
Which look something like this :
So the thing is this checklist makes sure that all public access to the bucket and its objects is denied!
But for our use case, we need our assets to be public so our users can consume them.
So let's make our objects public now... For that go to your BUCKET > Permissions > Block public access (bucket settings)
Here, uncheck all the settings as I have shown in the image above.
Now, try again to make that folder public for our users.
Woohoo! this time we were able to make our objects public.
I'd recommended you to go through this once to understand better what the Block public access settings offers.
Now let's add these URLs to your platform, I have created a Codepen where I will be referring these videos for demo purposes.
codepen.io/k4kratik/pen/NWvxowL?editors=1000
HTML Source : geeksforgeeks.org/html5-video
When you add the S3 Object URL to your platform, users are able to see the content, Great!
π‘For those who don't know, you can click on any object in S3 and from there you can copy the object URL.
The Problem
Wait what, you thought that was it? π No! Let's see what's the issue here.
Keeping objects as public
does not mean anyone should be able to download these objects so easily! We made those objects public so our users on the Internet can access it for viewing, surely not for downloading! π€
The Workaround
Yup! You read the title right! It is not a solution but a workaround that can be effective for most of the users who can try to download your content! π
So even before we start, I want to summarize what we are gonna do - We will make use of Bucket Policies, We will whitelist your platform's domain name so only your platform's webpages can access your assets.
Step-1: Change Block public access (bucket settings)
Again, Go back to Block public access (bucket settings) and keep the checklist as shown below :
In BUCKET > Permissions > Block public access (bucket settings)
You'll see that UI is little changes with these indications:
Don't worry we will fine-tune the access in a bit, Just stick to the guide!
Validation
Now when I check the webpage (In my case, it is Codepen) The video is not accessible anymore! π₯
Step-2: Add the bucket policy to whitelist our domain
βΉοΈ
As you know from Step-1, our video was unable to play. let's resolve this.
For that go to your BUCKET > Permissions > Bucket policy and paste the below code.
β οΈ Make sure you are replacing kratik-blog-assets with your bucket name.
β οΈ For the value of the Key "aws:Referer", make sure you are adding your domain name(s).
{
"Version": "2012-10-17",
"Id": "http referer policy example",
"Statement": [
{
"Sid": "Allow get requests originating from your domains only.",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::kratik-test/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"https://codepen.io/*",
"https://cdpn.io/*"
]
}
}
}
]
}
It will look something like this:
Validation
Check the Codepen again and observe if something is different now.
Oh, Wow! Our video is able to play on our platform's Webpage.
βΉοΈ
As we created the above Bucket policy, it whitelisted our domain and allowed access.
Step-3: Testing the Download
Let's try again downloading our assets.
π π π₯³
This is what we wanted right? Users can view your content but won't be able to download it.
isn't it cool?
Disclaimer
As I mentioned this is a workaround but not a 100% foolproof solution, technically advanced users can bypass this policy very easily, So if your data is really very very sensitive, my Suggestion is, Don't do this :)
For more sensitive content there are other methods available that require time and knowledge to set up but yeah, they will def fulfill your use case.
For example :
Drop Some Emojis if you find this useful. Or leave a comment.
Thanks for Reading! πββοΈ
Wanna buy me a Coffee β ?