The Exam Blueprint · DOP-C02 · D6 · Security & Compliance · 17%

Security & Compliance

Security & Compliance is tied for the single largest domain on the DOP-C02 exam blueprint at 17% of the questions — the same weight as Configuration Management and IaC, and only behind SDLC Automation's 22%. It is also the domain most candidates under-study, because it doesn't map to one product the way "CodePipeline" maps to SDLC Automation. It maps to a whole layer that sits underneath and around everything else in this course: who is allowed to do what, what gets encrypted and how, whether your account still looks the way you configured it to look yesterday, and whether anyone is watching for the moment it doesn't. This page covers that layer at exam depth — IAM least privilege, KMS and Secrets Manager, AWS Config and conformance packs, GuardDuty and Security Hub, and securing the pipeline that ships everything else.

☺ Explain it like I'm 10

Imagine your house has a landlord and a tenant. The landlord (AWS) is responsible for the foundation, the walls, and the locks on the building's front gate — that part is solid no matter what you do. You, the tenant, are responsible for locking your own apartment door, deciding who gets a key, and not leaving your jewelry on the windowsill. If your apartment gets robbed because you left the door open, that's not a landlord problem. This domain is entirely about being a good tenant: who gets a key (IAM), locking the valuables in a safe (encryption), a nightly walkthrough that checks every room still matches the checklist (Config), a guard who notices if someone's climbing through a window (GuardDuty), and making sure the delivery guy who drops off packages can't also let himself into the bedroom (pipeline security).

🐢🤖Your hosts for this topic: Timmy the Turtle & Recon the Robot — Timmy is the guardrail who won't hand out more access than a job needs, and Recon is the reconciliation loop who checks your account against the rules forever, not just once at deploy time.

The domain, and the shared responsibility model underneath it

☺ Like you're 10: AWS locks the building; you lock your apartment — this whole domain is everything on your side of that line.

Every task statement in this domain sits on top of one foundational idea: AWS's shared responsibility model. AWS is responsible for security of the cloud — the physical data centers, the hardware, the global network, and (for managed services) the underlying host OS and hypervisor. You are responsible for security in the cloud — how you configure IAM, what you encrypt and with which keys, how you patch a guest OS you still control, how you set your security groups, and what your own application code does with the access it's been granted. The exam never asks you to name the model outright; it asks scenario questions that only resolve correctly once you know which side of the line a given failure sits on.

EC2 (IaaS) — you own more RDS / Lambda (managed) — AWS owns more Data · IAM config Applications Guest OS & patching Network & firewall (SGs) Data · IAM · app config Hypervisor Physical hardware Global infrastructure DB / runtime engine Guest OS & hypervisor Physical hardware Global infrastructure "in the cloud" — you "in the cloud" — you The more AWS manages, the higher the line moves — but your slice never reaches zero

Notice the line moves. On EC2, you own the guest OS, so unpatched OS vulnerabilities are your finding, not AWS's. On RDS or Lambda, AWS owns the engine and the host, so your slice shrinks to data, access configuration, and application-level behavior — but it never disappears. Even on the most abstracted managed service, you still decide who has IAM access to it, whether its data is encrypted, and what your application does with the credentials it's handed. That residual slice is what the rest of this domain is built to cover, and it's also the lens AWS's own Well-Architected Framework uses in its Security pillar when architects review a workload: identity foundations, traceability, security at all layers, automating security best practices, protecting data in transit and at rest, and preparing for security events. Every section below maps onto one or more of those six.

IAM: least privilege, roles, and permission boundaries

☺ Like you're 10: Give everyone the smallest possible set of keys for the job in front of them, and use a second lock that caps how many keys any one key ring can ever hold.

IAM is the single most heavily tested service on the entire exam, and this domain is where its edge cases live. Four policy types combine to determine what a principal (a user, role, or federated identity) can actually do, and the exam's hardest questions are almost always about how they combine:

Policy typeAttached toWhat it does
Identity-based policyA user, group, or roleGrants (or denies) permissions to that identity directly — the policy type most people mean when they say "IAM policy."
Resource-based policyThe resource itself (S3 bucket policy, KMS key policy, Lambda resource policy, SQS/SNS policy)Grants permissions on that specific resource, including to principals in other AWS accounts — the only way to grant cross-account access without a role.
Permissions boundaryA user or role (as a managed policy)Sets the maximum permissions that identity's policies can ever grant. It never grants anything by itself — it only clips what identity policies are allowed to reach.
Service control policy (SCP)An AWS Organizations account or OUSets the maximum permissions for every principal in that account, including its root user. Also grants nothing by itself — pure guardrail, org-wide.

