By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
(For AWS Solutions Architect – Associate & Real-World Deployments)
You’re a cloud engineer at a media company. Your team just launched a video-streaming platform, but users in Europe and Asia complain about slow load times. Worse, your CEO just emailed: "We need to restrict access to premium content—only paying subscribers should see it, and pirates are hotlinking our videos on Reddit."
This is where CloudFront + Signed URLs/Cookies come in:- CloudFront = AWS’s global CDN (Content Delivery Network). It caches your content at 200+ edge locations, slashing latency for users worldwide.- Signed URLs/Cookies = Time-limited, cryptographically signed access tokens. They let you restrict content to specific users (e.g., paying subscribers) without managing IAM roles or VPNs.
Why this matters in production:- Without CloudFront: Your origin server (e.g., S3, EC2, ALB) gets hammered with requests, leading to slow loads, high costs, and potential outages.- Without Signed URLs/Cookies: Your content is either public (anyone can access it) or completely private (no one can access it). There’s no middle ground for "paying users only." - If you ignore this: You’ll either overspend on bandwidth, lose revenue to piracy, or frustrate users with slow loads—all of which kill retention.
Real-world scenario:You inherit a legacy app where videos are stored in S3 and served directly to users. Your tasks: 1. Speed up global delivery (CloudFront).2. Restrict access to paying users (Signed URLs/Cookies).3. Block hotlinking (Origin Access Control + Signed URLs).
.jpg
https://d123.cloudfront.net/video.mp4?Expires=1234567890&Signature=abc123...
aws configure
premium-video.mp4
# Create a private S3 bucket aws s3api create-bucket --bucket my-premium-content-bucket --region us-east-1 # Upload a test file (e.g., a video) aws s3 cp premium-video.mp4 s3://my-premium-content-bucket/
Verify:
aws s3 ls s3://my-premium-content-bucket/
(Should show premium-video.mp4)
# Create a CloudFront distribution config file (cloudfront-config.json) cat > cloudfront-config.json << 'EOF' { "CallerReference": "my-distribution-$(date +%s)", "Origins": { "Quantity": 1, "Items": [ { "Id": "S3-my-premium-content-bucket", "DomainName": "my-premium-content-bucket.s3.amazonaws.com", "S3OriginConfig": { "OriginAccessIdentity": "" }, "OriginAccessControlId": "" } ] }, "DefaultCacheBehavior": { "TargetOriginId": "S3-my-premium-content-bucket", "ViewerProtocolPolicy": "redirect-to-https", "AllowedMethods": { "Quantity": 2, "Items": ["GET", "HEAD"], "CachedMethods": { "Quantity": 2, "Items": ["GET", "HEAD"] } }, "ForwardedValues": { "QueryString": false, "Cookies": { "Forward": "none" } }, "TrustedKeyGroups": { "Enabled": true, "Quantity": 0 } }, "Comment": "Distribution for premium content", "Enabled": true } EOF # Create the distribution aws cloudfront create-distribution --distribution-config file://cloudfront-config.json
Note the Distribution.Id and DomainName (e.g., d123.cloudfront.net).
Distribution.Id
DomainName
d123.cloudfront.net
Create an Origin Access Control (OAC): bash aws cloudfront create-origin-access-control --origin-access-control-config '{ "Name": "my-oac", "OriginAccessControlOriginType": "s3", "SigningBehavior": "always", "SigningProtocol": "sigv4" }' (Note the Id from the output.)
bash aws cloudfront create-origin-access-control --origin-access-control-config '{ "Name": "my-oac", "OriginAccessControlOriginType": "s3", "SigningBehavior": "always", "SigningProtocol": "sigv4" }'
Id
Update the CloudFront distribution to use OAC: ```bash # Get the current distribution config DISTRIBUTION_ID="YOUR_DISTRIBUTION_ID" ETAG=$(aws cloudfront get-distribution-config --id $DISTRIBUTION_ID | jq -r '.ETag')
# Update the config to use OAC aws cloudfront get-distribution-config --id $DISTRIBUTION_ID | \ jq '.DistributionConfig.Origins.Items[0].OriginAccessControlId = "YOUR_OAC_ID"' | \ jq '.DistributionConfig.Origins.Items[0].S3OriginConfig = null' > updated-config.json
# Apply the update aws cloudfront update-distribution --id $DISTRIBUTION_ID --distribution-config file://updated-config.json --if-match $ETAG ```
aws s3api put-bucket-policy --bucket my-premium-content-bucket --policy file://s3-policy.json ```
Verify:- Try accessing the S3 URL directly (https://my-premium-content-bucket.s3.amazonaws.com/premium-video.mp4). It should fail (403 Forbidden).- Try accessing the CloudFront URL (https://d123.cloudfront.net/premium-video.mp4). It should work (200 OK).
https://my-premium-content-bucket.s3.amazonaws.com/premium-video.mp4
https://d123.cloudfront.net/premium-video.mp4
# Generate an RSA key pair (private key) openssl genrsa -out private_key.pem 2048 # Extract the public key openssl rsa -pubout -in private_key.pem -out public_key.pem
Upload the public key to CloudFront:
aws cloudfront create-public-key --public-key-config '{ "CallerReference": "my-key-$(date +%s)", "Name": "my-signing-key", "EncodedKey": "'$(awk '{printf "%s", $0}' public_key.pem | base64 -w 0)'", "Comment": "Key for signed URLs" }'
(Note the Id from the output.)
Create a Trusted Key Group:
aws cloudfront create-key-group --key-group-config '{ "Name": "my-key-group", "Items": ["YOUR_PUBLIC_KEY_ID"] }'
Update the CloudFront distribution to use the key group:
# Get the current distribution config ETAG=$(aws cloudfront get-distribution-config --id $DISTRIBUTION_ID | jq -r '.ETag') # Update the config to use the key group aws cloudfront get-distribution-config --id $DISTRIBUTION_ID | \ jq '.DistributionConfig.DefaultCacheBehavior.TrustedKeyGroups.Items = ["YOUR_KEY_GROUP_ID"]' | \ jq '.DistributionConfig.DefaultCacheBehavior.TrustedKeyGroups.Quantity = 1' > updated-config.json # Apply the update aws cloudfront update-distribution --id $DISTRIBUTION_ID --distribution-config file://updated-config.json --if-match $ETAG
Use the private key to sign a URL. Here’s a Python script:
import rsa import time import base64 import urllib.parse # Load the private key with open("private_key.pem", "rb") as f: private_key = rsa.PrivateKey.load_pkcs1(f.read()) # CloudFront distribution domain distribution_domain = "d123.cloudfront.net" object_path = "/premium-video.mp4" # Policy (expires in 1 hour) expires = int(time.time()) + 3600 policy = f'{{"Statement":[{{"Resource":"https://{distribution_domain}{object_path}","Condition":{{"DateLessThan":{{"AWS:EpochTime":{expires}}}}}}]}}' # Sign the policy signature = rsa.sign(policy.encode(), private_key, "SHA-1") signature_b64 = base64.b64encode(signature).decode() # URL-encode the signature and policy signature_encoded = urllib.parse.quote(signature_b64, safe="") policy_encoded = urllib.parse.quote(policy, safe="") # Generate the signed URL signed_url = f"https://{distribution_domain}{object_path}?Policy={policy_encoded}&Signature={signature_encoded}&Key-Pair-Id=YOUR_PUBLIC_KEY_ID" print("Signed URL:", signed_url)
Test the signed URL:- Open it in a browser. It should work (200 OK).- Wait 1 hour. It should expire (403 Forbidden).
ViewerProtocolPolicy: redirect-to-https
PriceClass_100
cf-
cf-premium-videos
Environment=prod
Team=media
Requests
4xxErrorRate
BytesDownloaded
4xxErrorRate > 5%
Requests > 10,000/min
Trap: "Use IAM roles" (wrong—OAC is the correct answer).
"A user needs access to 100 files. Should you use Signed URLs or Signed Cookies?"
Trap: "Signed URLs" (works but is impractical for 100 files).
"How do you block hotlinking?"
Trap: "Use a WAF" (WAF blocks malicious traffic but doesn’t restrict content access).
"What’s the default cache TTL for CloudFront?"
Challenge:Deploy a CloudFront distribution that: 1. Serves a private S3 file (secret-doc.pdf).2. Uses a signed URL that expires in 10 minutes.3. Blocks direct S3 access (OAC).
secret-doc.pdf
Solution:1. Create an S3 bucket + upload secret-doc.pdf.2. Create a CloudFront distribution with OAC.3. Generate a signed URL (use the Python script above, set expires = int(time.time()) + 600).4. Test: - Direct S3 URL → 403. - CloudFront URL → 200. - Signed URL → 200 (expires in 10 mins).
expires = int(time.time()) + 600
Why it works:- OAC blocks direct S3 access.- Signed URL grants time-limited access.
```bash
aws cloudfront create-distribution --distribution-config file://config.json
aws cloudfront update-distribution --id DISTRIBUTION_ID --distribution-config file://updated-config.json --if-match ETAG
openssl genrsa -out private_key.pem 2048 openssl rsa -pubout -in private_key.pem -out public_key.pem
aws cloudfront create-public-key --public-key-config '{"CallerReference": "ref", "Name": "key", "EncodedKey": "'$(base64 -w 0 public_key.pem)'"}'
aws cloudfront create-key-group --key-group-config '{"Name": "group", "Items
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.