Skip to content

Instantly share code, notes, and snippets.

@cheeyeo
Last active October 19, 2025 11:58
Show Gist options
  • Select an option

  • Save cheeyeo/3b1c08cb288e2ffc8ab246257e13cd8d to your computer and use it in GitHub Desktop.

Select an option

Save cheeyeo/3b1c08cb288e2ffc8ab246257e13cd8d to your computer and use it in GitHub Desktop.
Example of using boto3 CloudFrontSigner
import datetime
import json
import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from botocore.signers import CloudFrontSigner
def rsa_signer(message: bytes) -> bytes:
with open('private_key.pem', 'rb') as f:
private_key = serialization.load_pem_private_key(f.read(), password=None, backend=default_backend())
return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())
def cookie_policy(resource: str, expires_in: int) -> str:
"""Signed cookies require a cookie policy attached"""
return json.dumps({"Statement": [{"Resource": resource, "Condition": {"DateLessThan": {"AWS:EpochTime": expires_in}}}]}, separators=(",", ":"))
def replace_chars(orig: str) -> str:
return orig.replace("+", "-").replace("=", "_").replace("/", "~")
def cloudfront_signed_url(key_id: str, url: str, expires_in: int = 3600) -> str:
expire_date = datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(seconds=expires_in)
cloudfront_signer = CloudFrontSigner(key_id, rsa_signer)
return cloudfront_signer.generate_presigned_url(url, date_less_than=expire_date)
def cloudfront_signed_cookies(key_id: str, url: str, expires_in: int = 3600) -> dict[str, str]:
expiration = (datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(seconds=expires_in)).timestamp()
policy = cookie_policy(resource=url, expires_in=int(expiration))
signature = rsa_signer(policy.encode("utf-8"))
return {
"CloudFront-Policy": replace_chars(str(base64.b64encode(policy.encode("utf-8")), "utf-8")),
"CloudFront-Signature": replace_chars(str(base64.b64encode(signature), "utf-8")),
"CloudFront-Key-Pair-Id": key_id
}
if __name__ == "__main__":
# Public key ID uploaded to Cloudfront > Public Key
key_id = 'XXXXXXXX'
url = 'https://YYYY.cloudfront.net/cat.jpeg'
signed_url = cloudfront_signed_url(key_id=key_id, url=url)
print(signed_url)
# For signed cookies, we can specify either specific file or * for all files. Note that the url must match else we get access denied error
url = 'https://YYYY.cloudfront.net/*'
signed_cookies = cloudfront_signed_cookies(key_id, url)
# print(signed_cookies)
output = f"Cookie: CloudFront-Policy={signed_cookies["CloudFront-Policy"]};CloudFront-Signature={signed_cookies["CloudFront-Signature"]};CloudFront-Key-Pair-Id={signed_cookies["CloudFront-Key-Pair-Id"]}"
print(output)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment