SOA-C02Chapter 70 of 104Objective 5.1

CloudFront Origin Access Control (OAC)

This chapter covers CloudFront Origin Access Control (OAC), the modern, more secure method for restricting access to S3 bucket origins in Amazon CloudFront. OAC replaces the older Origin Access Identity (OAI) and is a critical topic for the SOA-C02 exam, particularly under Domain 5: Networking and Content Delivery, Objective 5.1: Implement and manage content delivery using CloudFront. Approximately 10-15% of exam questions touch on CloudFront security features, with OAC being a key differentiator. Understanding OAC's mechanism, configuration, and advantages over OAI is essential for both the exam and real-world deployments.

25 min read
Intermediate
Updated May 31, 2026

CloudFront OAC as a VIP Pass System

Imagine a secure office building with a front desk (CloudFront) and a restricted floor (S3 bucket). Employees (users) enter the building via the front desk, which checks their ID (origin request). Previously, the desk used a simple 'origin access identity' (OAI) badge that allowed anyone with that badge to access the floor, but the badge never changed—if stolen, it could be reused. Now, the building upgrades to 'origin access control' (OAC). Each time an employee enters, the front desk generates a unique, time-limited digital pass (signed request) that includes a signature (AWS Signature Version 4) and a timestamp. The pass is valid only for a few minutes (e.g., 5 minutes) and contains the specific employee's credentials (hash of the request). The restricted floor's door (S3 bucket policy) verifies the pass by checking the signature, timestamp, and that it came from the front desk (aws:SourceArn). If the pass is expired or the signature doesn't match, the door stays locked. This prevents replay attacks: even if an attacker intercepts a pass, they cannot reuse it because it expires quickly and is tied to the original request. The front desk also logs every pass issued (CloudFront logs) for auditing. This mechanism mirrors how AWS Signature Version 4 with signed requests provides temporary, verifiable access from CloudFront to S3, replacing the static OAI with a dynamic, secure handshake.

How It Actually Works

What is CloudFront Origin Access Control (OAC)?

CloudFront Origin Access Control (OAC) is a feature that allows you to restrict access to an S3 bucket origin so that only your CloudFront distribution can serve content from that bucket. It uses AWS Signature Version 4 (SigV4) to sign requests from CloudFront to the origin, providing a more secure and flexible alternative to the legacy Origin Access Identity (OAI). OAC supports encrypted origins (S3 SSE-KMS), which OAI does not, and eliminates the need for a static user (the OAI) by dynamically signing each request.

Why OAC Exists: The Security Gap with OAI

OAI worked by creating a special CloudFront user (the origin access identity) and granting that user access to the S3 bucket via a bucket policy. However, OAI had several limitations:

It could not be used with S3 buckets that require Server-Side Encryption with AWS KMS (SSE-KMS).

The OAI was a static identity; if the OAI ID was compromised, an attacker could access the bucket directly (though bucket policies typically restrict to CloudFront only).

OAI did not support signed requests, making it vulnerable to replay attacks if the OAI credentials were leaked.

OAI was limited to S3 origins only; OAC can be extended to other origins in the future.

OAC addresses these issues by using SigV4 to sign each request with a unique signature that includes a timestamp and a hash of the request. The S3 bucket policy then verifies that the request is signed and originates from the CloudFront distribution.

How OAC Works Internally: The Request Flow

