Securing Amazon Cloudfront stream with signed cookies
In the context of audiobook streaming platform
Search for a command to run...
In the context of audiobook streaming platform
No comments yet. Be the first to comment.
In this series I discuss the issues that I encountered while working on audiobook streaming platform.
Today's post is a continuation of what I wrote yesterday about securing Cloudfront stream with signed cookie. I encourage you to open this post especially to look at the UML diagram. There are some things you need to keep in mind to access a stream ...
If you have been working on a multi-tenant application for a long time, there is a high chance that your Tenant model has grown to an enormous size. You probably started with id, name, and subdomain columns. Later there were things that had to be con...
Today, I came across the following method in my old code. (This comes from an application supporting calculations in the construction of concrete floors). def l_factor ((bending_stiffness * 10000000000) / k) ** 0.25 end This big number looks ...
Last weekend I went to the dynamIT conference that took place in Kraków. In his presentation, Andrzej Krzywda was speaking about DDD as Low-Code. He distilled 11 bounded contexts that are common in the different business applications. One of them is ...
Today's post is a continuation of what I wrote yesterday about securing Cloudfront stream with signed cookie. I encourage you to open this post especially to look at the UML diagram. There are some things you need to keep in mind to access a stream ...
In one of my recent posts I described the challenges I faced while building the audiobook streaming platform. One of them was securing access to the Cloudfront stream.
There are two ways of securing content that CloudFront delivers: signed URLs and signed cookies. In the case of a segmented file, URL signing doesn't seem to be a way to go. We have to take advantage of signed cookies.
The client browser should have a proper cookie already set while requesting .m3u8 playlist file for each streaming session. You can later refresh this cookie asynchronously. A valid cookie must be attached to the request for each .aac segment file.

When you create a signed cookie, you provide a policy statement that specifies the restrictions on the signed cookie:
My implementation uses CookieSigner from the official CloudFront SDK for Ruby. You can get it with aws-sdk-cloudfront gem.
module Panel
class ChaptersController < Panel::PanelController
def progress
chapter = Chapter.find_by(user_id: current_user.id, s3_key: params[:s3_key].split('_converted').first)
chapter.update_columns playback_progress: params[:progress], playback_progress_saved_at: DateTime.now
sign_cookie(chapter.s3_key)
head :no_content
end
private
def sign_cookie(s3_key)
signer = Aws::CloudFront::CookieSigner.new(
key_pair_id: Rails.application.credentials.aws[:cloudfront_private_key_pair_id],
private_key: Rails.application.credentials.aws[:cloudfront_private_key]
)
signer.signed_cookie(
nil,
policy: policy(s3_key, DateTime.now + 1.minute)
).each do |key, value|
cookies[key] = {
value: value,
domain: :all
}
end
end
def policy(s3_key, expiry)
{
"Statement" => [
{
"Resource" => "#{Rails.application.credentials.aws[:cloudfront_url]}/#{s3_key}*",
"Condition" => {
"DateLessThan" => {
"AWS:EpochTime" => expiry.utc.to_i
},
"IpAddress" => {
"AWS:SourceIp" => "#{request.remote_ip}/32"
}
}
}
]
}.to_json
end
end
end