An identity's effective permissions are the intersection of everything that applies, minus any explicit deny: identity policy ∩ permissions boundary (if one is attached) ∩ SCP (if the account sits in an OU with one), with resource-based policies able to add cross-account access on top for that specific resource. This is why the single most common permission-boundary mistake in the field — and on the exam — is attaching AdministratorAccess as an identity policy and expecting a permissions boundary to somehow "correct" it down to least privilege. It does clip the ceiling, but it does nothing to encourage least privilege in the identity policy itself; the two need to be designed together, usually by delegating to a team the ability to create their own roles, capped by a boundary that keeps them from ever escalating past what a platform team pre-approved.

◆ Key idea

Permissions boundaries and SCPs solve the same shape of problem at two different altitudes. A permissions boundary caps one identity and is how you let application teams self-service their own IAM roles without a platform team reviewing every one. An SCP caps an entire account or OU and is how a security team enforces "no one in the sandbox OU can ever disable CloudTrail," full stop, no matter what any identity policy inside that account says — not even the account's own root user can override an SCP.

Beyond the four policy types, three practices show up constantly in scenario questions: prefer roles over long-lived IAM user access keys wherever compute needs AWS access — EC2 instance profiles, Lambda execution roles, ECS task roles, and CodeBuild/CodePipeline service roles all hand out short-lived credentials via STS AssumeRole that rotate automatically and never live in a config file; use condition keys (aws:SourceIp, aws:MultiFactorAuthPresent, aws:PrincipalOrgID, aws:RequestedRegion) to scope a policy beyond what the Action/Resource block alone can express; and run IAM Access Analyzer before and after granting access — it flags resources shared outside your account or organization, and its policy generation feature can draft a least-privilege policy straight from a role's actual CloudTrail activity, which is the fastest real-world way to shrink an over-broad policy down to what a workload actually uses.

Encrypting everything: KMS and Secrets Manager

☺ Like you're 10: A locked box for your data (KMS) and a locked box for your passwords that also changes the lock on a schedule (Secrets Manager).

AWS KMS is the encryption backbone nearly every other AWS service defers to. A customer managed key (CMK) is controlled by a key policy — a resource-based policy that is mandatory and, unusually, applies even to the account's own root user: if the key policy doesn't grant access, an AdministratorAccess IAM policy alone will not unlock it. That dual-control design (key policy and IAM policy must both allow the action) is a favorite exam trap. Symmetric keys (AES-256, the default) support optional automatic annual rotation with no application-visible change, because KMS keeps prior key material to decrypt data encrypted under an older version transparently. Asymmetric keys (RSA or elliptic-curve, used for encrypt/decrypt or sign/verify workflows) do not support automatic rotation at all — if a question mentions rotating an asymmetric key on a schedule, that option is wrong by definition.

Large payloads never get encrypted by KMS directly — the service enforces a 4 KB limit on direct Encrypt calls specifically to push you toward envelope encryption: KMS generates a data key, your application (or the AWS SDK, transparently, via the S3/EBS/RDS integration) encrypts the actual payload locally with that data key, and only the small data key itself gets sent to KMS to be wrapped by the CMK and stored alongside the ciphertext. This is also how EBS, S3 (SSE-KMS), and RDS default encryption scale to large volumes without hammering the KMS API. One RDS wrinkle worth knowing cold: encryption at rest can only be set at creation time — you cannot flip it on for an existing unencrypted instance; the standard path is snapshotting the instance, copying the snapshot with encryption enabled, and restoring a new instance from the encrypted copy.

{
  "Sid": "AllowPipelineRoleToDecryptOnly",
  "Effect": "Allow",
  "Principal": { "AWS": "arn:aws:iam::111122223333:role/deploy-role" },
  "Action": ["kms:Decrypt", "kms:DescribeKey"],
  "Resource": "*",
  "Condition": {
    "StringEquals": { "kms:EncryptionContext:app": "checkout" }
  }
}

