I will attempt to answer this question with the hope of helping others who come across the same concern. Also with the hope of someone pointing out what I am missing (if any) or improvements along the way.
The first thing you will need is to create a key pair at https://portal.aws.amazon.com/gp/aws/securityCredentials (Key Pairs tab
). Which will provide you with a key pair id
and a pem file
(save the pem file in your project dir).
In your AWS Cloudfront portal, create a distribution. Select yes
for Restrict Bucket Access
.
Click yes
for Grant Read Permissions on Bucket
. This will add a bucket policy allowing your Cloudfront distribution to read files on your S3 bucket.
Create the distribution.
In your S3 bucket, have a file that is not public. i.e. no read permissions. In this case, we will test this against test.png
.
url = "https://actual_cdn_id_here.cloudfront.net/test.png"
key_pair_id = 'your_aws_key_pair_id'
expires_in = 1.minute
expires = (Time.now.getutc + expires_in).to_i.to_s
private_key = OpenSSL::PKey::RSA.new(File.read('private_key_file.pem'))
policy = %Q[{"Statement":[{"Resource":"#{url}","Condition":{"DateLessThan":{"AWS:EpochTime":#{expires}}}}]}]
signature = Base64.strict_encode64(private_key.sign(OpenSSL::Digest::SHA1.new, policy))
"#{url}?Expires=#{expires}&Signature=#{signature}&Key-Pair-Id=#{key_pair_id}"
Hope this helps someone. If there is a need for improvement / suggestions for this solution, do mention.