CertNote/ Commute Study Notes
Roadmap
KOEN
CLF-C02 · FoundationalCloud Practitioner - Foundational
DVA-C02 · AssociateDeveloper - Associate
  • Week 1
    • 1.AWS from a Developer's Perspective: Regions, Infrastructure, and the Boundary of Responsibility
    • 2.The 4 Core Entities of IAM: User, Group, Role, Policy
    • 3.STS and Policy Conditions: The Deep World of Temporary Credentials
    • 4.AWS CLI and SDK: From Credential Chaining to SigV4
    • 5.Week 1 Review: The Chain of Trust Built by Infrastructure and IAM
  • Week 2
  • Week 3
  • Week 4
  • Week 5
    • 1.S3: The Philosophy of Object Storage and Designing Storage Classes
    • 2.S3: Versioning, Lifecycle Policies, and the Inner Workings of Replication
    • 3.S3 Security: Bucket Policies, Encryption, and the Layered Structure of Access Control
    • 4.S3 Performance Optimization: Multipart Upload, Transfer Acceleration, Prefix Design
    • 5.S3 Advanced Features + Week 5 Comprehensive Review
  • Week 6
  • Week 7
  • Week 8
  • Week 9
  • Week 10
  • Week 11
  • Week 12
  • Week 13
SAA-C03 · AssociateSolutions Architect - Associate
SOA-C02 · AssociateCloudOps Engineer - Associate
SAP-C02 · ProfessionalSolutions Architect - Professional
DOP-C02 · ProfessionalDevOps Engineer - Professional
Linux Master 2 · 2급KAIT Linux Master - Level 2
SCS-C03 · SpecialtySecurity - Specialty
Linux Master 1 · 1급KAIT Linux Master - Level 1
MLA-C01 · AssociateMachine Learning Engineer - Associate
AIF-C01 · FoundationalAI Practitioner - Foundational
DEA-C01 · AssociateData Engineer - Associate
MLS-C01 · SpecialtyMachine Learning - Specialty
SQLD · 개발자SQL Developer (SQLD)

© CertNote · 주간랩스

  • About
  • Changelog
  • Contact
  • Terms
  • Privacy
← DVA-C02/Week 5/Day 3

Based on the DVA-C02 exam guide·Report an error

DVA-C02· AssociateWeek 5 · Day 3~34 min read

Day 3 - S3 Security: Bucket Policies, Encryption, and the Layered Structure of Access Control

A significant share of AWS security incidents starts with S3. From 2017 to 2022, about 35% of publicly disclosed data breaches were related to misconfigured S3 buckets. Verizon, Twitch, Toyota, GoDaddy — companies you know by name exposed tens of millions of records of personal information through S3 configuration mistakes. This day is about understanding the layered structure of the S3 security model, digging into the technical differences among encryption methods, and pointing out the traps that commonly arise in practice.

The Layered Structure of S3 Access Control — In What Order Is It Evaluated?

A request to S3 is evaluated in the following order. If there is even a single Deny, the final result is denial.

Request arrives
    ↓
① Account-level Block Public Access → if Deny, immediate denial
    ↓
② Bucket-level Block Public Access → if Deny, immediate denial
    ↓
③ Explicit Deny (bucket policy, SCP, IAM policy) → if Deny, immediate denial
    ↓
④ IAM policy Allow + bucket policy Allow → allow
   or when there is only a resource-based policy → allow
    ↓
⑤ ACL (ignored if Bucket Owner Enforced)
    ↓
Default deny

In this structure, the most powerful is Block Public Access. Even if the bucket policy allowed public access with "Principal": "*", public access is blocked if Block Public Access is enabled.

💡 Related theory: S3's policy evaluation logic is based on AWS IAM's general policy evaluation model (explicit Deny > explicit Allow > implicit Deny). S3 adds an additional layer on top of this, called Block Public Access. This layered structure aligns with the Defense in Depth principle of computer security — overlapping multiple independent security layers so that a single mistake does not collapse the entire security posture.

The 4 Options of Block Public Access

Block Public Access consists of four independent settings. Since 2023, all four are enabled by default on every new bucket.

OptionWhat it blocks
BlockPublicAclsBlocks public grants in new ACLs
IgnorePublicAclsIgnores public grants in existing ACLs
BlockPublicPolicyBlocks public grants in new bucket policies
RestrictPublicBucketsBlocks anonymous/cross-account-external access even if the bucket policy allows public

