AWS CloudFront
secure streaming
Python
cloud computing
video streaming

Getting started with secure AWS CloudFront streaming with Python

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Modern secure CloudFront streaming is usually built around private HTTP delivery, not the old RTMP distribution model. The normal pattern is to store media in an origin such as S3, serve it through a CloudFront distribution, and require signed URLs or signed cookies so only authorized viewers can fetch the content. In Python, the practical starting point is generating signed URLs with CloudFrontSigner.

The Basic Secure Streaming Architecture

A simple private-streaming setup looks like this:

  • media files are stored in S3 or another origin
  • CloudFront serves them over HTTPS
  • the relevant cache behavior requires signed URLs or signed cookies
  • your Python application generates short-lived access tokens for viewers

For video delivery, this is commonly paired with HLS manifests and segment files rather than legacy RTMP streaming.

Configure CloudFront For Private Content

Before Python signs anything, CloudFront must trust a signer.

At a high level, that means:

  • create a public key in CloudFront
  • add it to a key group
  • configure the distribution behavior to trust that key group for private content

Once the behavior requires signed URLs or cookies, CloudFront rejects unsigned requests for that path pattern.

Generate A Signed URL In Python

The AWS SDK stack exposes CloudFrontSigner through botocore.signers. A minimal example looks like this:

python
1import datetime
2from botocore.signers import CloudFrontSigner
3from cryptography.hazmat.backends import default_backend
4from cryptography.hazmat.primitives import hashes, serialization
5from cryptography.hazmat.primitives.asymmetric import padding
6
7
8def rsa_signer(message):
9    with open("private_key.pem", "rb") as key_file:
10        private_key = serialization.load_pem_private_key(
11            key_file.read(),
12            password=None,
13            backend=default_backend(),
14        )
15    return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())
16
17
18key_id = "K123EXAMPLEKEYID"
19url = "https://d111111abcdef8.cloudfront.net/video/master.m3u8"
20expire_at = datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
21
22signer = CloudFrontSigner(key_id, rsa_signer)
23signed_url = signer.generate_presigned_url(url, date_less_than=expire_at)
24
25print(signed_url)

That signed URL can then be returned to the authorized client.

Signed URLs Versus Signed Cookies

Signed URLs are easiest when the client needs access to one object or a small set of objects.

Signed cookies are often better when the player needs access to many related files under the same path, such as:

  • HLS manifest
  • segment files
  • subtitle files

If you sign only the manifest URL but the segment paths are also private, playback can still fail because the player needs access to every downstream request.

Keep The Policy Short And Narrow

A signed URL is more secure when it is limited in both scope and lifetime.

Good defaults include:

  • short expiration windows
  • path patterns restricted to the intended content
  • HTTPS-only delivery
  • key rotation and controlled private-key access

If you sign very broad paths for long durations, you weaken the practical value of the protection.

RTMP Is Not The Modern Starting Point

Older CloudFront documentation included RTMP streaming distributions, but that path is deprecated. If you are starting now, use standard HTTPS delivery with signed URLs or cookies and let a browser or media player consume HLS or similar media formats.

That matches the current operational direction of CloudFront private content delivery.

Common Pitfalls

The most common mistake is configuring signed URLs in Python before configuring CloudFront to trust a signer. If the distribution behavior is not set up correctly, the signatures are useless.

Another issue is signing only the top-level media URL when the player also needs access to child objects such as HLS segments.

It is also easy to leave URLs valid for too long. Short-lived links are usually the safer default.

Finally, protect the private key carefully. If the signing key is leaked, anyone with that key can mint valid access URLs.

Summary

  • Secure CloudFront streaming today usually means private HTTPS delivery with signed URLs or signed cookies.
  • Configure a trusted signer in CloudFront before generating URLs in Python.
  • Use CloudFrontSigner to create short-lived signed URLs.
  • Prefer signed cookies when a player must fetch many related media files.
  • Treat the private signing key as a sensitive secret and keep access tightly controlled.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.