Skip to main content

Audit Readiness

What auditors actually do — not a theory exercise, but what happens in the room.


Type I vs. Type II — What You're Proving

SOC 2 Type ISOC 2 Type II
What it provesControls are designed and in place at a point in timeControls operated effectively over a period (typically 6–12 months)
Audit duration2–6 weeks of fieldwork3–6 months of observation period + fieldwork
EvidenceConfiguration screenshots, policy docs, architecture diagramsLogs, ticket history, access review records, alert response records
When to pursueFast path for new customers; first-time SOC 2Required for enterprise procurement; higher trust signal
Cost (typical)$15,000–$30,000$25,000–$60,000

Start with Type I to clear procurement blockers quickly. Begin the Type II observation period immediately after — overlap is valid.


What Happens During Fieldwork

Day 1–2: Kickoff and population requests

The auditor sends a population request — a list of everything they want to see. Typical items:

  • List of all AWS accounts in scope
  • List of all employees with AWS access (as of audit date)
  • List of all employees who joined or left during the period
  • Incident log for the period
  • Access review records for the period
  • List of all third-party vendors with access to customer data

Have these ready before Day 1. Scrambling to gather populations signals poor control maturity.

Day 3–10: Evidence review and sampling

Auditors sample from your populations. If you had 200 employees, they might test 25. If you had 12 incidents, they test all of them. For each sample:

  • They ask for the original evidence artifact (screenshot, log export, ticket)
  • They verify it matches the control description in your policy documents
  • They look for exceptions — any sample where the control was not followed

The evidence must exist at the time the control was supposed to operate. You cannot go back and create it after the fact. Auditors check document creation dates and git history.

Day 11–15: Walkthroughs

Auditors schedule 30–60 minute calls with the people who operate each control:

Control ownerWhat they're asked
Security engineer"Walk me through what happens when GuardDuty fires a HIGH finding"
SRE/DevOps"Show me how a new engineer gets access to AWS"
Engineering manager"How do you verify an engineer's access is removed when they leave?"
CISO/Security lead"Walk me through the last incident from alert to post-incident review"

Prepare your team. People who actually do the work answer — not the person who wrote the policy. Auditors will probe: "What if that person is on vacation?" "Who reviews it?" "Where is that decision documented?"

Final: Management representation letter

Before issuing the report, auditors ask management to sign a letter confirming no undisclosed incidents, no material changes, and that evidence provided is accurate. This is a legal document.


The 10 Most Common SOC 2 Findings on AWS

These are the issues that generate the most findings in practice. Fix these before scheduling your audit.

1. IAM users without MFA (CC6.1)

The credential report will show it. Auditors always pull the credential report. Even one user without MFA on an account in scope is a finding.

Fix: Enable the mfa-enabled-for-iam-console-access Config rule and enforce the MFA-deny IAM policy from the IAM page.

2. Access keys older than 90 days (CC6.2)

The credential report shows access_key_1_last_rotated. Anything over 90 days is flagged. Auditors calculate the age from the rotation date to the last day of the audit period.

Fix: Set the access-keys-rotated Config rule and run the key audit script before the audit window opens.

3. Terminated employee still has AWS access (CC6.3)

Auditors cross-reference your HR termination list with IAM Identity Center assignments or IAM users. If a terminated employee still appears with active access after their last day, it's a finding — even if they never logged in.

Fix: Automate deprovisioning via SCIM. If manual, run a deprovisioning check on every offboarding ticket before closing it.

4. GuardDuty findings with no documented response (CC7.3)

HIGH and CRITICAL GuardDuty findings must have evidence of investigation and resolution. If a finding sat in the console unacknowledged for weeks, auditors treat it as evidence the monitoring process is not operating effectively.

Fix: Any finding at severity ≥ 7 must have a corresponding ticket. The ticket must show: who investigated, what they found, what action was taken. Archive the ticket for 3 years.

5. No evidence of incident response testing (CC7.4)

Having a runbook is not enough. Auditors ask: "When did you last test this?" If you can't point to a tabletop exercise or a live incident with a post-incident review in the past 12 months, this is a finding.

Fix: Run an annual tabletop exercise. Document it. Retain the agenda, attendees, and outcomes.

6. CloudTrail not covering all regions (CC7.2)

A single-region trail misses API activity in other regions. Auditors check IsMultiRegionTrail: false and ask about workloads in other regions.

Fix: Use a multi-region trail. Verify with aws cloudtrail describe-trails --include-shadow-trails.

7. Overly permissive IAM policies (CC6.1)

Auditors sample 10–20 IAM policies. Action: "*" or Resource: "*" on non-admin roles is an immediate finding. Inline policies on users are also flagged.

