This exercise turns the module's concepts into a concrete skill: taking a real account configuration and auditing it against the CIS Benchmarks. You will read a sample account's settings, check each resource against specific benchmark controls, record pass or fail with severity, and produce a prioritised remediation list. This is exactly the workflow a CSPM automates, and doing it by hand once builds the judgement to use those tools well.
The Exercise
Scenario
You are handed read-only access to a small sample AWS account for a startup. It contains a few storage buckets, some IAM users and roles, a database, and basic networking. Nobody has audited it before. Your task is to assess it against a focused subset of the CIS AWS Foundations Benchmark, identify every failing control, and hand back a prioritised list of fixes the team can action immediately.
Step 1 — Inventory the Account
You cannot audit what you cannot see, so begin by listing every resource. Enumerate the storage buckets, the IAM users and roles, the databases, and the network configuration. Record what each is and whether it is intended to be public or private. This inventory is your scope; every item on it will be checked against the relevant benchmark controls in the next step.
# Step 1 — inventory the account (read-only listing commands).
# List all S3 buckets
aws s3api list-buckets --query "Buckets[].Name"
# List IAM users and roles
aws iam list-users --query "Users[].UserName"
aws iam list-roles --query "Roles[].RoleName"
# List RDS database instances
aws rds describe-db-instances \
--query "DBInstances[].[DBInstanceIdentifier,PubliclyAccessible]"
# Describe security groups (network exposure)
aws ec2 describe-security-groups \
--query "SecurityGroups[].[GroupName,IpPermissions]"
# Record each resource and whether it SHOULD be public or private.Step 2 — Check Each Resource against CIS Controls
Now walk each inventoried resource against specific benchmark controls. For storage, check public-access blocking and encryption. For IAM, check that multi-factor authentication is enabled, that no unused credentials linger, and that policies are not over-broad. For the database, check it is not publicly accessible and is encrypted. For networking, check that no security group exposes sensitive ports to the whole internet. Mark each as pass or fail.
# Step 2 — example checks mapped to CIS controls.
# CIS: S3 buckets should block public access
aws s3api get-public-access-block --bucket customer-exports
# -> If BlockPublicAcls is false, this is a FAIL (CRITICAL).
# CIS: root/user accounts should have MFA enabled
aws iam get-account-summary --query "SummaryMap.AccountMFAEnabled"
# -> 0 means the root account lacks MFA. FAIL (CRITICAL).
# CIS: RDS instances should not be publicly accessible
# (from Step 1 output) PubliclyAccessible == true -> FAIL (HIGH).
# CIS: no security group should allow 0.0.0.0/0 to port 22 (SSH)
aws ec2 describe-security-groups \
--filters Name=ip-permission.from-port,Values=22 \
Name=ip-permission.cidr,Values=0.0.0.0/0
# -> Any result here is a FAIL (HIGH): SSH open to the world.Step 3 — Record Findings with Severity
For every failed control, record a structured finding: the resource, the control it violated, a severity, and the concrete remediation. Severity should reflect real exposure — a publicly readable bucket of customer data outranks a missing encryption flag on an empty test bucket. This structured record is the deliverable, and its quality depends on honest, exposure-based prioritisation rather than treating every failure as equally urgent.
# Step 3 — the findings you produce, ranked by real risk.
FINDINGS (highest risk first)
-----------------------------------------------------------------
1. [CRITICAL] Bucket 'customer-exports' is publicly readable.
Control: CIS 2.1.5 | Fix: enable Block Public Access, remove '*'.
2. [CRITICAL] Root account has no MFA.
Control: CIS 1.5 | Fix: enable a hardware/virtual MFA device.
3. [HIGH] RDS 'prod-db' is PubliclyAccessible = true.
Control: CIS 2.3.3 | Fix: set PubliclyAccessible false, use VPC.
4. [HIGH] Security group 'web-sg' allows 0.0.0.0/0 on port 22.
Control: CIS 5.2 | Fix: restrict SSH to a known admin CIDR.
5. [MEDIUM] IAM user 'olddev' has a key unused for 200+ days.
Control: CIS 1.12 | Fix: deactivate and delete the stale key.Step 4 — Verify and Hand Back
Finally, sanity-check your audit before delivering it. Confirm every inventoried resource was actually checked, that no critical control was skipped, and that each finding names both the violated control and a specific, actionable fix. A good audit is reproducible: another engineer following your findings should be able to remediate without needing to ask you what you meant. Deliver the ranked list as the account's remediation plan.
Warning: The most common mistake in a first audit is flattening severity — listing a stale tag next to a public customer-data bucket as if they matter equally. This buries the findings that could cause a breach under trivia and guarantees the team fixes the wrong things first. Always rank by actual exposure and data sensitivity. A finding's severity is about consequences if exploited, not about how easy it was to spot.
Extension Challenge: Repeat the same audit conceptually against Azure and GCP. Find the equivalent CIS controls for each — blocking public blob access, enforcing MFA in the identity provider, restricting network security group rules — and note how the same intent maps to different service names and commands. This cross-cloud mapping is precisely the skill Modules 3 and 5 build on, and it makes you effective in any provider rather than fluent in only one.
- Auditing an account by hand against CIS Benchmarks builds the judgement to use automated CSPM tools well and to trust or challenge their output.
- Always inventory first — you cannot audit resources you have not enumerated, so listing every bucket, identity, database, and network rule is step one.
- Map each resource to specific benchmark controls: public-access blocking and encryption for storage, MFA and least privilege for IAM, no public database.
- Record structured findings with resource, violated control, severity, and a concrete fix, so another engineer can remediate without further explanation.
- Rank findings by real exposure and data sensitivity, never flattening severity, so the public customer-data bucket is fixed before cosmetic issues.
- The same audit intent maps across AWS, Azure, and GCP through equivalent controls, a cross-cloud skill that later modules build upon directly.