Amazon SCS-C02: Data Protection & S3 — Study Guide

Part of the AWS Security Specialty SCS-C02 — Study Guide. Practice with verified answers in the Amazon exam hub, or take timed practice tests on ExamRoll.io.

S3 Bucket Policies, Resource ARNs, and Explicit Denies

An S3 bucket policy is a resource-based JSON document evaluated alongside identity-based policies. Two rules dominate its behavior. First, an explicit Deny always wins: no matter how many Allow statements exist, a matching Deny blocks the request. Second, the Resource element must precisely match the ARN pattern of the action. Bucket-level actions like s3:ListBucket operate on arn:aws:s3:::my-bucket, while object-level actions like s3:GetObject and s3:PutObject operate on arn:aws:s3:::my-bucket/*. A common misconfiguration is granting s3:GetObject on arn:aws:s3:::my-bucket without the /* suffix — the API call targets an object ARN, no statement matches, and the request is denied by default.

The following policy denies any non-TLS access and grants read for a specific role, using both ARN forms correctly.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyInsecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::reports",
        "arn:aws:s3:::reports/*"
      ],
      "Condition": { "Bool": { "aws:SecureTransport": "false" } }
    },
    {
      "Sid": "AllowAnalyticsRead",
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::111122223333:role/Analytics" },
      "Action": ["s3:GetObject"],
      "Resource": "arn:aws:s3:::reports/*"
    }
  ]
}

A frequent trap is trying to “carve out” an exception by adding a later Allow after a broad Deny. Policy statements are not order-sensitive, and IAM evaluation logic returns Deny the moment any matching deny exists. The correct remediation is to narrow the Deny — for example, via a NotPrincipal or a Condition — rather than appending a permissive statement below it.

Lifecycle Rules, Object Expiry, and Vault Lock

S3 Lifecycle rules automate storage-class transitions and object expiration. To satisfy retention requirements — such as removing PII 30 days after ingest — attach a rule that expires current object versions after 30 days and permanently deletes noncurrent versions shortly thereafter. For related metadata written to DynamoDB, enable the DynamoDB TTL attribute so items self-delete on the same schedule; combining these two mechanisms is operationally efficient because no Lambda, scheduler, or bespoke cleanup code is required.

LifecycleConfiguration:
  Rules:
    - Id: ExpirePIIAfter30Days
      Status: Enabled
      Filter: { Prefix: "ingest/" }
      Expiration: { Days: 30 }
      NoncurrentVersionExpiration: { NoncurrentDays: 1 }

For archived data with regulatory retention, S3 Glacier Vault Lock provides a separate WORM control at the vault level. Once the Vault Lock policy is committed (a two-step initiate/complete process within 24 hours), it cannot be altered, even by the account root. This is distinct from Object Lock, which operates at the S3 object level.

Block Public Access and CloudFront OAC

S3 Block Public Access (BPA) is a set of four account- and bucket-level switches that override any ACL or policy that would otherwise grant public access. Enable all four at the account level, and enforce with an SCP such as denying s3:PutBucketPublicAccessBlock when it would relax settings. This defense-in-depth prevents an engineer from accidentally re-exposing a bucket through a permissive ACL.

For public-facing content served through CloudFront, the correct pattern is Origin Access Control (OAC). OAC signs requests from CloudFront to S3 using SigV4; the bucket policy then permits only the CloudFront distribution’s service principal. Relying on CloudFront alone without OAC (or the legacy OAI) leaves the S3 URL directly accessible, defeating the CDN’s access controls and WAF. The bucket must remain private, BPA enabled, and the policy scoped to the distribution ARN:

{
  "Effect": "Allow",
  "Principal": { "Service": "cloudfront.amazonaws.com" },
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::site-assets/*",
  "Condition": {
    "StringEquals": {
      "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/E1ABCXYZ"
    }
  }
}

S3 Object Lock and Cross-Region Replication

Object Lock enforces WORM semantics on individual objects and requires that versioning be enabled and Object Lock be turned on at bucket creation (it cannot be added later to an existing bucket without contacting AWS). Two retention modes exist:

Compliance mode is the correct choice when the requirement is absolute immutability against all identities. To extend that guarantee across Regions, pair Object Lock with S3 Replication. Replicated objects preserve their lock configuration in the destination bucket (which must also have Object Lock enabled), so a Region-wide event or malicious deletion attempt cannot compromise the retained copy.

Macie and Athena for Discovery and Investigation

Amazon Macie uses managed and custom data identifiers to scan S3 objects for PII, PHI, credentials, and other sensitive patterns. It reports findings to Security Hub and EventBridge, enabling automated remediation such as quarantining objects with a restrictive tag-based bucket policy. Enable Macie in every Region that stores customer data, and delegate administration through AWS Organizations for centralized findings.

Amazon Athena provides serverless SQL over data in S3, and is the standard tool for querying CloudTrail object-level data events. To investigate who accessed a specific S3 object, enable CloudTrail data events for the bucket, deliver logs to a central S3 bucket, and query with Athena:

SELECT eventTime, userIdentity.arn, sourceIPAddress, requestParameters
FROM cloudtrail_logs
WHERE eventName IN ('GetObject','DeleteObject')
  AND requestParameters LIKE '%reports/q3-financials.pdf%'
  AND eventTime > '2024-01-01T00:00:00Z';

Consolidated Traps and Their Root Causes

Practical Problem: Use-Case Scenario

Scenario: Meridian Financial stores customer statements, transaction logs, and long‑term compliance archives in multiple S3 buckets across two AWS regions. Their environment uses CloudFront for customer portals, cross‑account logging, and automated lifecycle transitions to archival storage classes for regulatory retention.

Challenge: A recent internal review found several buckets with inconsistent policies exposing PII, no immutable retention for archived records, and no centralized way to discover where sensitive objects reside across accounts and regions.

Recommended Approach:

  1. Enable S3 Block Public Access at the account and bucket level and deploy CloudFront Origin Access Control (OAC); tighten the bucket policy to allow GetObject only from the CloudFront OAC principal using precise resource ARNs and add explicit denies for any request not coming via the OAC.
  2. Enforce server‑side encryption with AWS KMS by requiring kms:Encrypt/kms:GenerateDataKey in a bucket policy and add explicit denies for PutObject requests that do not include x‑amz‑server‑side‑encryption and the required kms:context to prevent unencrypted uploads.
  3. Configure S3 Object Lock in compliance mode for buckets that must be immutable and enable Cross‑Region Replication (CRR) with replication rules that preserve object lock metadata so replicated objects remain immutable in the DR region.
  4. Create S3 Lifecycle Rules to transition aged objects to S3 Glacier storage classes and set object expiry for allowable retention windows; for archives that must be legally immutable, place them into Amazon S3 Glacier vaults and apply Glacier Vault Lock policies to enforce write‑once retention.
  5. Deploy Amazon Macie across accounts to discover and classify PII, enable S3 Inventory and query findings with Amazon Athena for investigative queries, and trigger automated remediation (Lambda/Step Functions) to tag, quarantine, or move sensitive objects into locked, encrypted buckets.

Rationale: This layered approach enforces least privilege and encryption, provides immutable retention and cross‑region durability for compliance, and uses Macie/Athena for centralized discovery and automated remediation—aligning with AWS best practices for data protection and lifecycle management.

Amazon Macie: Automated Discovery, Classification Jobs, and Allow Lists

Amazon Macie is a managed data security service that uses machine learning and pattern matching to discover sensitive data — personally identifiable information (PII), payment card numbers (PANs), credentials, and custom regex-defined data types — stored in Amazon S3. Macie operates in two complementary modes that are frequently confused.

Automated sensitive data discovery is a low-cost, continuously running process that samples objects across every bucket in the account (or across an organization when Macie is delegated to a Security account). It builds a per-bucket sensitivity score and inventory. This is the correct starting point when you have thousands of buckets and do not yet know where sensitive data lives, because it minimizes cost and administrative overhead by sampling rather than scanning every object.

Classification jobs (sensitive data discovery jobs) are one-time or scheduled deep scans targeted at specific buckets. Once automated discovery flags a bucket as containing sensitive data, you create a classification job scoped to that bucket for exhaustive analysis. The canonical pattern is therefore: enable automated discovery organization-wide, then follow up with classification jobs only on flagged buckets.

Allow lists are the mechanism for suppressing known-benign matches. If a data lake contains synthetic test PANs (for example the well-known 4111 1111 1111 1111 test card range), Macie will flag every occurrence. Rewriting the data or moving it is expensive and disruptive; the correct approach is to define a Macie allow list — either a plaintext list of exact values or a regex — and associate it with your classification jobs and automated discovery configuration. Matches against the allow list are excluded from findings while genuine PANs continue to trigger alerts.


### Practical Problem: Use-Case Scenario

**Scenario:** Meridian Financial runs a multi-account AWS environment with hundreds of S3 buckets storing transaction logs, customer documents, and long-term archives moved to S3 Glacier. Their security team has basic encryption and logging, but no centralized sensitive-data discovery or consistent retention controls across accounts.

**Challenge:** A recently discovered public-facing bucket contained archived customer records with PII after an errant bucket policy and lifecycle transition to S3 Glacier, and Meridian needs to find all sensitive data, remediate exposures, and enforce compliant archival retention going forward.

**Recommended Approach:**
1. Enable Amazon Macie across the AWS Organization and turn on automated S3 discovery so Macie continuously evaluates buckets and objects for sensitive data and risky configurations.
2. Create Macie classification jobs that target all S3 buckets; configure custom sensitive data identifiers for SSNs and account numbers and set up allow lists to exclude known test data, vendor files, and service accounts.
3. Use S3 Inventory to enumerate objects in S3 Glacier, then run S3 Batch Operations to temporarily restore only the objects flagged by inventory for Macie scanning so classification jobs can inspect content archived to Glacier.
4. Automate remediation by sending Macie findings to Amazon EventBridge and Security Hub; trigger Lambda functions to apply secure S3 bucket policies, enable S3 Block Public Access, remove public ACLs, and tag buckets for review.
5. Implement durable retention and prevention: enable S3 Versioning and S3 Object Lock (governance/compliance modes) on critical buckets, enforce SSE-KMS with CMKs via bucket policy, and deploy AWS Organizations SCPs to block public ACLs and require encryption and Object Lock where applicable.
6. Enable CloudTrail data events for S3 and feed findings into SIEM for alerting and periodic Macie classification job scheduling to ensure continuous coverage.

**Rationale:** This approach uses Macie for automated discovery and targeted classification (with allow lists), restores Glacier objects only when necessary for inspection, automates remediation via EventBridge/Lambda and enforces immutable retention and encryption with Object Lock and KMS—aligning with AWS best practices for detection, remediation, and preventive controls.

## Example allow list (regex form) matching common test PANs
Type: Regex
Regex: '^4111[- ]?1111[- ]?1111[- ]?1111$|^5555[- ]?5555[- ]?5555[- ]?4444$'
Name: synthetic-test-pans

Treating raw Macie findings as ground truth without configuring allow or suppression lists produces alert fatigue and can mask real incidents inside noise from synthetic data — this is why simply “trusting the findings” is the wrong answer for false-positive-heavy environments.

Integrating Macie Findings with EventBridge

Macie publishes every finding to Amazon EventBridge on the aws.macie source. This lets you route findings without polling the Macie API. A typical rule forwards Policy findings to SNS for on-call paging and sends SensitiveData findings to AWS Security Hub for aggregation.

{
  "source": ["aws.macie"],
  "detail-type": ["Macie Finding"],
  "detail": { "severity": { "description": ["High"] } }
}

The rule’s targets are SNS topics, Security Hub, or a Lambda function for custom remediation (for example, automatically applying a restrictive bucket policy on the offending bucket).

Bucket Policy Conditions for Organization Boundaries

S3 Block Public Access (BPA) only blocks access originating from the public internet or anonymous principals. It does not prevent an authenticated principal in a different AWS account or a different AWS Organization from accessing the bucket if a bucket policy or ACL grants such access. Relying on BPA alone is therefore incorrect when the requirement is to prevent cross-organization access — you must combine bucket policies with Service Control Policies (SCPs) at the Organizations level.

Two IAM condition keys make organization-boundary enforcement precise:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "DenyOutsideOrg",
    "Effect": "Deny",
    "Principal": "*",
    "Action": ["s3:GetObject", "s3:DeleteObject"],
    "Resource": "arn:aws:s3:::acme-compliance/*",
    "Condition": {
      "StringNotEqualsIfExists": {
        "aws:PrincipalOrgID": "o-abcd1234",
        "aws:SourceOrgPaths": "o-abcd1234/r-root/ou-prod-xyz/"
      }
    }
  }]
}

Pair this with an SCP that denies s3:DeleteObject* on resources where aws:ResourceOrgID does not match your Org, and cross-Org exfiltration or deletion becomes impossible even if a bucket policy is accidentally loosened.

S3 Object Lock: Compliance Mode and Versioning

Object Lock enforces write-once-read-many (WORM) semantics on individual object versions. It requires that S3 Versioning be enabled on the bucket (Object Lock without versioning is not possible — the lock protects a specific version ID, not the key).

Retention can be set per-object (Retain-Until date) or via a default bucket-level retention configuration. Legal Holds are separate, indefinite locks that persist until explicitly removed by a principal holding s3:PutObjectLegalHold.

aws s3api put-object-retention \
  --bucket acme-audit-logs \
  --key 2024/transactions.parquet \
  --retention '{"Mode":"COMPLIANCE","RetainUntilDate":"2031-01-01T00:00:00Z"}'

S3 Glacier Vault Lock: Fixing Policy Errors Before Lock Completion

Vault Lock on S3 Glacier enforces immutable vault access policies. The process has two calls: initiate-vault-lock puts the policy into an in-progress state with a 24-hour window, and complete-vault-lock makes it permanent. If a typo is discovered during the 24-hour window — for example, an overly permissive Principal — the correct and cheapest remediation is:

aws glacier abort-vault-lock --account-id - --vault-name compliance-archive
aws glacier initiate-vault-lock --account-id - --vault-name compliance-archive \
  --policy file://corrected-policy.json

abort-vault-lock cancels the in-progress lock at no cost, letting you re-initiate with the corrected policy. Alternative “fixes” — deleting and recreating the vault (which requires deleting all 10 TB of archives and re-uploading, incurring retrieval and transfer charges), or waiting for the lock to complete and then working around it — are wasteful or impossible. Once complete-vault-lock runs, the policy is immutable forever; abort is only valid during the in-progress window.

Adjacent Trap: DNSSEC Chain of Trust

A common cross-domain trap concerns Route 53 DNSSEC. Enabling DNSSEC signing on a hosted zone for a subdomain generates a Key Signing Key (KSK) and a corresponding DS record. That DS record must be published in the parent zone; without it, resolvers cannot validate the chain of trust and either treat responses as bogus or fall back to insecure resolution, breaking DNS for validating clients. Enabling signing without exporting the DS record and inserting it at the registrar or parent zone is a configuration-incomplete state, not a working DNSSEC deployment.


Encryption · All domains · Networking

Practice these questions → · Timed practice on ExamRoll.io →

Pass the whole exam — not just this question

You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.

Pass your exam →

Browse Amazon →

Related guides

All-in-one access

One subscription. Every exam.

Every plan unlocks unlimited answer search, practice tests, AI explanations, and the full resource library — in 20+ languages.

Monthly
24.87
Just €0.83/day
Everything included:
  • Unlimited answer search
  • Unlimited practice tests
  • AI-powered explanations
  • Full resource library
  • 20+ languages
  • Weekly content updates
  • Rewards & referrals
  • Priority support
Start free trial

No credit card required*

Best value
12 months
179.87
Just €0.49/daySave 40%
Everything included:
  • Unlimited answer search
  • Unlimited practice tests
  • AI-powered explanations
  • Full resource library
  • 20+ languages
  • Weekly content updates
  • Rewards & referrals
  • Priority support
Start free trial

No credit card required*

✓ Free plan included · ✓ Cancel anytime · ✓ All plans unlock the full product