1. User Request: A user requests content from CloudFront (e.g., https://d123.cloudfront.net/image.jpg). 2. Cache Check: CloudFront checks its edge cache. If the object is cached and fresh, it serves it directly. If not, it proceeds to the origin. 3. Origin Request Signing: CloudFront constructs an HTTP GET request to the S3 origin (e.g., https://my-bucket.s3.amazonaws.com/image.jpg). It then signs this request using AWS Signature Version 4. The signing process involves: - Canonical Request: Build a canonical request using HTTP method, URI, query string, headers (including host and x-amz-content-sha256), and payload hash. - String to Sign: Combine algorithm, request date, credential scope, and hashed canonical request. - Signature: Compute the signature using the distribution's private key (associated with the OAC configuration) and the string to sign. 4. Signed Request to S3: CloudFront sends the signed GET request to S3. The request includes the Authorization header with the signature, as well as x-amz-date and x-amz-content-sha256 headers. 5. S3 Verification: S3 receives the request and verifies the signature using the public key of the CloudFront distribution. It also checks that the aws:SourceArn condition in the bucket policy matches the CloudFront distribution ARN. If both checks pass, S3 returns the object. If not, S3 returns a 403 Forbidden. 6. Response: CloudFront receives the object, caches it at the edge, and serves it to the user.

Key Components and Defaults

- OAC Configuration: Created in CloudFront console or via API. You specify the S3 bucket origin and optionally enable signing behavior (e.g., for all requests or only for specific behaviors). - Bucket Policy: Must include a statement that allows s3:GetObject (and optionally s3:PutObject for PUT requests) with conditions: - aws:SourceArn: Must equal the CloudFront distribution ARN (e.g., arn:aws:cloudfront::123456789012:distribution/E1234567890ABC). - aws:SourceAccount: Must equal the AWS account ID of the distribution owner. - Signature Version 4: The signing algorithm. Default headers signed: host, x-amz-content-sha256, x-amz-date. The signature includes a timestamp that is checked against the current time (with a default skew of 15 minutes). - OAC vs OAI: OAC is the recommended option for new distributions. OAI is still supported but deprecated for new use cases.

Configuration and Verification

To configure OAC for an S3 origin:

1. Create an OAC: In the CloudFront console, under "Origin Access", select "Origin access control settings" and create a new control setting. You can also use the AWS CLI:

aws cloudfront create-origin-access-control \
     --origin-access-control-config OriginAccessControlConfig.json

where OriginAccessControlConfig.json contains:

{
     "Name": "MyOAC",
     "Description": "OAC for my distribution",
     "SigningProtocol": "sigv4",
     "SigningBehavior": "always",
     "OriginAccessControlOriginType": "s3"
   }

2. Associate OAC with Origin: During distribution creation or update, under "Origin settings", choose "Origin access control" and select the OAC. 3. Update S3 Bucket Policy: Add a bucket policy like:

{
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": "*",
         "Action": "s3:GetObject",
         "Resource": "arn:aws:s3:::my-bucket/*",
         "Condition": {
           "StringEquals": {
             "aws:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E1234567890ABC"
           }
         }
       }
     ]
   }
4.

Verify: Use aws cloudfront get-distribution to check the Origins.Items[].OriginAccessControlId field. Also, test by accessing a CloudFront URL for an object that is not cached; if the bucket policy is correct, you should receive the object. If misconfigured, you get a 403 error from S3.

Interaction with Related Technologies

S3 SSE-KMS: OAC supports SSE-KMS encrypted objects. You must grant the CloudFront distribution's service principal (cloudfront.amazonaws.com) permission to use the KMS key via a key policy. OAI does not support this.

Custom Origins: OAC currently only supports S3 origins. For custom origins (e.g., ALB, EC2), you still use custom headers or other methods.

Lambda@Edge: OAC works with Lambda@Edge origin requests. The signed request is generated after the Lambda function executes, so you can modify the request before signing.

CloudFront Functions: OAC works similarly with CloudFront Functions at viewer request/response, but origin request signing occurs after function execution.

WAF: OAC does not affect WAF integration; WAF rules are evaluated before the origin request is signed.

Performance and Cost Considerations

Signing Overhead: OAC adds minimal latency (microseconds) for signing at the edge. No additional cost for OAC itself.

Cache Hit Ratio: OAC does not affect caching behavior. Signed requests are only sent on cache misses.

Logging: CloudFront logs include the signed request information. S3 server access logs show the requests from CloudFront's IP addresses.

Common Configuration Mistakes

Incorrect Bucket Policy: Forgetting the aws:SourceArn condition or using the wrong ARN (e.g., using the OAC ARN instead of the distribution ARN).

KMS Key Policy: When using SSE-KMS, forgetting to add the CloudFront service principal to the KMS key policy. The principal is cloudfront.amazonaws.com with condition aws:SourceArn matching the distribution ARN.

SigningBehavior: Setting SigningBehavior to never disables signing, which defeats OAC. Use always or no-override (for behaviors that inherit from origin).

Multiple Origins: Each S3 origin must have its own OAC or share one if they use the same signing configuration.

Exam-Specific Details

OAC is required for SSE-KMS: This is a key exam point. If a question involves an S3 bucket with SSE-KMS and CloudFront, OAC is the only option (not OAI).

Bucket Policy Condition: The exam tests that you must use aws:SourceArn (not aws:SourceIp or aws:Referer) to restrict access to CloudFront.

OAC vs OAI Comparison: Know that OAC uses SigV4, supports KMS, and is more secure. OAI is legacy and does not support KMS.

SigningBehavior Values: always (sign all requests), never (do not sign), no-override (sign unless overridden by a behavior). The default is always for new OACs.

Distribution ARN: Format: arn:aws:cloudfront::<account-id>:distribution/<distribution-id>. The distribution ID is a 14-character alphanumeric string (e.g., E1234567890ABC).