Fix: Run IAM Access Analyzer before the audit. Remediate any policy with * on sensitive resources.

8. No quarterly access review records (CC6.3)

SOC 2 requires evidence that access is reviewed periodically. "We informally review access" is not evidence. The review must be documented: who reviewed it, when, and what was changed as a result.

Fix: Export the IAM credential report quarterly. Put the review in a ticketing system. Retain it.

9. S3 buckets without encryption or public access block (CC6.1, CC6.7)

If any S3 bucket in scope has ServerSideEncryptionConfigurationNotFound or BlockPublicAcls: false, it's a finding — even if the bucket contains no sensitive data. Auditors look at the configuration, not the contents.

Fix: Enable account-level public access block and default encryption. Run the Config rules s3-bucket-server-side-encryption-enabled and s3-bucket-public-access-prohibited.

10. Vendor without a signed BAA or security review (CC9.2)

SOC 2 CC9.2 requires vendor risk management. If you use third-party services that process customer data (Datadog, Sentry, PagerDuty, Slack, etc.) and have no record of reviewing their security posture, it's a finding.

Fix: Maintain a vendor list. For each vendor with access to customer data: note their SOC 2 status, review date, and whether a DPA/BAA is in place.


Evidence Package Structure

Organize evidence before the audit starts. A well-structured package signals maturity and makes fieldwork faster.

soc2-evidence-2024/
├── README.md ← index of every artifact + what control it covers

├── CC6-access-control/
│ ├── iam-credential-report-2024-09-30.csv
│ ├── mfa-enforcement-policy.json
│ ├── password-policy.json
│ ├── access-review-Q1-2024.pdf
│ ├── access-review-Q2-2024.pdf
│ ├── access-review-Q3-2024.pdf
│ ├── offboarding-tickets/
│ │ ├── ENG-1234-jane-smith-offboard.pdf
│ │ └── ENG-1456-john-doe-offboard.pdf
│ └── identity-center-assignments-export.csv

├── CC7-monitoring/
│ ├── cloudtrail-trail-config.json
│ ├── cloudtrail-log-validation-status.json
│ ├── guardduty-detector-config.json
│ ├── guardduty-findings-resolved-2024.csv
│ ├── security-hub-summary-report.pdf
│ ├── config-rule-compliance-2024-09-30.csv
│ └── cloudwatch-alarms-config.json

├── CC6-encryption/
│ ├── kms-key-list.json
│ ├── kms-rotation-status.json
│ ├── s3-encryption-config.json
│ ├── ebs-encryption-default.json
│ └── rds-encryption-status.json

├── CC6-network/
│ ├── vpc-config.json
│ ├── security-group-rules.json
│ ├── waf-web-acl.json
│ └── alb-tls-policy.json

├── CC7-incident-response/
│ ├── incident-response-policy-v2.3.pdf
│ ├── incident-runbook-v1.1.md
│ ├── tabletop-exercise-2024-03-15.pdf
│ ├── incidents/
│ │ ├── INC-2024-001-post-incident-review.pdf
│ │ └── INC-2024-002-post-incident-review.pdf
│ └── guardduty-finding-responses/
│ ├── finding-abc123-ticket-ENG-2001.pdf
│ └── finding-def456-ticket-ENG-2089.pdf

├── CC9-vendor-management/
│ ├── vendor-inventory-2024.xlsx
│ └── vendor-soc2-reports/
│ ├── aws-soc2-type2-2023.pdf ← from AWS Artifact
│ ├── datadog-soc2-2023.pdf
│ └── pagerduty-soc2-2023.pdf

└── policies/
├── information-security-policy-v3.0.pdf
├── access-control-policy-v2.1.pdf
├── incident-response-policy-v2.3.pdf
├── change-management-policy-v1.4.pdf
└── vendor-management-policy-v1.2.pdf

Version-control your policies. Auditors ask "has this policy changed during the period?" If you can't show a version history (Git, Google Docs revision history, Confluence page history), it's a gap.


Evidence Collection Script

Run this before the audit to bulk-export AWS configuration evidence:

#!/bin/bash
# export-soc2-evidence.sh
# Run from a role with SecurityAudit managed policy attached

ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
REGION=$(aws configure get region)
DATE=$(date +%Y-%m-%d)
OUT="soc2-evidence-${DATE}"
mkdir -p "$OUT"/{iam,cloudtrail,guardduty,config,network,encryption,securityhub}

echo "[1/9] IAM credential report..."
aws iam generate-credential-report > /dev/null 2>&1
sleep 5
aws iam get-credential-report --query Content --output text | base64 -d \
> "$OUT/iam/credential-report-${DATE}.csv"

