# how to do a basic cloud security posture audit

## TL;DR

Inventory everything first, then check the classics in order: IAM (old keys, wildcard admins), public storage, security groups open to the internet, missing audit logging, unencrypted volumes, and root without MFA. Most cloud breaches come from this list, not from exotic attacks. Tools like Prowler or Scout Suite automate the checks; your judgment handles the rest.

```text
how to do a basic cloud security posture audit
```

## Use this when

- You inherited a cloud account and need a first-pass review
- Compliance asks for evidence of periodic security reviews
- You want a repeatable quarterly audit routine
- A misconfiguration scare makes you check everything

## Not for this skill when

- You are selecting a continuous CSPM product (evaluation, not an audit)
- You need a penetration test (this is config review, not exploitation)
- The goal is cost optimization (different audit entirely)

## Steps

### 1. Inventory every region and account in scope

List accounts, regions with resources, and the rough shape of each. You cant audit what you dont know exists.

```bash
aws account list-regions --query "Regions[].RegionName" --output text | tr ' ' '\n' | head -20
```

Expected: the region list. For each active region, note which services are in use; an audit that covers only one region misses everything deployed elsewhere. Multi-account setups repeat every step per account.

### 2. Audit IAM: old keys, wildcard policies, dormant users

Generate the credential report and look for access keys older than 90 days, users with no MFA, and wildcard admin policies.

```bash
aws iam generate-credential-report && sleep 10 && aws iam get-credential-report --query Content --output text | base64 -d | head -5
```

Expected: a CSV of users with key ages and MFA status. Flag keys over 90 days, users with console access but no MFA, and anyone who hasnt logged in for 6 months; dormant accounts get disabled, not just noted.

### 3. Check storage and security groups for public exposure

Find buckets and security groups open to the world. This is the step that catches the headline-making misconfigurations.

```bash
aws ec2 describe-security-groups --query "SecurityGroups[].{Group:GroupName, Id:GroupId, Ingress:IpPermissions[].{Port:FromPort, CIDRs:IpRanges[].CidrIp}}" --output json | python3 -c "import json,sys; d=json.load(sys.stdin); [print(g['Group'], g['Id'], p['Port'], p['CIDRs']) for g in d for p in g['Ingress'] for c in [p] if any(x.endswith('/0') for x in p['CIDRs'])]"
```

Expected: lines naming groups with ingress open to the whole internet (any CIDR range ending in /0). Check whether each open port is intentional (public web on 443 is fine; a database on 5432 is not). Pair with the S3 audit skill for storage.

### 4. Verify audit logging and encryption baselines

Confirm CloudTrail logs to a locked-down bucket in every region, and check that volumes, databases, and buckets use encryption at rest.

```bash
aws cloudtrail describe-trails --query "trailList[].{Name:Name, MultiRegion:IsMultiRegionTrail, Logging:IsLogging}" --output table
```

Expected: at least one multi-region trail with logging enabled. Then spot-check encryption: `aws ec2 describe-volumes --query "Volumes[?Encrypted==\`false\`].VolumeId"` should come back empty.

### 5. Run an automated scanner and triage the output

Prowler (AWS) or Scout Suite (multi-cloud) run hundreds of these checks at once. Run one, then triage: fix the criticals this week, schedule the mediums, and document accepted risks with expiry dates.

```bash
prowler aws --severity critical --output-formats csv -M csv
```

Expected: a CSV of critical findings. Dont try to fix everything in one pass; the value is the prioritized list plus the repeatability. Save the report; next quarter you diff against it.

### Variant: aws security audit checklist

The AWS-specific short list: root MFA on, no root access keys, CloudTrail multi-region, S3 Block Public Access account-wide, EBS encryption by default, security groups reviewed, IAM Access Analyzer findings cleared. Run it quarterly.

### Variant: cloud misconfiguration scan tools

Prowler for AWS depth, Scout Suite for multi-cloud breadth, and your cloud's native advisor (Security Hub, Security Command Center) for continuous monitoring between audits. The audit is the point-in-time deep look; the native tools are the always-on shallow one.

### Variant: inherited aws account first 10 checks

Do steps 2 through 4 plus: who has root, what the billing alerts say (surprise spend is often a breach indicator), whether GuardDuty is on, and whether there are IAM users that should be SSO roles. Then schedule the full audit.

## Why this happens

Cloud consoles make powerful things one click away: public buckets, open security groups, admin policies. Defaults vary by service and era, teams grow faster than their guardrails, and nobody deletes the temporary rule from two years ago. Posture audits exist because cloud config drifts toward permissive the way unattended gardens drift toward weeds.

## Edge cases and pitfalls

- Audit vs live changes: run read-only; an audit that modifies config mid-review corrupts its own evidence.
- Cross-account roles: the audit account needs read access everywhere; missing roles look like clean accounts.
- Accepted risks without expiry: "we know about it" without a review date is just a finding you stopped looking at.
- Scanner noise: automated tools flag intentional designs (public website buckets); tune or allowlist with justification, dont ignore the whole report.
- One region only: resources in regions you forgot about are the ones most likely misconfigured; enumerate first, always.
- Snapshot sharing: publicly shared AMIs and snapshots leak data as surely as public buckets; check sharing settings too.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_XMHUPEPILOi66WOX0E0FwA
