SCS-C02 Data Protection Practice Question
A company is storing sensitive data in Amazon S3 buckets. They want to ensure that all uploaded objects are encrypted at rest using server-side encryption with AWS KMS (SSE-KMS). Which bucket policy statement will enforce this?
⚠ Common exam trap
It's easy for candidates to choose an Allow policy (Option C) thinking it enforces encryption, but without a Deny, requests that omit the encryption header are still allowed by default, making the policy ineffective.
Answer choices
Why each option matters
Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.
Correct answer & explanation
✓
{"Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::bucket/*", "Condition": {"StringNotEquals": {"s3:x-amz-server-side-encryption": "aws:kms"}}}
It uses a Deny effect with a StringNotEquals condition on the s3:x-amz-server-side-encryption header set to 'aws:kms'. This ensures that any PutObject request that does not include the header specifying SSE-KMS is denied, effectively enforcing that all uploaded objects must be encrypted with AWS KMS. The Deny effect overrides any Allow, making this policy robust against accidental or malicious uploads without the required encryption.
Answer analysis
Option-by-option breakdown
For each option: why learners choose it and why it is or isn't the right answer here.
- ✓
{"Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::bucket/*", "Condition": {"StringNotEquals": {"s3:x-amz-server-side-encryption": "aws:kms"}}}
Why this is correct
This bucket policy is correct because it uses an explicit Deny with a StringNotEquals condition to require that every s3:PutObject request includes the x-amz-server-side-encryption header set to aws:kms. Since explicit Deny statements override any Allow, any upload that lacks the header or uses a different encryption method is blocked, while requests that properly specify SSE-KMS are allowed. The absence of the header also makes StringNotEquals evaluate true, so the Deny also catches requests that omit encryption entirely, ensuring sensitive data is always encrypted with KMS-managed keys.
- ✗
{"Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::bucket/*", "Condition": {"StringNotEquals": {"s3:x-amz-server-side-encryption": "AES256"}}}
Why it's wrong here
This policy is incorrect because it compares the x-amz-server-side-encryption header against the value AES256, which corresponds to SSE-S3, not SSE-KMS. With Deny and StringNotEquals, it blocks any upload that does not specify SSE-S3, including requests that correctly use aws:kms for KMS encryption, thus failing the requirement to mandate KMS. Additionally, a request without an encryption header would be denied because the missing key evaluates as not-equal to AES256, but the real flaw is that the value is wrong for the stated goal of requiring KMS.
- ✗
{"Effect": "Allow", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::bucket/*", "Condition": {"StringEquals": {"s3:x-amz-server-side-encryption": "aws:kms"}}}
Why it's wrong here
This policy is ineffective because a conditional Allow only grants permission when the condition is met; it does not prevent a principal who has permissions from another policy (such as an IAM user policy or a different bucket policy) from uploading an object without SSE-KMS. In IAM, only an explicit Deny can override an Allow, so allowing PutObject only when aws:kms is specified leaves non-compliant uploads possible if they are permitted elsewhere. To enforce encryption, you must invert the logic with a Deny statement that blocks requests where the header is not aws:kms, not an Allow that merely permits one specific case.
- ✗
{"Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::bucket/*", "Condition": {"StringEquals": {"s3:x-amz-server-side-encryption": "aws:kms"}}}
Why it's wrong here
This policy is incorrect and nearly identical to the second option, as it also uses AES256 (SSE-S3) as the required encryption value instead of aws:kms. With Deny and StringNotEquals, this would reject all uploads that do not set x-amz-server-side-encryption to AES256, which includes legitimate KMS-encrypted requests that use the aws:kms value. Since the requirement is to enforce SSE-KMS, the condition must check for aws:kms; using AES256 actively blocks compliant uploads and would allow only SSE-S3, directly contradicting the security objective.
Quick reference
AWS S3 Storage Class Comparison
| Storage Class | Min Duration | Retrieval | Use Case |
|---|---|---|---|
| S3 Standard | None | Immediate | Frequently accessed data |
| S3 Standard-IA | 30 days | Immediate | Infrequent access, rapid retrieval |
| S3 One Zone-IA | 30 days | Immediate | Non-critical infrequent data |
| S3 Intelligent-Tiering | None | Immediate–hours | Unknown or changing access patterns |
| S3 Glacier Instant | 90 days | Milliseconds | Archive with instant retrieval |
| S3 Glacier Flexible | 90 days | Minutes–hours | Archive, flexible retrieval |
| S3 Glacier Deep Archive | 180 days | Hours | Long-term compliance archive |
Go deeper
Related to this question
About these practice questions
This SCS-C02 question is part of Courseiva's 1,205-question bank — original exam-style content with full explanations and wrong-answer analysis, never real exam questions or exam dumps. Learn why practice questions differ from exam dumps →
JA
Written by Johnson Ajibi, MSc IT Security
Senior Network & Security Engineer · founder of Courseiva
This SCS-C02 practice question is part of Courseiva's free Amazon Web Services certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the SCS-C02 exam.