Walk-Through

1

Create Origin Access Control

In the AWS Management Console, navigate to CloudFront > Origin Access Control > Create control setting. Provide a name (e.g., 'MyOAC'), description (optional), signing protocol (only 'sigv4' is available), signing behavior (choose 'always' to sign all requests, 'never' to disable signing, or 'no-override' to inherit from origin), and origin type ('s3' for S3 buckets). Alternatively, use the AWS CLI with the `create-origin-access-control` command. The OAC is created as a resource in your account and can be reused across multiple distributions. Note that OAC is regional but works globally with CloudFront.

2

Associate OAC with CloudFront Distribution

While creating or updating a CloudFront distribution, under 'Origin settings', select 'Origin access control' as the origin access type. Choose the OAC you created from the dropdown. You can also use the CLI with `update-distribution`. The association creates a link between the distribution and the OAC. The distribution's service principal (cloudfront.amazonaws.com) will use the OAC's signing credentials to sign requests. You can associate the same OAC with multiple origins (e.g., multiple S3 buckets) if they share the same signing behavior.

3

Update S3 Bucket Policy

Modify the S3 bucket policy to allow CloudFront to access objects. The policy must grant `s3:GetObject` (and optionally `s3:PutObject` for PUT) to the principal `*` with a condition that restricts access to the CloudFront distribution ARN. The condition uses `aws:SourceArn` set to the distribution ARN (e.g., `arn:aws:cloudfront::123456789012:distribution/E1234567890ABC`). You may also include `aws:SourceAccount` for additional security. Without this policy, requests from CloudFront will be denied by S3, resulting in 403 errors. The policy does not need to specify the OAC; it only needs to trust the distribution.

4

Verify Bucket Policy (Optional KMS)

If the S3 bucket uses SSE-KMS, you must also update the KMS key policy to allow the CloudFront service principal to decrypt objects. Add a statement with `Effect: Allow`, `Principal: cloudfront.amazonaws.com`, and `Action: kms:Decrypt`. Use a condition `aws:SourceArn` matching the distribution ARN. Without this, CloudFront will fail to decrypt the object and return a 502 error. This step is not required for SSE-S3 or SSE-C.

5

Test and Monitor

After configuration, test by accessing a CloudFront URL for an object that is not cached. Use `curl -I https://d123.cloudfront.net/image.jpg` and check for HTTP 200 or 403. If 403, check CloudFront error logs and S3 access logs. Verify that the request includes the `Authorization` header (signed). Monitor CloudFront metrics for origin errors. Also, ensure that direct S3 access (without CloudFront) is denied by the bucket policy (since the condition requires the CloudFront ARN). If you need to allow direct access for other purposes, add separate allow statements.

What This Looks Like on the Job

Enterprise Scenario 1: Secure Media Streaming

A large media company uses CloudFront to stream video content stored in an S3 bucket encrypted with SSE-KMS. They previously used OAI but needed to upgrade to OAC to support KMS encryption. The bucket policy was updated to include the aws:SourceArn condition pointing to the CloudFront distribution ARN. The KMS key policy was also updated to allow cloudfront.amazonaws.com to decrypt. They set SigningBehavior to always to ensure all origin requests are signed. Performance was negligible; the signing overhead was less than 1 ms per request. They observed that cache hit rates remained above 90%. One misconfiguration occurred when the KMS key policy was accidentally removed during a rotation, causing 502 errors for all requests. The fix was to re-add the CloudFront service principal with the correct condition.

Enterprise Scenario 2: Multi-Bucket E-Commerce Platform

An e-commerce platform uses multiple S3 buckets for different content types (images, CSS, JavaScript) behind a single CloudFront distribution. Each bucket is a separate origin. They created a single OAC and associated it with all origins. The bucket policies for each bucket were identical except for the bucket ARN in the resource. They set SigningBehavior to no-override so that individual behaviors could override signing if needed (e.g., for public content). However, they later realized that no-override still signs by default unless a behavior explicitly sets SigningBehavior to never. This was fine for their use case. A common mistake was forgetting to update the bucket policy for a new bucket, causing intermittent 403 errors. They automated policy updates using AWS CloudFormation.

Enterprise Scenario 3: Hybrid Cloud with Lambda@Edge

A SaaS company uses Lambda@Edge to modify origin requests (e.g., add authentication headers). They use OAC to secure the S3 origin. The Lambda function runs before the request is signed; CloudFront signs the request after the function executes. This allowed them to use OAC without modifying the Lambda code. They encountered an issue where the Lambda function changed the URI, causing the signed request to mismatch the actual request (since the signature was computed on the original URI). They fixed this by ensuring the Lambda function did not modify the URI path. They also used CloudFront logs to debug signature mismatch errors.

