Sample Report · AWS

AWS Account Audit — Sample

A worked example of auditing an AWS estate — account structure, the guardrails that should apply everywhere, identity findings ranked by reachability, and the network exposure a scan finds but a diagram does not.

Markdown. No sign-up, no email.

This is an illustrative example. The estate, findings and figures are invented to show the shape of an audit that produces a sequence of work. Copy the structure; audit your own accounts.

The audit is ordered by blast radius: what a single compromised credential or a single mistake could reach. Findings that widen blast radius come first, regardless of how they score in any framework.


AWS estate audit — August 2026#

Accounts7
Regions in use2 (plus resources found in 3 others)
MethodOrganisation configuration review, identity audit, network review, external scan
VerdictStructure is sound. Guardrails are largely absent, so the structure is not enforced.

1. Account structure#

AccountPurposeAssessment
ManagementBilling, organisation⚠️ Runs 3 workloads. Should run none.
SecurityLog archive, findings✅ Correct, and logs are genuinely centralised
Shared servicesDNS, images, CI✅ Correct
Production ACustomer application✅ Correct
Production BReporting platform✅ Correct
DevelopmentAll non-production⚠️ Shared by 4 teams; one team's mistake affects the others
SandboxExperiments⚠️ No budget alert, no expiry on resources

The management account running workloads is the structural finding. It is the account that sets every guardrail and controls the organisation; a compromise there is a compromise of everything. It should be reachable by very few people and should host nothing worth attacking.

The three workloads found there are a monitoring stack, a scheduled report and an internal tool — none of which needed to be there, all of which were placed there because it was the account that existed first.

2. Guardrails — the gap#

GuardrailStatus
Service control policiesNone. Nothing is prevented at the organisation level.
Central identity with per-account roles⚠️ Partial — 3 accounts still have local users
Organisation-wide audit trail✅ Enabled, delivered to the security account
Configuration recording⚠️ 2 accounts only
Budget alerts⚠️ 4 of 7 accounts
Region restriction❌ None — resources found in 3 unused regions

No service control policies is the finding that carries the others. Without them, every guarantee about the estate depends on nobody making a mistake, including administrators, including in accounts created next year. Four policies would take an afternoon:

  • Deny leaving the organisation
  • Deny disabling or altering the audit trail
  • Deny use of regions the business does not operate in
  • Deny deletion of log archive storage

None of them affect day-to-day work. All of them hold when everything else fails.

The resources found in three unused regions are the practical case: nobody chose to run anything there, nothing prevented it, and they were found by an audit rather than by a control.

3. Identity, ranked by reachability#

FindingReach
I111 long-lived access keys, oldest 3 yearsWhatever the key can do, from anywhere, until rotated
I22 keys with administrator permissionsFull account, no MFA, no expiry
I36 roles with wildcard permissionsBroad, and no audit of what they actually use
I4Local users in 3 accountsOutside central identity, missed by joiners-and-leavers
I5Root account has MFA but no alert on useRoot use is invisible until someone looks

I2 is the one to fix today. A long-lived administrator key with no MFA is the credential that appears in nearly every public breach write-up, because it needs no exploit — only exposure. Both were found in configuration files on developer machines during interviews.

I3 deserves a note on method. The wildcard roles were compared against 90 days of actual use: the six roles collectively used 34 distinct permissions out of thousands granted. Replacing wildcards with what is actually used is mechanical work with the access analyser, and it is the difference between a compromised role being an incident and being a catastrophe.

4. Network#

FindingNote
N1Security group open to the world on port 223 instances, one in Production A
N2Storage bucket with public readContains marketing assets — intentional, but unmarked
N3No VPC endpointsAll service traffic via NAT gateway
N4Development VPC peered to Production APeered in 2024 for a migration that finished
N5Default VPCs remain in unused regionsNothing running, but nothing preventing it

N4 undoes the account separation. Development is shared by four teams and is peered into production; the strongest boundary in the estate has a door in it, left from work that ended two years ago.

N3 is a cost finding as well as a routing one — NAT gateway charges are hourly and per GB, and endpoints remove both for traffic that never needed to leave.

5. What is already right#

  • The security account is correct, and logs are delivered there rather than kept beside the workloads that produce them. An intruder in a workload account cannot edit the evidence.
  • Production A and B are separate accounts, not separate VPCs in one account.
  • Encryption at rest is on by default for storage and databases.
  • Infrastructure is described in code for the two production accounts.
  • The root account has MFA on every account. The alerting gap in I5 is real, but the fundamental control is in place.

6. Sequence#

WhenAction
TodayDelete the 2 administrator access keys · close the 3 open SSH rules
This weekFour service control policies · alert on root account use · remove the development-to-production peering
Weeks 2–3Rotate or eliminate the remaining 9 keys · move the 3 workloads out of the management account · budget alerts on all 7 accounts
This monthLocal users into central identity · VPC endpoints · configuration recording everywhere
This quarterReplace wildcard permissions with measured usage · separate development per team · delete default VPCs in unused regions

Deliberately not recommended: a third-party cloud security platform. Every finding in this audit came from the organisation's own configuration and logs. A platform would have presented the same findings on a nicer page, and it would not have fixed the absence of service control policies — which is the finding that makes all the others recur.


Notes on using this format#

Order by blast radius. An open SSH port on a development instance and an administrator key with no expiry are both "high" in most frameworks. One of them reaches everything.

Compare granted permissions to used permissions. It converts "we should apply least privilege" from a principle into a list, and the list is usually much shorter than anyone expects.

Separate structural findings from configuration findings. Closing an SSH port is a task. A management account that runs workloads, and a peering connection that joins development to production, are decisions — and they will be recreated by the next migration unless something prevents it.

Back to AWS