echo "[2/9] IAM password policy..."
aws iam get-account-password-policy > "$OUT/iam/password-policy.json"

echo "[3/9] Root account summary..."
aws iam get-account-summary > "$OUT/iam/account-summary.json"

echo "[4/9] CloudTrail configuration..."
aws cloudtrail describe-trails --include-shadow-trails > "$OUT/cloudtrail/trails.json"
aws cloudtrail get-trail-status --name org-trail > "$OUT/cloudtrail/trail-status.json" 2>/dev/null

echo "[5/9] GuardDuty detector config..."
DETECTOR=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text)
aws guardduty get-detector --detector-id "$DETECTOR" > "$OUT/guardduty/detector.json"

echo "[6/9] Config rule compliance..."
aws configservice describe-compliance-by-config-rule \
--query 'ComplianceByConfigRules[*].[ConfigRuleName,Compliance.ComplianceType]' \
--output table > "$OUT/config/rule-compliance-${DATE}.txt"

echo "[7/9] Security group audit (SSH/RDP open)..."
aws ec2 describe-security-groups \
--filters "Name=ip-permission.from-port,Values=22" "Name=ip-permission.cidr,Values=0.0.0.0/0" \
--query 'SecurityGroups[*].[GroupId,GroupName]' --output table \
> "$OUT/network/open-ssh-security-groups.txt"

echo "[8/9] KMS key rotation status..."
aws kms list-keys --query 'Keys[*].KeyId' --output text | tr '\t' '\n' | while read KEY; do
STATUS=$(aws kms get-key-rotation-status --key-id "$KEY" --query 'KeyRotationEnabled' --output text 2>/dev/null)
echo "$KEY: $STATUS"
done > "$OUT/encryption/kms-rotation-status.txt"

echo "[9/9] S3 public access block (account level)..."
aws s3control get-public-access-block --account-id "$ACCOUNT" \
> "$OUT/encryption/s3-public-access-block.json"

echo ""
echo "Evidence exported to: $OUT/"
echo "Account: $ACCOUNT | Region: $REGION | Date: $DATE"

Auditor Walkthrough Questions — Prepare Your Team

These are representative questions auditors ask in walkthroughs. Practice answering them before the audit.

Access control:

  • "Walk me through how a new engineer gets access to the production AWS account."
  • "What happens to that access when they move to a different team?"
  • "How do you know they don't still have access to the old team's resources?"
  • "Show me where the quarterly access review is documented."

Monitoring:

  • "Walk me through what happens when GuardDuty fires a HIGH severity finding at 2am."
  • "Who gets paged? How do you know they acknowledged it?"
  • "Show me the last HIGH finding and the ticket that was opened for it."
  • "If CloudTrail stopped logging right now, how long before someone noticed?"

Incident response:

  • "Walk me through the last security incident from detection to post-incident review."
  • "Where is the post-incident review document?"
  • "What action items came out of it? Are they closed?"
  • "When did you last run a tabletop exercise? Show me the documentation."

Change management:

  • "How do code changes get to production?"
  • "Is there a change that went to production without a code review in the past 6 months?"
  • "How do infrastructure changes get approved?"

Vendor management:

  • "Which third-party services have access to customer data?"
  • "Do you have their SOC 2 reports? When did you last review them?"

Compensating Controls

Sometimes a control cannot be implemented as described — legacy systems, technical constraints, cost. Auditors accept compensating controls when properly documented.

Primary controlExample constraintCompensating control
Encrypt existing RDS instanceEncryption requires recreation; downtime window not feasibleNetwork isolation (private subnet, SG restricted to app only) + encrypted backups + WAF + enhanced monitoring
MFA for all IAM usersLegacy CI/CD service account cannot use MFAKey rotation every 30 days + IP allowlist + CloudTrail alert on any non-CI usage
90-day access key rotationVendor integration with no key rotation supportRead-only policy + IP restriction + quarterly manual review with documented sign-off

Document the constraint, the compensating control, and who approved it. Auditors want to see that you identified the gap, reasoned about risk, and implemented an alternative — not that you ignored it.


90-Day Pre-Audit Timeline

Weeks before auditAction
12Confirm audit scope (which accounts, which TSC criteria). Assign control owners.
10Run evidence collection script. Identify gaps in the evidence.
8Remediate top findings (MFA gaps, key rotation, unencrypted resources).
6Run tabletop exercise. Document it.
4Finalize evidence package. Version-control all policy documents.
2Walkthrough practice with control owners. Brief the team on what to expect.
1Send completed evidence package to auditor. Confirm fieldwork schedule.
0Audit begins. Have a single point of contact for all auditor requests.

Official reference: AWS Audit Manager SOC 2 Framework → · AWS Artifact (SOC reports) →