What Goes Wrong When Misconfigured

403 Forbidden from S3: Usually due to missing or incorrect bucket policy condition (e.g., wrong distribution ARN).

502 Bad Gateway from CloudFront: Often caused by KMS key policy missing or incorrect, or S3 bucket policy not allowing CloudFront.

Signature Mismatch: If the request is modified after signing (e.g., by Lambda@Edge), S3 rejects it. Ensure signing happens after all modifications.

Expired Signature: If the edge location's clock is skewed, signatures may be rejected. CloudFront uses NTP, but rare issues can occur.

OAC Not Associated: If the OAC is not associated with the origin, CloudFront will not sign requests, and S3 will deny access (unless bucket policy allows anonymous access).

How SOA-C02 Actually Tests This

What SOA-C02 Tests on OAC

- Objective 5.1: Implement and manage content delivery using CloudFront. Subtopics include securing origin access using OAC vs OAI. - Key Exam Points: 1. OAC supports SSE-KMS; OAI does not. This is the most tested differentiator. 2. OAC uses AWS Signature Version 4; OAI uses a static identity. 3. The bucket policy must use aws:SourceArn condition with the distribution ARN. 4. OAC is the recommended option for new distributions. 5. SigningBehavior values: always, never, no-override.

Common Wrong Answers and Why

1.

"Use OAI with SSE-KMS": Wrong because OAI does not support KMS encryption. Candidates confuse OAI's ability to work with SSE-S3 with SSE-KMS.

2.

"Set bucket policy to allow CloudFront's IP ranges": Wrong because CloudFront IPs are shared and change over time. The correct method is to use aws:SourceArn condition.

3.

"Use custom headers for origin access": While custom headers can restrict access, OAC is the native method for S3. Custom headers are for custom origins.

4.

"OAC requires a separate IAM role": Wrong. OAC uses the CloudFront service principal, not an IAM role.

Specific Numbers and Terms on the Exam

Signature Version 4: The signing protocol. Expect the term 'SigV4'.

Distribution ARN format: arn:aws:cloudfront::<account-id>:distribution/<distribution-id>.

Default signing behavior: always when creating a new OAC.

KMS key policy: Must include cloudfront.amazonaws.com as principal.

Error codes: 403 (Forbidden) from S3, 502 (Bad Gateway) from CloudFront for KMS issues.

Edge Cases and Exceptions

Multiple AWS accounts: If the S3 bucket is in a different account, the bucket policy must still allow the CloudFront distribution's account (via aws:SourceAccount). The OAC is in the same account as the distribution.

OAC with custom origins: Not supported. The exam may ask which origin types support OAC (only S3).

OAC with CloudFront Functions: Functions run before signing; they can modify headers, but the signature is computed on the final request.

OAC with signed URLs: OAC applies to origin requests, not viewer requests. Viewer signed URLs (using CloudFront key pairs) are separate.

How to Eliminate Wrong Answers

If the question involves KMS encryption, eliminate any answer that uses OAI.

If the answer suggests using IP-based restrictions, eliminate it.

If the answer mentions IAM roles for CloudFront, eliminate it (CloudFront uses service principals).

If the answer suggests using OAC for a custom origin (ALB, EC2), eliminate it.

Key Takeaways

OAC uses AWS Signature Version 4 to sign origin requests, providing replay protection and support for SSE-KMS.

OAC is required when using an S3 origin with SSE-KMS encryption; OAI cannot be used.

The S3 bucket policy must include a condition `aws:SourceArn` equal to the CloudFront distribution ARN.

OAC currently only supports S3 origins, not custom origins like ALB or EC2.

A single OAC can be reused across multiple origins in the same or different distributions.

SigningBehavior can be set to 'always', 'never', or 'no-override'; default is 'always'.

When using SSE-KMS, the KMS key policy must grant `kms:Decrypt` to `cloudfront.amazonaws.com` with the distribution ARN condition.

OAC is the recommended origin access method for new CloudFront distributions.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Origin Access Control (OAC)

Uses AWS Signature Version 4 (SigV4) to sign requests.

Supports S3 buckets with SSE-KMS encryption.

More secure due to signed, time-limited requests.

Recommended for new distributions.

Bucket policy uses `aws:SourceArn` condition.

Origin Access Identity (OAI)

Uses a static CloudFront user (OAI) with long-term credentials.

Does not support SSE-KMS; only works with SSE-S3 or no encryption.

Less secure; static identity can be compromised.

Legacy; still supported but not recommended for new use cases.

