CloudFront as a security boundary

Lesson 2 of 4 in Protecting the Edge.

CloudFront is usually sold as a performance service, and the exam almost never asks about it that way. Treat it as a policy boundary: the one place where TLS terminates, where a web ACL can run, where response headers are stamped, where requests can be required to carry a signature — and, done properly, the only identity your origin will talk to.

That last part is the design the exam keeps drawing. The S3 bucket blocks all public access and has no website endpoint; its bucket policy grants s3:GetObject to the cloudfront.amazonaws.com service principal, with a condition narrowing it to the exact distribution ARN. The distribution uses Origin Access Control, so CloudFront signs every origin request with SigV4 as itself. Nobody who knows the bucket name can read an object. OAC's predecessor, Origin Access Identity (OAI), is legacy: it works only with S3, uses a special CloudFront identity rather than SigV4, and does not cover newer requirements — notably SSE-KMS encrypted objects and the full set of HTTP methods. New designs use OAC; OAI appears in exam questions as the dated option or as the thing you are migrating from.

Signed URLs and signed cookies — same cryptography, different ergonomics
PropertySigned URLSigned cookie

Grants access to

one object per signed URL

many objects matching a path pattern in the policy

Changes the URL

yes — the signature, policy and expiry are query parameters

no — URLs stay clean; the grant travels in Set-Cookie

Fits

a single download link, an emailed receipt, an installer, a short-lived export

a whole subscriber area, or streaming where one manifest pulls hundreds of segment URLs

Client requirement

none — any HTTP client can use it

the client must store and send cookies

Policy shape

canned (resource + expiry) or custom (adds IP range and start time)

always a custom policy — that is what makes wildcards possible

Who signs

your application, server-side, with the private key whose public half sits in the trusted key group

identical — the signature is the same; only the carrier differs

Four more distribution-level controls round out the boundary, and each one answers a differently-worded exam requirement.

Geographic restriction is a distribution setting: an allow list or block list of countries, enforced at the edge with a 403. It is blunt and free. A WAF geo match rule is the expressive alternative — it can combine country with URI path, header or rate, so "block this country only on the admin path" is a WAF rule, while "this service is not offered in these countries" is geo restriction.

Field-level encryption protects specific values from your own infrastructure. You upload an RSA public key, name up to 10 form fields, and CloudFront encrypts those fields in HTTPS POST bodies at the edge. Everything downstream — load balancers, application servers, logs — handles ciphertext; only the component holding the private key can read a credit-card number. The requirement phrasing to watch for is "sensitive fields must not be readable by the application tier".

Custom origin headers are how a non-S3 origin verifies that a request came through your distribution: CloudFront adds a header with a long random secret on every origin request, and a WAF rule on the ALB blocks anything without it. Rotate it like a credential, and pair it with a security group limited to the com.amazonaws.global.cloudfront.origin-facing managed prefix list.

S3 CORS is the one that bites in practice. A browser calling a different origin sends Origin and expects Access-Control-Allow-Origin back. The bucket's CORS configuration produces that header — but CloudFront will not forward Origin to the origin or vary its cache on it unless your cache policy or origin request policy includes it, so the first cached response wins for every subsequent origin. Symptom: CORS works for one site and fails for the next, apparently at random.

What the managed security-headers policy actually sets

CloudFront ships managed response headers policies, including a security-headers policy that sets Strict-Transport-Security, X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN, Referrer-Policy and a baseline Content-Security-Policy. You can attach a managed policy as-is, or create a custom one to tune CSP for your application — CSP is the one header that is genuinely application-specific. Response headers policies can also carry CORS configuration and custom headers, and can remove headers (hello, Server) on the way out.

Geo restriction or a WAF geo match rule?

Geo restriction is a property of the distribution: simple, free, all-or-nothing per country, returns 403. A WAF geo match statement is a rule condition, so it composes — geo match (XX) AND uri_path starts_with /admin, or geo match as a scope-down statement on a rate-based rule. Choose geo restriction for licensing and sanctions ("not offered in this country"); choose WAF when the restriction is conditional, or when you want it counted and logged alongside your other rules.

Field-level encryption, precisely

Applies to HTTPS POST request bodies with content type application/x-www-form-urlencoded, encrypts up to 10 named fields per request with an RSA public key you upload, and leaves the rest of the request untouched. It is an in-transit-through-your-own-stack control: the point is that components without the private key — including your web tier and your logs — never see plaintext. It does not encrypt responses, and it is not a substitute for TLS or for encryption at rest.

Why streaming almost always means signed cookies

An HLS or DASH session fetches a manifest and then hundreds of segment files. Signing each segment URL individually is possible and miserable; one signed cookie with a wildcard resource path covers the whole session and leaves the player’s URLs untouched. The flip side: cookies are scoped to a domain, so a signed-cookie design wants the content on a domain you control.

OAC also covers more than S3

Origin Access Control supports S3 origins, Lambda function URLs, MediaStore and MediaPackage v2 origins, signing each origin request with SigV4. OAI only ever supported S3. If a question mentions a private Lambda function URL fronted by CloudFront, OAC is the only one of the two that can do it.

Key terms: Origin Access Control (OAC), CloudFront signed URL, CloudFront signed cookie, Response headers policy, Custom origin header (origin verification), S3 CORS configuration

Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.