Data Security Controls
KMS key policies: cross-account grants, condition keys, ViaService restriction
The one rule that decides every KMS access question is this: the key policy is the authoritative grant, and IAM alone is never enough. A key's access is governed by its key policy (the resource policy on the key) working together with IAM identity policies, and once that ordering is clear you can decide who may use a key across accounts, lock a key to one service, and choose between a grant and a key-policy edit for temporary access.
Key policy basics: a default key policy[24] grants the AWS account root user full key access; from there, IAM policies can grant key actions to other principals (but only because the root grant exists). No contradiction: the account-root statement is a delegation switch. It hands granting over to IAM, and IAM grants work only while it stays in the key policy. To remove this, scope the key policy to specific principals; every IAM Allow then stops working.
Cross-account access pattern:
{
"Sid": "AllowCrossAccount",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::CONSUMER_ACCOUNT:root" },
"Action": ["kms:Decrypt", "kms:DescribeKey", "kms:CreateGrant"],
"Resource": "*"
}
In the Principal, :root is account-level syntax: the whole consumer account, not its root user (kms:CreateGrant lets it create grants: temporary permissions, covered below). The consumer account's role still needs kms:Decrypt in its identity policy: two-layer (resource + identity) authorization, like S3 cross-account access: the key policy is the first gate, the identity policy the second.
Condition keys worth memorising:
kms:ViaService[21]: restricts the key to be used only through a specific AWS service. E.g."kms:ViaService": "s3.us-east-1.amazonaws.com"means this key can only encrypt/decrypt via S3 in us-east-1. Defends against credentials being misused to decrypt the key through unintended services.kms:CallerAccount: restricts to a specific account. Combined with ViaService for fine-grained scoping.aws:SourceArn: restricts to a specific resource (e.g. only requests from one specific Lambda function or RDS instance).kms:EncryptionContext: requires a specific encryption-context dict to be passed; the same context must be supplied at decrypt time. Common in envelope encryption (KMS encrypts a per-object data key, which encrypts the data); Secrets Manager scopes rotation to one secret this way.
Grants vs key policy:
- Key policies are static: edit them and you change permanent permissions.
- Grants[20] are temporary, programmatic: created via
kms:CreateGrant, can be revoked or expire. AWS services (e.g. RDS encryption, EBS encryption) create grants automatically when they need temporary access.
For short-lived workloads needing temporary key access, grants are the pattern. For permanent integration, key policy.
ViaService restriction example (a common SAA scenario, applying kms:ViaService from above):
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::ACCOUNT:role/AppRole" },
"Action": ["kms:Encrypt", "kms:Decrypt"],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.us-east-1.amazonaws.com",
"kms:CallerAccount": "123456789012"
}
}
}
This role can encrypt/decrypt via this key, but only when the request comes through S3 in us-east-1 from account 123456789012. Misuse via SQS / Lambda / direct KMS API is denied.
S3 encryption options: SSE-S3 vs SSE-KMS vs SSE-C vs DSSE-KMS, when each applies
S3 supports four server-side encryption options (SSE-KMS in two flavours, AWS-managed or customer-managed key, so five variants below); they differ in who controls the key and whether key use is audited. Since January 2023, SSE-S3 is enabled by default[1] on every new bucket. The exam tests when to upgrade to a more controlled option.
SSE-S3 (AES-256 with AWS-managed keys):
- AWS manages key creation, rotation, and storage entirely.
- Free; no KMS API charges.
- NO CloudTrail audit of individual encrypt/decrypt operations.
- Use for: default for non-sensitive data, public marketing content.
SSE-KMS with AWS-managed key (aws/s3):
- AWS-managed key per region; free.
- Adds KMS API charges per encrypt/decrypt request.
- CloudTrail logs every key use (full audit trail).
- Key policy not editable; fine for general compliance, not for cross-account.
- Use for: compliance audit needs without cross-account complexity.
SSE-KMS with customer-managed key:
- You create the key; ~$1/key/month + per-request charges.
- Full key policy control: cross-account access, conditions like
kms:ViaServicefrom the first section. - Auto rotation (yearly) opt-in.
- Use for: multi-tenant isolation (key-per-tenant), cross-account encrypted access, regulatory compliance.
SSE-C (customer-provided keys)[3]:
- Caller provides the encryption key in every PUT/GET request (HTTPS only).
- AWS doesn't store the key; caller responsible for key management.
- No KMS API costs (KMS is bypassed entirely).
- No CloudTrail of key use.
- Use for: rare scenarios where customer MUST hold the key entirely outside AWS.
DSSE-KMS (Dual-layer SSE-KMS):
- Each object encrypted twice with two independent KMS calls.
- ~2× KMS request cost.
- Required for FedRAMP High workloads.
- Use for: government / defense workloads with explicit dual-layer requirement.
Decision pattern:
- 'Default encryption / public marketing content' → SSE-S3 (auto-on).
- 'Compliance audit / who decrypted what' → SSE-KMS (any flavour).
- 'Cross-account encrypted access' → SSE-KMS with customer-managed key.
- 'Multi-tenant data isolation' → SSE-KMS with separate customer-managed key per tenant.
- 'FedRAMP High / dual-layer' → DSSE-KMS.
- 'Customer must hold the key' → SSE-C.
Bucket-level enforcement: combine with a bucket policy denying non-encrypted uploads:
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::our-bucket/*",
"Condition": {
"StringNotEquals": { "s3:x-amz-server-side-encryption": "aws:kms" }
}
}
This denies any PUT that doesn't explicitly request SSE-KMS. The January 2023 default already rules out plaintext. This policy guarantees nothing lands with weaker encryption than SSE-KMS.
ACM certificate provisioning: DNS vs email validation, auto-renewal lifecycle
AWS Certificate Manager (ACM)[5] issues free TLS/SSL certificates for AWS services. The exam tests when ACM works, where the certificate must live, and how validation + renewal happen.
Where ACM-issued certificates can be used:
- CloudFront: certificate MUST be in us-east-1 (regardless of where your origin is).
- ALB / NLB / API Gateway / App Runner: certificate must be in the SAME region as the resource.
- Route 53: not a certificate consumer itself; it's where the DNS-validation records for ACM-issued certs live, in the hosted zone.
Issuance and validation are a short ordered flow whose one branch — the validation method you pick at step 2 — decides whether renewal is later hands-off or manual (the lifecycle diagram below traces exactly that branch):
- Request certificate: list domain names (FQDN + optional wildcards like
*.example.com). - Pick validation method:
- DNS validation (preferred): ACM gives you a CNAME record to add to your domain's DNS. Once propagated, ACM auto-validates and issues. Renewal stays hands-off as long as the CNAME stays in place (see Auto-renewal below).
- Email validation: ACM sends approval emails to standard addresses (admin@, hostmaster@, webmaster@) for the domain. Requires a manual click to approve, and again at every renewal (see below). Don't use unless you have to.
- Certificate issued → install on the AWS resource.
Auto-renewal:
- DNS-validated certificates renew automatically[25] 60 days before expiry. ACM checks the CNAME, validates, reissues. Zero downtime if the certificate is attached to a managed AWS resource (CloudFront, ALB).
- Email-validated certificates DON'T auto-renew; you must respond to a new email approval every year. Exam common trap: 'why did my ALB stop accepting HTTPS?' → email validation expired.
Private CA (AWS Private CA[26], formerly ACM Private CA):
- AWS Private CA provides a managed private CA for internal certificates (services that talk to each other internally over TLS).
- ~$400/month per CA[27] in general-purpose mode ($50/month in short-lived-certificate mode), billed per CA, so a root + subordinate hierarchy pays for each CA, plus per-certificate fees.
- Used for mutual-TLS (mTLS) on internal services.
Importing third-party certificates:
- You can import certs from external CAs (DigiCert, Let's Encrypt, etc.). Stored in ACM, usable on AWS services.
- Imported certs DON'T auto-renew; you must re-import the renewed cert. ACM sends expiry notifications via CloudWatch.
Public vs private certificates:
- ACM public certs (from Amazon Trust Services) are trusted by browsers worldwide. Free.
- ACM private certs (issued from your AWS Private CA) are trusted only by clients that trust the private CA. For internal mTLS.
Exam patterns:
- 'CloudFront with custom domain' → ACM cert in us-east-1.
- 'ALB HTTPS in us-west-2' → ACM cert in us-west-2.
- 'Internal microservices mTLS' → AWS Private CA + per-service private certs.
- 'Imported cert from Let's Encrypt' → no auto-renewal; CloudWatch alarm on expiry.
Block Public Access semantics: account vs bucket vs object level overrides
S3 Block Public Access[11] (BPA) is the strongest defense against accidental public bucket exposure. It applies at three levels (organization, account, bucket) with an override hierarchy: most restrictive wins (object ACLs sit beneath all three).
Four settings, each toggle-able:
BlockPublicAcls: prevents new public ACLs from being applied. Existing public ACLs remain (unless setting #2 is also on).IgnorePublicAcls: ignores all public ACLs (existing or new). The bucket / object isn't removed; ACLs are just not honored.BlockPublicPolicy: prevents new bucket policies that grant public access.RestrictPublicBuckets: even if a bucket policy somehow grants public access, only AWS principals + AWS services can access; anonymous internet requests are blocked.
Level hierarchy (most restrictive wins):
- Organization level (S3 Block Public Access at the Organizations level): applies to every member account. Cannot be overridden by member account admins.
- Account level: per-account setting. Overrides bucket-level if more restrictive.
- Bucket level: per-bucket setting. Applies to that bucket only.
- Object level: individual object ACLs (still subject to all the above).
Trap the exam loves: a bucket policy that allows s3:GetObject from "Principal": "*" and BPA is on at the account level. Outcome: BPA wins; bucket is not public. The policy is evaluated but the public-access result is suppressed by BPA. This is correct: BPA was designed exactly to override misconfigurations.
Organization-wide enforcement pattern:
To enforce 'no S3 bucket can ever be public anywhere in our Organization':
- AWS Organizations → S3 BPA at root level → all four settings enabled.
- Optional SCP at root denying
s3:PutPublicAccessBlockso member account admins can't disable BPA. - AWS Config rule
s3-bucket-public-access-prohibitedto detect any drift.
When to disable BPA: only for intentional public static-website hosting. Even then, prefer CloudFront in front of a private bucket (with Origin Access Control) to expose content while keeping the bucket itself private.
SCPs vs BPA: SCPs can deny S3 actions (PutBucketPolicy, PutObjectAcl) but cannot inspect bucket policy content. BPA inspects content: it's the only way to enforce 'no public exposure' regardless of how a bucket policy is written. The exam answer for organizational guarantee is BPA at the org level, not SCP. Hence step 1 above is BPA; the SCP merely protects the setting.
Macie job tuning: managed identifiers vs custom regex, cost-control patterns
Amazon Macie[14] scans S3 buckets for PII, PHI, financial data, and credentials. It's S3-only. No other data sources. Cost is per-GB scanned + per-object analyzed; petabyte-scale buckets are expensive to scan fully.
Two finding types:
- Policy findings — public buckets, unencrypted buckets, ACL grants to anonymous. Discovered continuously, free.
- Sensitive data findings — actual PII detected in objects. Requires running a discovery job; costs per GB.
Managed identifiers (built-in regex + dictionary patterns):
- PII: Social Security numbers (US), passport numbers (many countries), driver's licenses, credit card numbers, IBANs, bank account numbers.
- PHI: medical record numbers, NPI, diagnosis codes.
- Credentials: AWS access keys, OAuth tokens, SSH keys, X.509 private keys.
- Country-specific: tax IDs, national IDs for ~30+ countries.
Managed identifiers are accurate (high precision, low false-positive rate). Use them by default.
Custom data identifiers — your own regex + keywords:
Regex: ^[A-Z]{2}\d{6}$ (e.g. employee ID format)
Keywords: ["employee", "emp_id"]
Maximum match distance: 50 characters
Ignore words: ["test", "sample"]
Use for: company-specific identifiers (employee IDs, internal codes), regulated data formats unique to your domain.
Cost-control patterns:
- Bucket inclusions / exclusions: scope a job to specific buckets only. Don't scan obvious-non-PII buckets (build artifacts, log archives older than 90 days).
- Object filtering: include only specific file extensions / prefixes / tags. E.g. scan only
s3://uploads/prefix where users put data, nots3://thumbnails/. - Sampling depth: Macie samples a percentage of objects rather than scanning every one. Set sampling depth to balance cost vs coverage.
- One-time vs scheduled jobs: full one-time scan after migration; then monthly incremental scans on critical buckets.
- Findings aggregation: Macie publishes findings directly to Security Hub[28] (native integration) and to EventBridge as a separate destination. Security Hub for cross-account visibility, EventBridge for automated response.
Multi-account deployment:
- Enable Macie at the Organizations level via the delegated administrator account.
- Designate one account (typically security tooling account) as the Macie administrator; it gets visibility into all member accounts' findings.
Common exam scenario:
'After migration, audit S3 buckets across all accounts for PII without disrupting workloads' → Macie via Organizations + delegated administrator + one-time discovery job + scope to migration buckets + custom data identifier for company-specific employee IDs.
CloudHSM cluster setup: cross-AZ, client SDK, key replication
AWS CloudHSM[8] provides dedicated, FIPS 140-2 Level 3 validated Hardware Security Modules in your VPC. You control the keys entirely; AWS provides the hardware. Decision frame up front: KMS is the default. CloudHSM only when the requirement names dedicated hardware or full key custody: 'must store keys in a dedicated HSM', FedRAMP Moderate/High with HSM mandate, or government/defense.
Cluster topology:
A CloudHSM cluster = 1+ HSM instances in your VPC. Each HSM is ~$1.45/hr = ~$1 000/month. For production HA, run 2+ HSMs in different AZs (otherwise AZ failure = key loss).
Keys are replicated synchronously across HSMs in the same cluster. Operations are load-balanced.
Setup steps (mechanical, but the exam may test the sequence — the diagram below walks the same five steps in order):
- Create cluster — choose VPC + 2+ subnets in different AZs.
- Initialize cluster — generate the cluster's CA certificate; sign it.
- Activate HSMs — set the Crypto Officer (CO) credentials. CO administrates the HSM; can't perform crypto operations (separation of duties).
- Create Crypto Users (CU) — application identities that do encrypt/decrypt/sign/verify. Each CU has its own keys.
- Connect clients — install the CloudHSM Client SDK on EC2 instances, configure cluster endpoint, authenticate as a CU.
Client SDK options:
- PKCS #11 — standard cryptographic API; works with most languages.
- JCE (Java Cryptography Extension) — Java apps.
- CNG (Cryptography Next Generation) — Windows / .NET.
- OpenSSL Dynamic Engine — for apps using OpenSSL APIs.
Common integration patterns:
- TLS offload: nginx/Apache uses CloudHSM via OpenSSL engine to sign TLS handshakes. Private key never leaves the HSM.
- Code signing: build pipeline signs releases with a CloudHSM-stored signing key. Compliance-required for signed software.
- Database encryption: Oracle TDE / SQL Server TDE encrypts at the database engine layer using CloudHSM-stored keys.
- Custom AWS KMS Custom Key Store: bridge CloudHSM + KMS — KMS API on top of HSM-stored keys. Lets AWS services (S3, EBS) use HSM-backed keys transparently while you retain key custody.
Backup:
CloudHSM auto-backs up the cluster to S3 (encrypted, AWS-managed). Backups are tied to your cluster's CA certificate — restoring requires the original CA.
vs KMS:
- KMS = multi-tenant HSMs under the hood; AWS controls the hardware. Its HSMs are validated at FIPS 140-3 Security Level 3[29] (Level 3 since May 2023) — the FIPS level no longer separates the two services. Cheaper, simpler.
- CloudHSM = single-tenant hardware in YOUR VPC; you control the keys entirely. Required only when the spec explicitly mandates dedicated hardware or HSM key custody.
Exam triggers for CloudHSM:
- 'Dedicated hardware' / 'single-tenant HSM' → CloudHSM.
- 'Customer must control key material entirely' (full key custody) → CloudHSM (or imported key material in KMS, depending on context).
- A bare 'FIPS 140-2 Level 3' mention is not a CloudHSM cue on its own — KMS HSMs are Level 3 validated too; look for single-tenancy or key custody in the scenario.
- Otherwise → KMS is the default.
S3 server-side encryption options
| Type | Key custody | Per-request cost | Auditable in CloudTrail | Use when |
|---|---|---|---|---|
| SSE-S3 | AWS-managed | No | No | Default; non-sensitive data |
| SSE-KMS (AWS-managed key) | AWS-managed | Yes (KMS request) | Yes | Compliance audit needs |
| SSE-KMS (customer-managed key) | You manage policy + rotation | Yes | Yes | Multi-tenant or fine-grained access |
| SSE-C | You provide key per request | No KMS cost | No | Rare; specific compliance needs |
| DSSE-KMS | AWS + customer | Yes (2x KMS) | Yes | Defense-in-depth dual layer (FedRAMP High) |
Decision tree
Sharp facts the exam loves — give these one last read before exam day.
Cheat sheet
Sharp facts the exam loves — scan these before test day.
- Encrypt compliance data both at rest and in transit
Compliance data needs protection on both legs of its life (audits like HIPAA, PCI, and GDPR require it), so encrypt at rest with SSE/
KMSand in transit with TLS, because neither covers the other. S3 already applies SSE-S3 by default since Jan 2023, so the at-rest leg is mostly handled, but in transit is on you: enforce it with a bucket policy that denies any request whereaws:SecureTransportisfalse, forcing every connection onto TLS.Trap Assuming S3's default SSE-S3 also protects data in transit: at-rest encryption says nothing about TLS; enforce the transit leg separately by denying
aws:SecureTransport=false.3 questions test this
- A company stores sensitive customer data in an S3 bucket and must ensure that all requests to the bucket use encrypted connections. The…
- A company stores sensitive financial data in an S3 bucket that must only be accessed through HTTPS connections. The security team has…
- A company requires that all data transferred to and from an S3 bucket must be encrypted in transit using TLS. The bucket stores healthcare…
- Pick a KMS key type by control and cost, lowest first
Pick the cheapest KMS key tier that still meets your control requirement, climbing only as far as you need. AWS-owned keys are free but give no visibility; AWS-managed keys are free and add a CloudTrail audit trail; customer-managed keys cost ~$1/key/month plus per-request but unlock your own key policy, cross-account sharing, and rotation control; and
CloudHSMis the most expensive, giving a dedicated single-tenant FIPS 140-2 Level 3 module. The control you require pushes you up a tier, not a default reflex.Trap Reaching for
CloudHSMfor routine encryption: it's only worth it when you genuinely need single-tenant FIPS 140-2 Level 3, otherwise it just costs more than a customer-managed key.5 questions test this
- A healthcare company requires that encryption keys used for patient data be stored in single-tenant hardware security modules (HSMs) to…
- A healthcare company must meet regulatory compliance requirements that mandate full control over encryption keys used to protect patient…
- A financial services company has regulatory requirements mandating that encryption keys must be stored in hardware security modules (HSMs)…
- A company needs to share an encrypted Amazon RDS snapshot with a partner organization in a different AWS account. The RDS database is…
- A company encrypts its Amazon EBS volumes at rest. The operations team needs to share an encrypted EBS snapshot with a separate AWS account…
- Control S3 access at the bucket level, not per object
Govern an S3 bucket with account- and bucket-level controls (Block Public Access plus default encryption) so protection applies uniformly and can't be undone object by object. Bucket-wide controls are the right altitude because they're auditable and don't drift, whereas per-object ACLs and policies multiply with object count, so they don't scale and are painful to verify across a large bucket.
Trap Securing a bucket with per-object ACLs: they're easy to misconfigure and impossible to audit at scale, which is exactly why Block Public Access exists to override them.
3 questions test this
- A security team discovers that developers have inadvertently made several S3 buckets publicly accessible through bucket policies and ACLs.…
- A company recently experienced a security incident where an S3 bucket was accidentally made public by a developer. The company wants to…
- A company recently migrated to AWS and created several new S3 buckets. The security team wants to ensure that all buckets in the account…
- Use Macie to find and classify sensitive data in S3
Macieis the managed service for discovering and classifying sensitive data (PII, PHI, financial data, credentials) in S3, using AWS-managed identifiers plus your own custom regex and routing findings throughEventBridgefor auto-remediation. It works on data already stored, scanning asynchronously, and runs ~$1/GB scanned, which is why you point it at the buckets that matter rather than sweeping the whole org blindly.Trap Expecting
Macieto be a real-time inline guard on uploads: it's an asynchronous discovery and classification job over data at rest, not an upload-path filter.12 questions test this
- A company enables Amazon Macie to perform automated sensitive data discovery and wants to implement an automated workflow that responds to…
- A company stores customer data in Amazon S3 buckets across multiple AWS accounts. The security team must discover and classify sensitive…
- A healthcare organization is using Amazon Macie to scan S3 buckets for sensitive patient data. The organization has specific internal…
- A healthcare company stores millions of objects in Amazon S3, and some objects contain personally identifiable information (PII) and…
- A company wants to implement automated remediation when Amazon Macie detects high-severity sensitive data findings in S3 buckets. The…
- A retail company is building an analytics data lake on Amazon S3 that ingests data from many sources. The security team needs a fully…
- A healthcare organization needs to detect proprietary patient record identifiers stored in Amazon S3 buckets. These identifiers follow a…
- A healthcare organization needs to configure Amazon Macie to detect custom patient identifier formats that are specific to their internal…
- A healthcare company needs to ensure compliance with HIPAA regulations by identifying protected health information (PHI) stored in Amazon…
- A company uses Amazon Macie to discover sensitive data in their S3 buckets. The security team needs to detect employee ID numbers that…
- A company has thousands of Amazon S3 buckets. The security team wants to identify which buckets are publicly accessible and also contain…
- A healthcare company stores patient records in Amazon S3 buckets across multiple AWS accounts managed by AWS Organizations. The security…
- New S3 buckets have been SSE-S3 encrypted by default since Jan 2023
Every new S3 bucket gets SSE-S3 automatically[1] since January 2023 with no action from you, and you can upgrade a bucket to SSE-KMS whenever you want tighter key control. The change is forward-looking, so buckets and objects created before 2023 may still be unencrypted: find them with the AWS Config rule
s3-bucket-server-side-encryption-enabledrather than assuming the default reached back in time.Trap Assuming the Jan-2023 default went back and encrypted old objects: it only applies to new buckets and objects, so legacy data stays unencrypted until you audit it.
- KMS automatic rotation is yearly and opt-in for customer-managed keys
Customer-managed keys rotate the underlying key material automatically once a year[18] (the 365-day default, configurable to a shorter custom period via
RotationPeriodInDays) but only after you opt in with theEnableKeyRotationAPI. It's off until you ask for it. AWS-managed keys already rotate yearly with nothing to configure. The exception is imported key material: KMS can't regenerate material it didn't create, so it never auto-rotates and you rotate it by re-importing.Trap Turning on
EnableKeyRotationand assuming imported key material rotates too. It's excluded, so it stays static until you manually re-import.- KMS deletion is never instant: a 7–30 day window you can cancel
Deleting a KMS key is never instant:
ScheduleKeyDeletion[19] starts a mandatory 7–30 day waiting period, and you canCancelKeyDeletionanytime inside it. The delay is deliberate: destroying a key makes everything it encrypted permanently unreadable, so the window is your chance to catch a mistake before it's irreversible. CloudHSM is the contrast: it lets you destroy a key immediately because you own the HSM.Trap Counting on a deleted KMS key being recoverable like a soft-deleted resource: once the window elapses it's gone for good, so
CancelKeyDeletionduring the window is your only safety net.- Macie cost scales with data, so scan once then target critical buckets
Macie charges ~$1/GB scanned plus per-object analysis, so the bill tracks how much data you point it at: steep on petabyte-scale buckets, and rescanning unchanged data adds cost without adding signal. The cost-aware pattern is one full discovery pass after a migration, then scheduled monthly scans limited to critical buckets, using
excludes[15] filters to skip large prefixes you already know are non-sensitive.Trap Running continuous org-wide Macie discovery to be thorough: rescanning the same data over and over just multiplies the per-GB cost for no new signal, so scope and schedule it instead.
3 questions test this
- A security team is configuring Amazon Macie's automated sensitive data discovery feature. The team wants to exclude S3 buckets that store…
- A company uses Amazon Macie to perform automated sensitive data discovery across their Amazon S3 environment. The company has S3 buckets…
- A solutions architect is configuring Amazon Macie to discover sensitive data across hundreds of S3 buckets containing petabytes of data.…
- Give a short-lived workload a key with a KMS grant, not a policy edit
When a short-lived workload needs key access, issue a grant[20], a temporary, programmatic permission you create with
kms:CreateGrantand retire when done, because a grant is scoped to specific operations and goes away cleanly. Editing the key policy is permanent and shared: it changes who can use the key until someone edits it back, so it's wrong for ephemeral consumers. This is exactly the mechanism AWS services like RDS encryption use, creating grants for you behind the scenes.Trap Editing the key policy for every ephemeral consumer: it permanently bloats the policy and has to be revoked by hand, whereas a grant is scoped and retirable for exactly this case.
3 questions test this
- A company uses Amazon S3 to store sensitive financial data. The security team requires that all data be encrypted using AWS KMS customer…
- A company is deploying an application that uses Amazon RDS with encryption enabled using an AWS KMS customer managed key. The application…
- A company uses a customer managed AWS KMS key to encrypt data at rest. A third-party batch processing application that runs under a…
- Lock a KMS key to one service with the kms:ViaService condition
The
kms:ViaService[21] condition in a key policy (e.g.Condition: { StringEquals: { kms:ViaService: "s3.us-east-1.amazonaws.com" } }) restricts a key so it can be used only when the request comes through that one service in that one Region. It checks which service is making the call on a principal's behalf, defending against stolen credentials being replayed against the key through some other service: a containment control that complements, not replaces, the permissions on the principal itself.Trap Assuming
kms:ViaServicerestricts which principal can use the key: it constrains the calling service and Region, not the identity, so it pairs with principal-level permissions rather than replacing them.4 questions test this
- A financial services company is implementing encryption at rest for sensitive data stored in Amazon S3. The security team requires that a…
- A company is deploying an application that uses Amazon RDS with encryption enabled using an AWS KMS customer managed key. The application…
- A company uses AWS KMS customer managed keys to encrypt data across multiple AWS services including Amazon S3, Amazon EBS, and Amazon RDS.…
- A company uses AWS KMS customer managed keys to encrypt Amazon EBS volumes. The security team wants to ensure that only the Amazon EC2…
- Use S3 Object Lock for immutable retention. Compliance mode blocks even root
S3 Object Lock provides WORM (write-once-read-many) immutability in two modes: Governance, where a privileged admin can still override the lock, and Compliance, where nobody (not even the root user) can shorten retention or delete during the window. Compliance satisfies records rules like SEC 17a-4(f), FINRA, and CFTC[22] precisely because no one can tamper with it. You apply it per object or as a bucket default retention policy, and versioning must be enabled first.
Trap Using Governance mode for a regulatory WORM requirement: a privileged admin can override it, so only Compliance mode satisfies SEC 17a-4(f)-style immutability.
- An ACM cert for CloudFront has to live in us-east-1
An ACM certificate attached to CloudFront must be requested or imported in US East (N. Virginia) / us-east-1, regardless of where your origin or users sit, because CloudFront is a global service that distributes that single us-east-1 certificate out to every edge location. A cert created in any other Region won't appear in the CloudFront console for you to select.
Trap Requesting the ACM cert in the origin's Region where your ALB or S3 bucket lives: CloudFront only sees certificates in us-east-1, so it'll never appear for you to attach.
4 questions test this
- A solutions architect is configuring an Amazon CloudFront distribution to serve content for a web application using a custom domain name.…
- A company hosts a website using Amazon CloudFront with an Application Load Balancer as the origin. The company wants to use a custom domain…
- A company is deploying a new web application that uses Amazon CloudFront as the content delivery network. The application requires HTTPS…
- A company is deploying a web application that uses Amazon CloudFront with a custom domain name. The company has requested an SSL/TLS…
- For cross-account S3 uploads, set Object Ownership to Bucket owner enforced
Setting S3 Object Ownership to Bucket owner enforced makes the bucket owner automatically own every object (even ones uploaded from another account) while ACLs are disabled entirely, so access is governed purely by bucket and IAM policies. That's the clean fix for cross-account uploads, where by default the uploading account retains ownership of its objects and leaves the bucket owner unable to read them. It's now the recommended default for new buckets for exactly this reason.
Trap Granting the bucket owner an ACL on each cross-account object instead: that's brittle per-object work, whereas Bucket owner enforced transfers ownership automatically and removes ACLs entirely.
10 questions test this
- A company has enabled S3 Object Ownership with the Bucket owner enforced setting on a bucket used for storing application logs. Partner…
- A company recently migrated to AWS and is using Amazon S3 to store application data. The company's legacy application uploads objects to S3…
- A company has an existing S3 bucket that was created before April 2023 and uses ACLs to grant read access to several external AWS accounts.…
- A company recently migrated to AWS and has multiple teams uploading objects to a shared S3 bucket from different AWS accounts within the…
- A company has an S3 bucket that receives uploads from multiple AWS accounts within the same organization. The company requires that the…
- A company has an S3 bucket that receives objects uploaded by an external partner from a different AWS account. The company wants to ensure…
- A company has an S3 bucket where multiple AWS accounts within the same AWS Organization upload data files. The bucket owner wants to ensure…
- A company in Account A wants to share an Amazon S3 bucket with users in Account B. The company uses the default S3 Object Ownership setting…
- A company allows a partner organization in a different AWS account to upload files to an S3 bucket. The company has noticed that after…
- A company has an S3 bucket that receives data uploads from multiple AWS accounts within its organization. The company wants to simplify…
- Org-level S3 Block Public Access overrides account and bucket settings
S3 Block Public Access enforced at the AWS Organizations root or OU propagates to every member account, including ones that join later, and overrides account- and bucket-level settings so a local admin can't switch it off. That central enforcement removes accidental public exposure as an option across the whole org. If one account legitimately needs a public bucket, the carve-out is made at the org by excluding that account, not by a local toggle.
Trap Telling a member-account admin to just toggle Block Public Access off locally: the org-level setting wins, so the carve-out has to happen at the organization, not the account.
7 questions test this
- A company wants to ensure that all S3 buckets across their organization cannot be made publicly accessible, even if individual bucket…
- A company has multiple AWS accounts within an AWS Organization. The security team wants to ensure that no S3 bucket in any member account…
- A security audit reveals that an S3 bucket has both a bucket policy that allows public read access and S3 Block Public Access enabled at…
- A company has enabled S3 Block Public Access at the organization level through AWS Organizations. A developer in one of the member accounts…
- A company wants to ensure that no S3 buckets across all AWS accounts in its organization can be made publicly accessible. The security team…
- A company uses Amazon S3 to store sensitive data. The company's security policy requires that all S3 buckets must never allow public access…
- A solutions architect is configuring security controls for S3 buckets across multiple AWS accounts within an AWS Organization. The…
- On high-traffic SSE-KMS buckets, enable S3 Bucket Keys to cut KMS costs ~99%
On a high-traffic SSE-KMS bucket, enable S3 Bucket Keys: KMS hands S3 a short-lived bucket-level key from which S3 derives the per-object data keys itself, collapsing many per-object KMS calls into far fewer, cutting KMS request charges by up to ~99%. There's no security trade-off, because every object is still encrypted under your customer managed key; you've only changed how often S3 has to call KMS.
Trap Switching from SSE-KMS to SSE-S3 just to dodge per-request KMS charges: that throws away the customer-managed-key control, whereas Bucket Keys cut the cost while keeping the CMK.
6 questions test this
- A company stores sensitive data in an S3 bucket encrypted with SSE-KMS using a customer managed key. The bucket receives millions of PUT…
- A solutions architect needs to reduce AWS KMS costs for an Amazon S3 bucket that stores millions of objects encrypted with SSE-KMS. The…
- A solutions architect must configure default encryption for an Amazon S3 bucket using SSE-KMS with a customer managed key. The bucket will…
- A company is experiencing high AWS KMS costs due to a large volume of S3 GET and PUT requests on buckets encrypted with SSE-KMS using…
- A company is migrating workloads to AWS and plans to store data in Amazon S3 using server-side encryption with AWS KMS customer managed…
- A company uses Amazon S3 with SSE-KMS encryption for its data lake. The data lake contains billions of objects that are frequently accessed…
- Cross-account KMS access needs both a key policy and an IAM policy
Cross-account use of a customer managed KMS key takes consent from both sides: the key policy in the owning account must grant the external account or principal, and an IAM policy in the external account must allow those principals to use that specific key ARN. The key policy decides who may have access and the IAM policy decides who actually does. Both have to line up, so neither alone authorizes the call.
Trap Setting only the key policy as you would for same-account access. Cross-account principals also need an explicit IAM allow on the key ARN, or the call still fails.
8 questions test this
- A company has two AWS accounts: Account A (111122223333) for production workloads and Account B (444455556666) for analytics. The analytics…
- A company is configuring cross-account access to an AWS KMS customer managed key. The key exists in Account A and must be used by an…
- A company has an S3 bucket that stores sensitive financial data encrypted with SSE-KMS using a customer managed key. A partner company in a…
- A company needs to allow an application running in Account B to decrypt data that was encrypted using a customer managed key stored in…
- A company has multiple AWS accounts managed through AWS Organizations. A central security account contains customer managed AWS KMS keys…
- A company uses AWS KMS customer managed keys to encrypt data stored in Amazon S3 buckets. A development team in a different AWS account…
- A company uses Amazon EBS volumes encrypted with customer managed KMS keys for its production EC2 instances. The company wants to share…
- A company manages secrets in a centralized AWS account and needs to share database credentials with applications running in multiple…
- Changing default encryption doesn't touch existing objects: re-encrypt with S3 Batch Operations
Updating a bucket's default encryption is forward-looking only: it applies to newly uploaded objects while everything already stored keeps its original encryption, so flipping the setting alone never re-keys old data. To re-encrypt objects already in the bucket (even billions) under a new SSE-KMS customer managed key, run S3 Batch Operations with the Copy operation, copying objects back into the same bucket with the new encryption, which rewrites each object under the new key.
Trap Assuming flipping the bucket's default encryption re-encrypts what's already stored: it's forward-looking only, so old objects stay on the old key until you copy them.
4 questions test this
- A company has an existing S3 bucket containing millions of objects encrypted with SSE-S3. Due to new compliance requirements, the company…
- A company changed its S3 bucket default encryption from SSE-S3 to SSE-KMS with a customer managed key for compliance requirements. The…
- A company recently configured an S3 bucket to use SSE-KMS with a customer managed key as the default encryption. The bucket already…
- A company is migrating an existing S3 bucket from SSE-S3 to SSE-KMS encryption with a customer managed key to meet new compliance…
- KMS keys are Regional, so cross-Region replicas need a key in the target Region
A KMS key is a Regional resource and can't be invoked from another Region, so any cross-Region encrypted copy needs its own key in the destination Region. An encrypted cross-Region RDS read replica must be given a customer managed (or AWS managed) key that exists in the target Region, and an S3 bucket can only use a same-Region KMS key for SSE-KMS. The encryption key always has to be local to the data.
Trap Pointing the destination Region at the source key's ARN: KMS won't resolve it across Regions, so the replica creation fails until a key exists locally.
4 questions test this
- A solutions architect is implementing encryption at rest for Amazon RDS databases in a multi-Region disaster recovery architecture. The…
- A company operates an Amazon RDS for MySQL database in the us-east-1 Region encrypted with a customer managed AWS KMS key. The company…
- A company has configured an Amazon S3 bucket in the us-east-1 Region with SSE-KMS using a customer managed key. A solutions architect…
- A company is setting up an Amazon RDS for MySQL database with a read replica in a different AWS Region for disaster recovery. The primary…
- Run org-wide Macie from a delegated security account, not the management account
In AWS Organizations the management account designates a dedicated security account as the Macie delegated administrator, and that account is where you enable Macie across members, run org-wide discovery jobs, and aggregate findings centrally. Delegating this out of the management account keeps day-to-day security operations (and their blast radius) away from the most privileged account in the org. Automated sensitive data discovery then samples objects to score each bucket's sensitivity cost-efficiently.
Trap Operating Macie straight from the Organizations management account: AWS guidance is to delegate to a separate security account to limit management-account exposure and blast radius.
6 questions test this
- A solutions architect is setting up Amazon Macie for a large enterprise with over 200 AWS accounts managed through AWS Organizations. The…
- A company stores customer data in Amazon S3 buckets across multiple AWS accounts. The security team must discover and classify sensitive…
- A company stores customer data in Amazon S3 buckets across multiple AWS accounts in an AWS Organizations structure. The security team needs…
- A media company has enabled Amazon Macie to monitor sensitive data across their Amazon S3 environment. They want to continuously evaluate…
- A company stores customer data across hundreds of Amazon S3 buckets in multiple AWS accounts managed by AWS Organizations. The security…
- A company is deploying Amazon Macie across an AWS Organizations structure with 50 member accounts. The security operations team in the…
- For CloudFront HTTPS with a custom cert, use free SNI SSL, not Dedicated IP
For CloudFront HTTPS with your custom certificate, use SNI (Server Name Indication) SSL, which lets one IP present the right cert per hostname and carries no extra monthly charge. Every browser released after 2010 supports it, so it's the right default for essentially all modern traffic. Dedicated IP SSL exists only for the rare legacy client that can't do SNI, and it adds a per-distribution monthly fee, so you pick it for compatibility, never for robustness.
Trap Picking Dedicated IP SSL to look more robust: it just adds per-distribution monthly cost, whereas SNI is the default and works for every modern browser.
6 questions test this
- A company is configuring a CloudFront distribution with a custom domain name and needs to enable HTTPS using an ACM certificate. The…
- A company is configuring Amazon CloudFront with a custom SSL/TLS certificate for alternate domain names. The company wants to minimize…
- A media company operates a CloudFront distribution serving video content over HTTPS. The company wants to enforce TLS 1.2 as the minimum…
- A company has an Amazon CloudFront distribution with a custom domain name and an ACM certificate. The company wants to enforce HTTPS…
- A solutions architect is configuring an Amazon CloudFront distribution with a custom SSL/TLS certificate from AWS Certificate Manager…
- A company is configuring Amazon CloudFront to use a custom domain name with HTTPS. The solutions architect needs to choose between SNI…
- To encrypt CloudFront-to-origin, set Origin Protocol Policy to HTTPS Only with min TLS 1.2
To encrypt the leg between CloudFront and a custom origin, set the Origin Protocol Policy to HTTPS Only with a minimum origin SSL protocol of TLSv1.2, forcing every origin fetch onto modern TLS. Once HTTPS Only is on, CloudFront validates the origin's certificate and returns HTTP 502 (Bad Gateway) if it's self-signed or otherwise untrusted, so the origin must present a certificate signed by a trusted CA for the connection to succeed.
Trap Leaving a self-signed cert on the origin under HTTPS Only and then blaming the 502 on CloudFront. CloudFront refuses untrusted origin certs, so it needs a CA-signed certificate.
3 questions test this
- A company uses Amazon CloudFront to deliver content from an Application Load Balancer origin. The security team requires that all…
- A company wants to ensure encrypted communication between Amazon CloudFront and its custom origin server running on Amazon EC2 instances…
- A company is deploying an Amazon CloudFront distribution with a custom origin server running on Amazon EC2. The company needs to enforce…
- SSE-KMS needs kms:GenerateDataKey to upload and kms:Decrypt to download
SSE-KMS splits the two directions across two permissions: uploading makes S3 ask KMS to generate a data key, needing
kms:GenerateDataKey, while downloading makes S3 decrypt that data key, needingkms:Decrypt. An app that both reads and writes must hold both, because a policy missing either one fails only the matching S3 operation with AccessDenied while the other keeps working, which is what makes the gap confusing to diagnose.Trap Granting only
kms:Decryptjust because the app reads objects: uploads will then fail with AccessDenied, since writing SSE-KMS objects requireskms:GenerateDataKey.5 questions test this
- A company needs to implement server-side encryption for sensitive data stored in Amazon S3 using AWS KMS customer managed keys. Application…
- A company stores sensitive customer data in an Amazon S3 bucket and uses server-side encryption with AWS KMS customer managed keys…
- A company stores sensitive financial data in Amazon S3 and requires strict control over encryption keys. The security team wants to use…
- A solutions architect is configuring an IAM role that will be used by an application to read and write objects to an S3 bucket encrypted…
- A company's application uploads large files to an Amazon S3 bucket using multipart upload. The bucket is configured with default encryption…
- Cross-account secret access needs a secret resource policy and the KMS key policy
Cross-account reads of a Secrets Manager secret require two grants together: a resource-based policy on the secret allowing
secretsmanager:GetSecretValue, and a policy on the encrypting KMS key allowingkms:Decrypt, because retrieving the secret means decrypting it. This is why the defaultaws/secretsmanagerkey doesn't work cross-account: its key policy is immutable and can't be edited to admit the other account, so cross-account access forces you onto a customer managed key.Trap Encrypting the secret with the default
aws/secretsmanagerkey and expecting cross-account access: its key policy can't be edited to grant the other account, so you have to use a customer managed key.4 questions test this
- A financial services company has a central security account that stores database credentials for Amazon RDS instances running in multiple…
- A security team manages secrets centrally in one AWS account. Applications running in several other AWS accounts must retrieve a shared…
- A company manages secrets in a centralized AWS account and needs to share database credentials with applications running in multiple…
- Applications running in several different AWS accounts all need to use the same set of database credentials. A solutions architect must…
- Scope a rotation Lambda's KMS decrypt to one secret with kms:EncryptionContext:SecretARN
A rotation Lambda for a secret encrypted with a customer managed key needs
kms:Decrypton that key, but granting it plainly lets it decrypt every secret sharing the key. Add a condition onkms:EncryptionContext:SecretARNand the decrypt permission is confined to the one secret it's meant to rotate: least privilege in action, since the encryption context is bound to the secret's ARN and KMS only allows the decrypt when that context matches.Trap Granting the rotation function plain
kms:Decrypton the shared key: it can then decrypt every secret encrypted with that key, so the SecretARN encryption-context condition is what confines it.- Restrict what flows through a VPC endpoint with an endpoint policy
An Interface or Gateway endpoint can carry its own endpoint policy[23] that limits which API actions and resources may pass through it, for example an S3 Gateway endpoint scoped to permit
s3:GetObjecton your buckets only and deny everything else routed through it. It's a filter on the path, not a grant of access, so it's an extra constraint evaluated alongside the principal's IAM and the bucket policy rather than replacing them.Trap Assuming an endpoint policy grants access on its own: it only filters what the endpoint permits, so the principal still needs IAM and bucket permissions, and the two are evaluated together.
Also tested in
References
- Amazon S3 default encryption now SSE-S3 (AWS News Blog, Jan 2023) Blog
- Specifying server-side encryption with AWS KMS (SSE-KMS)
- Protecting data using server-side encryption with customer-provided keys (SSE-C)
- Using dual-layer server-side encryption with AWS KMS keys (DSSE-KMS)
- AWS Certificate Manager User Guide
- AWS KMS concepts (key types)
- AWS KMS pricing
- AWS CloudHSM introduction
- Getting started with AWS CloudHSM
- AWS KMS multi-region keys overview
- Blocking public access to S3 storage
- Setting default server-side encryption for an S3 bucket
- Controlling ownership of objects (Object Ownership)
- What is Amazon Macie
- Macie sensitive-data discovery jobs
- What is AWS Security Hub
- Amazon Macie pricing
- Rotating AWS KMS keys
- Deleting AWS KMS keys
- Using grants in AWS KMS
- AWS KMS policy conditions (kms:ViaService)
- Locking S3 objects (Object Lock)
- https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-access.html
- https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-default.html
- https://docs.aws.amazon.com/acm/latest/userguide/managed-renewal.html
- https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html
- https://aws.amazon.com/private-ca/pricing/
- https://docs.aws.amazon.com/macie/latest/user/securityhub-integration.html
- https://aws.amazon.com/kms/faqs/