That last block is encryption context — non-secret key/value pairs passed alongside an Encrypt/Decrypt call that KMS uses as additional authenticated data. Get the context wrong at decrypt time and the call fails even with a valid key and valid permissions; every use of it is also logged to CloudTrail, which is what makes it useful for scoping a policy to "only decrypt secrets belonging to the checkout app" rather than every secret the key protects.

For actual credentials — database passwords, third-party API keys — the choice is between Secrets Manager and Systems Manager Parameter Store SecureString, and the exam expects you to know when each wins:

Secrets ManagerParameter Store (SecureString)
CostPer-secret + per-API-call chargeStandard tier free; advanced tier low per-parameter cost
Automatic rotationNative — built-in Lambda rotation templates for RDS, Aurora, Redshift, and DocumentDB; bring your own Lambda for anything elseNone built in — you schedule your own EventBridge rule to trigger a rotation Lambda
Cross-account / cross-regionNative replicationManual
Typical fitDatabase credentials and anything that needs scheduled rotationConfig values and secrets where cost matters more than built-in rotation

Both encrypt with KMS underneath, so the real decision is "do I need managed rotation" — if yes, Secrets Manager; if the answer is "occasional config value, don't care about rotation, watching spend," Parameter Store SecureString is the cheaper, correct pick. See Secrets & Credential Management for rotation Lambda internals and a HashiCorp Vault comparison, and Vault if your org runs a multi-cloud secrets layer rather than an AWS-native one.

Continuous compliance: AWS Config and conformance packs

☺ Like you're 10: A robot that walks every room in the house every few minutes and checks it against a rulebook, forever — not just on move-in day.

AWS Config records a configuration item every time a supported resource changes and keeps the full history, which gives you two things a point-in-time audit never can: "what did this security group look like three weeks ago" and "did anything change between the last two deploys." On top of that history sit Config rules — AWS managed rules you enable with one click (s3-bucket-public-read-prohibited, encrypted-volumes, iam-user-mfa-enabled, restricted-ssh) or custom rules you write yourself, either as a Lambda function or, increasingly, as a Guard rule — AWS CloudFormation Guard's declarative policy-as-code language — so a custom compliance check doesn't require standing up and maintaining a Lambda at all.

A single Config rule doesn't scale to "enforce this everywhere." Conformance packs do: a conformance pack is one YAML template bundling many related Config rules — and, optionally, their auto-remediation actions — deployable as one unit to an account, or org-wide via an organization conformance pack pushed from the management account to every member account at once. AWS publishes ready-made sample packs for standards like the CIS AWS Foundations Benchmark and PCI DSS, which is usually the fastest way to stand up "we are compliant with <standard>" as a continuously-checked, rather than once-audited, fact.

Resource changes state AWS Config records config item Config rule from a conformance pack Compliant no action Non-compliant SSM Automation auto-remediates finding → Security Hub re-evaluates on every future change, forever — not once at deploy time

The loop is deliberately the same shape you already know from Terraform state and GitOps drift: desired state (the rule), actual state (the config item), a diff, and a correction. The difference is what counts as desired state — here it's "does this configuration satisfy a compliance rule," not "does this configuration match a manifest." When a rule evaluates NON_COMPLIANT, attaching an SSM Automation remediation document (with a retry count and rate limit to avoid a remediation storm) closes the loop without a human in it — see Compliance as Code & Policy Enforcement for writing custom Guard rules and building your own remediation runbooks, and Configuration Management & IaC for how this same reconciliation pattern shows up one domain over, applied to infrastructure drift rather than compliance drift.

Threat detection: GuardDuty and Security Hub

☺ Like you're 10: One service watches for someone actually breaking in (GuardDuty); another collects every alarm in the building — break-ins, unlocked doors, expired fire extinguishers — onto one screen (Security Hub).

GuardDuty is a threat detection service, not a compliance service — the distinction the exam leans on hardest in this section. It continuously analyzes CloudTrail management and S3 data events, VPC Flow Logs, and DNS query logs by default the moment you enable it, no log pipeline to build yourself, and layers on optional protection plans — S3 protection, EKS audit log and runtime monitoring, RDS login activity, Lambda network activity, and EBS malware scanning — for broader coverage. Under the hood it combines threat-intelligence feeds with machine-learning anomaly detection to surface findings like UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration or Recon:EC2/PortProbeUnprotectedPort, each scored Low, Medium, or High severity.