Bucket policy uses `CanonicalUser` ID of the OAI.

Watch Out for These

Mistake

OAC and OAI are interchangeable and equally secure.

Correct

OAC is more secure because it uses SigV4 signed requests that are time-limited and request-specific, preventing replay attacks. OAI uses a static identity with no request signing.

Mistake

OAC requires an IAM role for CloudFront to access S3.

Correct

OAC does not use IAM roles. It uses the CloudFront service principal (cloudfront.amazonaws.com) and signs requests with SigV4. The bucket policy grants access based on the distribution ARN.

Mistake

OAC works with any origin type, including Application Load Balancers.

Correct

OAC currently only supports S3 origins. For custom origins like ALB or EC2, you must use other methods such as custom headers or AWS WAF.

Mistake

You must create a separate OAC for each S3 bucket origin.

Correct

A single OAC can be associated with multiple origins (even multiple S3 buckets) if they use the same signing behavior. However, each origin's bucket policy must still allow the distribution ARN.

Mistake

OAC automatically updates the S3 bucket policy.

Correct

OAC does not automatically modify bucket policies. You must manually or via Infrastructure as Code (e.g., CloudFormation) add the appropriate bucket policy statement with the `aws:SourceArn` condition.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

Does CloudFront OAC support SSE-KMS encrypted S3 buckets?

Yes, CloudFront OAC supports S3 buckets with server-side encryption using AWS KMS (SSE-KMS). This is a key advantage over OAI, which does not. To use OAC with SSE-KMS, you must update the KMS key policy to allow the CloudFront service principal (`cloudfront.amazonaws.com`) to perform the `kms:Decrypt` action, with a condition that restricts access to your CloudFront distribution ARN. Without this, CloudFront will return a 502 Bad Gateway error when trying to fetch encrypted objects.

Can I use OAC with a custom origin like an Application Load Balancer?

No, CloudFront OAC currently only supports S3 origins. For custom origins such as Application Load Balancers, EC2 instances, or on-premises servers, you must use other methods to restrict access, such as custom HTTP headers (e.g., X-Origin-Verify), AWS WAF, or security group rules. The exam may test this distinction: OAC is for S3 only; OAI was also S3-only.

What is the difference between OAC and OAI in CloudFront?

OAC (Origin Access Control) is the modern, more secure method that uses AWS Signature Version 4 to sign each request from CloudFront to the S3 origin. It supports SSE-KMS and provides replay protection. OAI (Origin Access Identity) is the legacy method that uses a static CloudFront user identity. OAI does not support SSE-KMS and is less secure. AWS recommends using OAC for all new distributions. The exam often asks which method to use when KMS encryption is involved.

How do I configure the S3 bucket policy for CloudFront OAC?

The bucket policy must allow `s3:GetObject` (and optionally `s3:PutObject`) for the principal `*` with a condition that restricts access to your CloudFront distribution. The condition uses `aws:SourceArn` set to the distribution ARN (e.g., `arn:aws:cloudfront::123456789012:distribution/E1234567890ABC`). You can also include `aws:SourceAccount` for additional security. Example: `{"Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-bucket/*", "Condition": {"StringEquals": {"aws:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E1234567890ABC"}}}`.

What happens if I don't set the bucket policy correctly for OAC?

If the bucket policy is missing or incorrectly configured (e.g., wrong distribution ARN), CloudFront will receive a 403 Forbidden error from S3 when trying to fetch objects. This will cause the user to see an error page or a blank response. CloudFront will still attempt to serve cached objects, but any cache miss will fail. You can verify the issue by checking CloudFront error logs or S3 access logs.

Can I use the same OAC for multiple CloudFront distributions?

Yes, a single OAC can be associated with multiple CloudFront distributions. However, each distribution's bucket policy must explicitly allow the respective distribution ARN. You cannot use a single OAC to grant access to all distributions; the bucket policy must list each distribution ARN separately or use a wildcard (not recommended).

Does OAC work with CloudFront Functions and Lambda@Edge?

Yes, OAC works with both CloudFront Functions and Lambda@Edge. CloudFront Functions run at viewer request/response and do not affect origin requests. Lambda@Edge can modify origin requests, but the signing occurs after the Lambda function executes. Therefore, if the Lambda function changes the request path or headers, the signature will be computed on the modified request. Ensure that the Lambda function does not alter the request in a way that causes a signature mismatch.

Terms Worth Knowing

Ready to put this to the test?

You've just covered CloudFront Origin Access Control (OAC) — now see how well it sticks with free SOA-C02 practice questions. Full explanations included, no account needed.

Done with this chapter?