It can also be set at the account level, and the account-level setting takes precedence over the bucket level. You can also use an AWS Organizations SCP to enforce "never allowed to turn off Block Public Access" — a method that large-enterprise security teams prefer.

📚 Case study: In the 2019 Capital One data breach, the attacker read EC2 metadata via an SSRF vulnerability in the WAF, stole IAM credentials, and then read the data in an S3 bucket. The bucket was not public at the time, but the stolen IAM role had excessive S3 read permissions. The card-application data of 106 million people was exposed. This incident shows that Block Public Access alone is not enough — the principle of Least Privilege and IMDSv2 configuration are needed together.

Bucket Policies — The Power of Resource-Based Policies

Unlike an IAM policy, a bucket policy is a policy attached to a resource. It can grant permissions even to a different AWS account that has no IAM user, or to public internet users. It is the key tool for cross-account access.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowOrganizationReadOnly",
      "Effect": "Allow",
      "Principal": "*",
      "Action": ["s3:GetObject", "s3:GetObjectVersion"],
      "Resource": "arn:aws:s3:::my-company-data/*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalOrgID": "o-xxxxxxxxxxxx"
        }
      }
    },
    {
      "Sid": "DenyHTTP",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::my-company-data",
        "arn:aws:s3:::my-company-data/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

The aws:PrincipalOrgID condition is a powerful pattern that allows access only from accounts belonging to a specific AWS Organization. An external IP or account outside the organization is denied by this condition even with "Principal": "*".

Denying HTTP with the aws:SecureTransport condition forces all S3 communication to use HTTPS. This is the basic protection of data in transit.

⚠️ Trap: Placing a Deny on aws:SecureTransport: false is different from placing an Allow on aws:SecureTransport: true. The Deny approach is the correct one. If you only place an Allow, HTTP does not fall through to default deny — it can be allowed together when there is another Allow rule. Enforcing HTTPS must always be configured as a Deny on the false condition.

ACLs — Why They Became Legacy and the Currently Recommended Setting

An ACL (Access Control List) is an access-control method that existed since S3's early design. It can be granted on buckets and on objects individually, and it was a simple way to grant specific permissions to another AWS account. However, in 2021 AWS shifted, through the Object Ownership setting, toward effectively deprecating ACLs.

The three current Object Ownership options:

  • Bucket Owner Enforced (recommended): ACLs completely disabled. Control by IAM and bucket policy only. The default for new buckets since 2023.
  • Bucket Owner Preferred: ACLs allowed, but a PUT with the bucket-owner-full-control header is owned by the bucket owner.
  • Object Writer (legacy): The principal that did the PUT is the object owner. Ownership disputes can arise on cross-account uploads.

🔍 Going deeper: The representative pattern where ACLs caused problems was cross-account uploads. When account A uploads an object to account B's bucket, in Object Writer mode account A becomes the owner of that object. Even though the object is in its own bucket, account B ends up in a situation where it cannot delete or change the tags of the object at will. Setting Bucket Owner Enforced makes the bucket owner always the owner of all objects, resolving this problem.

The 4 Methods of S3 Encryption — The Difference in Who Manages the Key

The key to understanding S3 encryption is "who manages the encryption key."

SSE-S3 (Server-Side Encryption with S3 Managed Keys): AWS fully manages the keys. Key generation, rotation, and storage are all AWS's responsibility. Header: x-amz-server-side-encryption: AES256. No additional cost. The default for all new objects since 2023.

SSE-KMS (Server-Side Encryption with KMS Keys): The customer manages the keys in AWS KMS. Header: x-amz-server-side-encryption: aws:kms. Fine-grained access control is possible through KMS key policies, and all key usage is logged in CloudTrail. The downside is that it calls the KMS API on every encryption/decryption — there is a limit of 5,500–30,000 requests per second, which becomes a bottleneck in high-performance environments.

DSSE-KMS (Dual-layer SSE with KMS): Applies two independent encryption layers. It is a defense/government option that meets FIPS 140-3 Level 3 requirements.

SSE-C (Server-Side Encryption with Customer Keys): The customer provides the key and AWS performs the encryption. AWS does not store the key. You must pass the key in a header on every request. HTTPS is required — sending the key over HTTP exposes it on the network. The key is verified with a SHA-256 hash and discarded immediately after encryption.

CSE (Client-Side Encryption): The client encrypts the data before uploading. AWS only sees the encrypted data and cannot access the key. It is the strongest security, but the client-code complexity is high.

MethodKey managementAudit logHTTPS requiredKMS costExtra code
SSE-S3AWS fully managed❌❌❌❌
SSE-KMSKMS (customer-configured)✅ CloudTrail❌✅❌
DSSE-KMSKMS dual✅ CloudTrail❌✅✅❌
SSE-CCustomer-provided❌✅ required❌Key management needed
CSECustomer directly❌Recommended❌Encryption code

💡 Related theory: Among the design principles of modern encryption systems, "Key Separation" means storing the encryption key and the encrypted data on physically different systems. SSE-KMS implements this principle — the data is stored in S3 and the key in KMS, separately, and KMS provides independent key auditing and access control. In SSE-S3, the key and the data reside within the same system (the S3 service), so this separation is not complete.

S3 Bucket Key — How to Cut KMS Costs by 99%

The biggest downside of SSE-KMS is that it calls the KMS GenerateDataKey API on every object encryption/decryption. If 10,000 requests per second come into the bucket, 10,000 API calls per second are generated to KMS as well. The KMS API has a per-region limit, so throttling occurs and costs surge.

S3 Bucket Key solves this problem. It generates a bucket-level key once from KMS and uses this bucket key to encrypt individual objects. The KMS calls are reduced to one per bucket. According to AWS's announcement, enabling Bucket Key cuts KMS costs by up to 99%.

Exam scenario: "While using SSE-KMS, S3 requests fail because the KMS API limit is exceeded" → the answer is to enable the S3 Bucket Key or to request a KMS service quota increase. Bucket Key is the better solution that both reduces cost and resolves throttling.

🔍 Going deeper: The operating principle of S3 Bucket Key leverages the key hierarchy. The KMS CMK (Customer Master Key) generates a DEK (Data Encryption Key); regular SSE-KMS receives a new DEK from KMS for each object. In Bucket Key mode, a bucket-level key is created once from the CMK, and this bucket key generates individual DEKs within the S3 infrastructure. KMS is called only when creating/rotating the bucket key. Note, however, that an object's ETag changes after enabling Bucket Key, so a workflow that uses the ETag for integrity verification requires caution.

VPC Endpoint — Accessing S3 Without the Internet

There are two ways for an EC2 instance or a Lambda function to access S3.

Via the internet gateway: Going out from the VPC to the internet and accessing the S3 public endpoint. Incurs NAT Gateway cost + data transfer cost.

Via a VPC Endpoint: Accessing S3 over the AWS internal network. Does not go out to the internet.

There are two kinds of VPC Endpoints.

TypeCostAddressOn-premises accessCross-region
Gateway EndpointFreeAdded to the routing table❌❌ (same region only)
Interface Endpoint (PrivateLink)Hourly fee + data processing feeENI + private IP✅ (Direct Connect/VPN)✅

Exam scenario: "Access S3 from EC2 without a NAT Gateway" → Gateway Endpoint (free). "Access S3 from on-premises via a private IP" → Interface Endpoint.

The Hidden Trap of Cross-Account KMS Encryption

When uploading or downloading an SSE-KMS-encrypted object from a different account, additional permission configuration is required.

Scenario: You want to upload an object encrypted with account A's KMS key to account B's S3 bucket, and have a user in account B download it.

Required permissions:

  1. Add account B's role/user as a Principal in account A's KMS key policy
  2. Add kms:Decrypt permission to account B's IAM policy
  3. For CRR replication: add kms:Encrypt permission for the replication role to the destination-region KMS key

If you do not configure all three of these, an "AccessDenied" or "KMS key access denied" error occurs. On the exam, when a "cross-account KMS encryption problem" scenario appears, you must check both layers (bucket policy + KMS key policy).

⚠️ Trap: The KMS key policy and the IAM policy must both have an Allow. If you allow it only in the key policy and there is no allow in the IAM policy, access is denied (KMS requires the intersection of both policies). Conversely, if you allow it only in the IAM policy and there is no allow in the key policy, it is also denied.

S3 Access Point — Simplifying Complex Bucket Policies

When multiple teams access a single S3 bucket with different permissions, managing this with a single bucket policy makes the policy grow to thousands of lines in complexity. An S3 Access Point creates multiple virtual entrances to a bucket, letting you manage independent access policies per team.

[Bucket: company-data]
    ↑
    ├── [Access Point: finance-ap] → finance team only (finance/ prefix)
    ├── [Access Point: hr-ap] → HR team only (hr/ prefix, VPC-only)
    └── [Access Point: engineering-ap] → engineering team (engineering/ prefix)

Each Access Point has its own DNS name and policy. If you create a VPC-restricted Access Point, it is accessible only from within that VPC, and internet access is blocked at the source.

Exam scenario: "Multiple teams must access one bucket with their own different permissions" → S3 Access Points is the answer.

💡 Related theory: The Access Point pattern is similar to the Facade Pattern in software design. It wraps a complex internal structure (bucket policy, thousands of objects) in a simple interface (the Access Point) and exposes it to users. Each team only needs to know its own Access Point and does not need to know the entire bucket structure.

CORS — The Setting Needed When Accessing S3 Directly from the Browser

When a web browser sends a request directly to S3 with JavaScript (e.g., uploading a file with a Pre-signed URL), the browser's Same-Origin Policy blocks the request. You must add a CORS configuration to the S3 bucket.

[{
  "AllowedOrigins": ["https://myapp.example.com"],
  "AllowedMethods": ["GET", "PUT", "POST"],
  "AllowedHeaders": ["Content-Type", "x-amz-server-side-encryption"],
  "ExposeHeaders": ["ETag"],
  "MaxAgeSeconds": 3000
}]

Exam scenario: "A CORS error occurs when uploading directly to S3 from client-side JavaScript" → add a CORS configuration to the bucket.

The S3 security layers we looked at today — Block Public Access, bucket policies, ACLs, encryption methods, Access Points — are all independent yet cooperating defense layers. In the next day, we look at the performance optimization techniques for uploading and downloading large volumes of data to and from S3 quickly.

📝 Practice Questions

Click a choice to reveal the answer and explanation.

Question 1

Which of the following is the correct way to configure a bucket policy to allow only HTTPS in S3?

Question 2

On an S3 bucket using SSE-KMS encryption, a KMS API limit error occurs at thousands of requests per second. What is the most effective solution?

Question 3

When a user in a different AWS account tries to download an SSE-KMS-encrypted S3 object, an AccessDenied error occurs. What settings must you check?

Question 4

A company has a requirement where three teams (finance, HR, dev) must access different prefixes in an S3 bucket, and the HR team must access only from within the VPC. What is the most suitable solution?

Question 5

Which is the correct description of SSE-C encryption?

Question 6

With account-level Block Public Access enabled on an S3 bucket, you allowed GetObject with "Principal": "*" in the bucket policy. What happens when you access that object from the internet?

Question 7

Which of the following is correct regarding the post-2023 changes to S3 encryption?

PreviousS3: Versioning, Lifecycle Policies, and the Inner Workings of ReplicationWeek 5 · Day 2Next S3 Performance Optimization: Multipart Upload, Transfer Acceleration, Prefix DesignWeek 5 · Day 4

Official references

  • DVA-C02 official exam page(opens in a new tab)
  • Amazon S3 documentation(opens in a new tab)
  • AWS KMS documentation(opens in a new tab)
  • AWS IAM documentation(opens in a new tab)
  • Amazon VPC documentation(opens in a new tab)
  • AWS CloudTrail documentation(opens in a new tab)

On this page

  • The Layered Structure of S3 Access Control — In What Order Is It Evaluated?
  • The 4 Options of Block Public Access
  • Bucket Policies — The Power of Resource-Based Policies
  • ACLs — Why They Became Legacy and the Currently Recommended Setting
  • The 4 Methods of S3 Encryption — The Difference in Who Manages the Key
  • S3 Bucket Key — How to Cut KMS Costs by 99%
  • VPC Endpoint — Accessing S3 Without the Internet
  • The Hidden Trap of Cross-Account KMS Encryption
  • S3 Access Point — Simplifying Complex Bucket Policies
  • CORS — The Setting Needed When Accessing S3 Directly from the Browser
  • Practice Questions