Security Hub doesn't detect anything itself — it's the aggregation and normalization layer sitting on top of GuardDuty, Inspector, Macie, IAM Access Analyzer, Config, Firewall Manager, and third-party tools, translating every finding from every source into one consistent shape, the AWS Security Finding Format (ASFF). It also runs its own continuous checks against named security standards — the CIS AWS Foundations Benchmark, the AWS Foundational Security Best Practices (FSBP) standard, PCI DSS, and NIST 800-53 — and rolls the results into a security score per account. A designated administrator account can aggregate findings across an entire AWS Organization, and — critically for this course — every finding lands on EventBridge, so a Security Hub finding can trigger a Lambda that automatically isolates a compromised instance's security group, or route straight into the paging path covered in Incident & Event Response, which is exactly the job Pip the Hummingbird does in the rest of this course.

ServiceAnswers
CloudTrail"What API call happened, when, and who made it?" — the raw audit log everything else draws from.
AWS Config"Is this resource's configuration compliant with a rule right now, and how did it look last week?"
GuardDuty"Is there malicious or anomalous behavior happening against this account?"
Security Hub"One screen, every finding from every source above, normalized and scored against a named standard."
⚠ Watch out

The exam loves swapping these four services into each other's answer slots. "Which service tells you a security group was opened to 0.0.0.0/0 an hour ago and is still open" is Config (a compliance rule against current + historical state), not GuardDuty — GuardDuty would only fire if that open port was actually probed or exploited, which is a behavior, not a configuration. If the scenario says "detect" or "malicious," think GuardDuty; if it says "compliant," "drift," or "rule," think Config; if it says "one dashboard across everything," think Security Hub.

Securing the pipeline itself

☺ Like you're 10: The delivery truck that drops off packages shouldn't also have a key to the front door — and you should be able to prove, after the fact, exactly what was inside every box it delivered.

Everything above protects the account at rest. This last piece protects the thing that changes the account on every merge: the pipeline. Three practices carry most of the exam weight here.

Pipeline IAM roles, scoped per stage. A CodeBuild role that compiles and tests code needs to read source and write build logs — it does not need permission to run CloudFormation or invoke CodeDeploy. A separate deploy role needs the opposite. Splitting them means a compromised dependency in the build stage can't also push straight to production, because the credentials it has access to were never granted that reach in the first place. For deployments that cross AWS accounts (a common pattern: one tooling account runs the pipeline, separate dev/staging/prod accounts each hold their own resources), the deploy stage uses sts:AssumeRole into a narrowly-scoped role in the target account rather than holding standing credentials for every environment at once — see AWS Developer Tools for how CodePipeline cross-account actions configure this. For pipelines running outside AWS entirely — GitHub Actions is the common case — prefer OIDC federation over long-lived IAM user access keys stored as repo secrets: configure an IAM OIDC identity provider that trusts token.actions.githubusercontent.com, scope the trust policy's condition to a specific repo and branch (repo:acme/checkout:ref:refs/heads/main), and every workflow run gets short-lived credentials with zero long-lived secrets to leak in the first place.

Dependency and image scanning, shifted left. Amazon Inspector v2 continuously rescans container images pushed to ECR and deployed Lambda functions against the National Vulnerability Database the moment a new CVE is published — no manual re-trigger needed. Layered on top of that, scanning inside the CI stage itself (Amazon CodeGuru Security, or third-party SCA tooling like Snyk or OWASP Dependency-Check) catches a vulnerable dependency in a pull-request check, before it ever reaches an image registry. That ordering is the whole point: a finding caught in a PR costs a failed check; the same finding caught in production costs an incident. Shift-Left Security for DevOps covers SAST/DAST placement in the pipeline in full.

Artifact signing and provenance. AWS Signer signs Lambda deployment packages so a function can be configured to reject any code update that doesn't carry a signature from an approved signing profile — supply-chain tampering becomes a deploy-time rejection instead of a runtime surprise. For container images, the open-source equivalent pattern (sigstore/cosign) accomplishes the same thing: a signed image plus its generated SBOM proves both who built it and exactly what's inside it, checked as its own pipeline gate before a deploy role is ever invoked. Full coverage, including SBOM formats and registry-level enforcement, lives in Supply-Chain Security & SBOM.

🐢 Timmy's workshop · 20 min

Take one pipeline you already have running — even a toy one. List every IAM role it touches, and for each one, write down the single riskiest action its current policy would allow if that role's credentials leaked today (not what it's used for — what it's allowed to do). If any answer is broader than "read source, write logs" for a build stage or "deploy to one specific environment" for a deploy stage, that's your least-privilege gap, and it's exactly the class of finding this domain tests.

Common exam traps in this domain

☺ Like you're 10: The exam likes to swap two similar-sounding things into the wrong slot — know which is which cold.

🎬 At the Ship-It Guild
🦊

Foxy: Our build role can already deploy straight to prod. Why split it into two roles? It's one pipeline.

🐢

Timmy the Turtle: Because "one pipeline" doesn't mean "one blast radius." If a bad dependency compromises your build step, I don't want its credentials able to touch production at all.

👺

Gizmo: Or — hot take — just attach AdministratorAccess to the whole thing. Way faster to set up. 🤑

🐢

Timmy the Turtle: That's not a permissions boundary, Gizmo, that's a boundary-shaped hole. I'm not signing off until each role has exactly what its stage needs, nothing more.

🤖

Recon: BEEP. And once you write the rule down, I'll check every account against it every few minutes, forever — not just the day you set it up.

🦊

Foxy: So least privilege isn't a one-time review. It's a rule Recon keeps re-checking.

🐢

Timmy the Turtle: Exactly. That's the whole domain in one sentence.

Security & Compliance doesn't stand alone on the exam — it's the lens the other five domains get graded through. A pipeline from SDLC Automation isn't finished until its roles are scoped; infrastructure from Configuration Management & IaC isn't resilient (Resilient Cloud Solutions) if it's also wide open; and a finding from GuardDuty is only useful once Incident & Event Response and Monitoring & Logging turn it into a page someone actually sees. Practice applying all of it hands-on in Drill — Secure a Vulnerable Pipeline and Capstone Part 6 — Security Hardening, then check your pacing against the rest of the blueprint in The DOP-C02 Exam and look up any service by name in the AWS Service & Command Reference.

⚠ Domain weights shift between exam guide revisions

The 17% figure and the domain split used across this blueprint reflect the DOP-C02 exam guide as published; AWS has revised DOP-C02's weighting before and can again. Verify the current domain breakdown on AWS's own DOP-C02 exam page before you build a study plan around a specific percentage.

🐢 Timmy's checkpoint

1. What is the difference between a permissions boundary and a service control policy, and what do they have in common? 2. Why can't an asymmetric KMS key use automatic rotation, and what kind of key can? 3. A publicly-writable S3 bucket has existed, untouched, for two weeks. Which service's finding is that — Config or GuardDuty — and why? 4. When is Secrets Manager the better choice over Parameter Store SecureString, and when is SecureString actually the more correct answer? 5. Name two ways to eliminate long-lived AWS credentials from a CI/CD pipeline.

Check your answers
  1. A permissions boundary caps the maximum permissions of one IAM user or role; an SCP caps the maximum permissions of an entire AWS account or OU (including its root user). Neither grants any permission by itself — both only clip what identity policies inside their scope are allowed to reach.
  2. Asymmetric keys don't support automatic rotation because KMS can't transparently swap key material for sign/verify or asymmetric encrypt/decrypt operations the way it can for symmetric AES-256 keys, which keep prior key versions around to decrypt older ciphertext invisibly. Only symmetric customer managed keys support optional automatic annual rotation.
  3. Config, not GuardDuty. Config evaluates static/historical configuration against a rule (a public bucket is non-compliant the instant it's created, whether or not anyone touches it). GuardDuty only fires on observed behavior — it would need the bucket to actually be accessed or scraped by a suspicious actor to generate a finding.
  4. Secrets Manager wins when you need native, scheduled rotation — especially the built-in RDS/Aurora/Redshift/DocumentDB rotation templates. Parameter Store SecureString wins for lower-cost config values and secrets with no rotation requirement, where paying for Secrets Manager's per-secret and per-API-call pricing would be over-engineering.
  5. Any two of: use IAM roles (instance profiles, execution roles, service roles) instead of IAM user access keys for any AWS-hosted compute in the pipeline; use OIDC federation (an IAM OIDC identity provider trusting the CI platform's token issuer) instead of storing static AWS access keys as repo secrets for externally-hosted pipelines like GitHub Actions; use sts:AssumeRole for cross-account deploy stages instead of holding standing credentials for every target account.