← Back to Tutorials
Tutorial 20 Intermediate

SOC 2 Compliance on AWS: Enterprise Sales Security Guide

SOC 2 compliance has become the golden ticket to enterprise contracts. Learn how to implement the required AWS security controls, collect audit evidence, and achieve certification to unlock deals worth millions.

3-6 month implementation
15 min read
Compliance

Why SOC 2 Compliance Matters for Enterprise Sales

SOC 2 (Service Organization Control 2) isn't just another compliance checkboxβ€”it's become the golden ticket to enterprise contracts. For B2B SaaS companies handling customer data, SOC 2 compliance has transformed from a "nice-to-have" to an absolute requirement for enterprise sales success.

  • Enterprise procurement teams mandate SOC 2 compliance for vendors handling customer data
  • Average enterprise deal value is 5-10x larger than SMB contracts
  • Without SOC 2, sales teams spend 3-6x longer on security questionnaires
  • Competitors with SOC 2 automatically advance in RFP processes
  • SOC 2 signals security maturity and builds immediate trust

The Four Business Impacts of Non-Compliance

1

Lost Revenue Opportunities

Companies without SOC 2 miss out on 60-80% of enterprise deals. The average enterprise contract is 5-10x larger than SMB deals, representing millions in lost revenue annually.

2

Extended Sales Cycles

Without SOC 2, sales teams spend 3-6x longer answering security questionnaires and providing custom documentation, significantly slowing deal velocity and increasing customer acquisition costs.

3

Competitive Disadvantage

Competitors with SOC 2 compliance automatically advance in RFP processes while non-compliant companies are eliminated early in the evaluationβ€”often before even speaking with decision-makers.

4

Customer Trust Barrier

Enterprise buyers view SOC 2 as proof of security maturity. Without it, companies appear risky and unprepared for enterprise-scale data protection, regardless of actual security posture.

πŸ’‘
AWS Advantage: AWS maintains SOC 2 Type II compliance for 183+ services, providing the underlying infrastructure compliance foundation you can build upon. Your organization inherits certain controls while maintaining responsibility for application-level security, access management, and operational procedures.

Understanding the 5 Trust Service Principles

SOC 2 compliance is built on five Trust Service Principles (TSP). While Security is mandatory for all SOC 2 audits, you choose which additional principles apply based on your services and customer commitments.

1

Security (Mandatory)

Protection against unauthorized access through physical and logical controls. Includes IAM policies, VPC security groups, encryption at rest/transit, and CloudTrail logging.

2

Availability

System operational performance and uptime commitments. Covers Multi-AZ deployments, Auto Scaling, health checks, and disaster recovery strategies.

3

Processing Integrity

Ensures system processing is complete, valid, accurate, and authorized. Includes data validation, error handling, transaction logging, and monitoring pipelines.

4

Confidentiality

Protection of information designated as confidential. Covers encryption, data classification, secure transmission, and access restrictions.

5

Privacy

Personal information protection per privacy policies. Addresses data retention, right to deletion, consent management, and cross-border transfers.

⚠️
Scope Selection Strategy: Start with Security (mandatory) plus 1-2 relevant principles. Most SaaS companies choose Security + Availability + Confidentiality. Adding all principles increases audit scope, time, and cost significantly.
1

AWS Environment Assessment & Gap Analysis

~2 weeks

Before implementing controls, conduct a comprehensive assessment of your current AWS security posture and identify gaps against SOC 2 requirements.

Prerequisites

  • AWS account with administrative access
  • AWS CLI configured
  • AWS Config enabled
  • AWS Security Hub enabled

Console Steps

1.1 Inventory Your AWS Environment

  • Navigate to AWS Config in the console
  • Go to "Resources" to view all discovered resources
  • Export the resource inventory for documentation
  • Identify all resources that store or process customer data
AWS CLI - Inventory Commands
# Get discovered resource counts from AWS Config
aws configservice get-discovered-resource-counts --output table

# List all EC2 instances across regions
aws ec2 describe-instances \
    --query 'Reservations[*].Instances[*].[InstanceId,InstanceType,State.Name,Tags[?Key==`Name`].Value|[0]]' \
    --output table

# Inventory S3 buckets and encryption status
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
    echo "Bucket: $bucket"
    aws s3api get-bucket-encryption --bucket $bucket 2>/dev/null || echo "  No encryption configured"
done

# List all IAM users and access keys
aws iam list-users --query 'Users[*].[UserName,CreateDate]' --output table

1.2 Security Configuration Assessment

  • Navigate to AWS Security Hub
  • Enable the "AWS Foundational Security Best Practices" standard
  • Review findings by severity (CRITICAL, HIGH, MEDIUM)
  • Export findings for gap analysis documentation
AWS CLI - Security Assessment
# Enable Security Hub with all standards
aws securityhub enable-security-hub --enable-default-standards

# Get high and critical findings
aws securityhub get-findings \
    --filters '{"SeverityLabel":[{"Value":"HIGH","Comparison":"EQUALS"},{"Value":"CRITICAL","Comparison":"EQUALS"}]}' \
    --query 'Findings[*].[Id,Title,Severity.Label]' \
    --output table

1.3 Access Control Review

  • Navigate to IAM Access Analyzer
  • Create an analyzer for your account
  • Review findings for overprivileged access
  • Document all IAM users, roles, and their permissions
AWS CLI - Access Review
# Create IAM Access Analyzer
aws accessanalyzer create-analyzer \
    --analyzer-name SOC2-Access-Analyzer \
    --type ACCOUNT

# List Access Analyzer findings
aws accessanalyzer list-findings \
    --analyzer-arn arn:aws:access-analyzer:REGION:ACCOUNT:analyzer/SOC2-Access-Analyzer \
    --query 'findings[*].[id,status,resourceType,resource]' \
    --output table

# Generate IAM credential report
aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | base64 --decode > iam-credential-report.csv
βœ“
Gap Analysis Complete: Create a comprehensive document listing all missing controls, misconfigurations, and remediation priorities. This becomes your SOC 2 implementation roadmap.
2

Implement Required AWS Security Controls

~4-8 weeks

Based on your gap analysis, implement the core AWS security controls required for SOC 2 compliance.

Console Steps

2.1 Enable Multi-Factor Authentication

  • Navigate to IAM β†’ "Users"
  • Select each user β†’ "Security credentials" tab
  • Under "Multi-factor authentication (MFA)", click "Assign MFA device"
  • Choose "Authenticator app" and follow setup steps
  • Repeat for ALL IAM users, especially administrators

2.2 Configure IAM Password Policy

  • Navigate to IAM β†’ "Account settings"
  • Click "Edit" under Password policy
  • Set minimum length to 14 characters
  • Require uppercase, lowercase, numbers, and symbols
  • Enable password expiration (90 days)
  • Prevent password reuse (24 passwords)

2.3 Enable S3 Bucket Encryption

  • Navigate to S3 β†’ Select bucket
  • Go to "Properties" tab
  • Under "Default encryption", click "Edit"
  • Select "Server-side encryption with AWS KMS keys (SSE-KMS)"
  • Choose your KMS key or create a new one
  • Enable "Bucket Key" for cost optimization
AWS CLI - S3 Encryption
# Enable default encryption for S3 bucket
aws s3api put-bucket-encryption \
    --bucket YOUR-BUCKET-NAME \
    --server-side-encryption-configuration '{
        "Rules": [{
            "ApplyServerSideEncryptionByDefault": {
                "SSEAlgorithm": "aws:kms",
                "KMSMasterKeyID": "arn:aws:kms:REGION:ACCOUNT:key/KEY-ID"
            },
            "BucketKeyEnabled": true
        }]
    }'

# Block public access
aws s3api put-public-access-block \
    --bucket YOUR-BUCKET-NAME \
    --public-access-block-configuration \
    "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

# Enable versioning for audit trail
aws s3api put-bucket-versioning \
    --bucket YOUR-BUCKET-NAME \
    --versioning-configuration Status=Enabled

2.4 Configure CloudTrail for Audit Logging

  • Navigate to CloudTrail β†’ "Create trail"
  • Name: soc2-audit-trail
  • Enable "Apply trail to all regions"
  • Create new S3 bucket or use existing encrypted bucket
  • Enable "Log file SSE-KMS encryption"
  • Enable "Log file validation"
  • Under "Events", enable Management events (Read/Write)
AWS CLI - CloudTrail Setup
# Create CloudTrail with log file validation
aws cloudtrail create-trail \
    --name soc2-audit-trail \
    --s3-bucket-name your-cloudtrail-bucket \
    --include-global-service-events \
    --is-multi-region-trail \
    --enable-log-file-validation \
    --kms-key-id arn:aws:kms:REGION:ACCOUNT:key/KEY-ID

# Start logging
aws cloudtrail start-logging --name soc2-audit-trail

# Enable data events for S3 (optional but recommended)
aws cloudtrail put-event-selectors \
    --trail-name soc2-audit-trail \
    --event-selectors '[{
        "ReadWriteType": "All",
        "IncludeManagementEvents": true,
        "DataResources": [{
            "Type": "AWS::S3::Object",
            "Values": ["arn:aws:s3:::your-data-bucket/*"]
        }]
    }]'

2.5 Configure VPC Security Groups

  • Navigate to VPC β†’ "Security groups"
  • Review each security group's inbound rules
  • Remove any rules allowing 0.0.0.0/0 except for public-facing services
  • Implement least privilege: only allow required ports
  • Document business justification for any open rules

2.6 Enable RDS Encryption

  • For new databases: Enable "Encryption" during creation
  • For existing unencrypted databases: Create encrypted snapshot, then restore
  • Enable "Deletion protection"
  • Set backup retention to minimum 30 days
  • Enable "Enhanced monitoring"
AWS CLI - RDS Encryption
# Create encrypted RDS instance
aws rds create-db-instance \
    --db-instance-identifier soc2-database \
    --db-instance-class db.r5.large \
    --engine postgres \
    --master-username admin \
    --master-user-password SECURE_PASSWORD \
    --allocated-storage 100 \
    --storage-encrypted \
    --kms-key-id arn:aws:kms:REGION:ACCOUNT:key/KEY-ID \
    --vpc-security-group-ids sg-12345678 \
    --db-subnet-group-name your-db-subnet-group \
    --backup-retention-period 30 \
    --deletion-protection \
    --enable-performance-insights
βœ“
Security Controls Implemented: You've established the core security foundation required for SOC 2 compliance. Next, focus on evidence collection and documentation.
3

Evidence Collection & Documentation

Ongoing throughout audit period

SOC 2 audits require extensive evidence to prove your controls are operating effectively. Evidence collection is the most time-consuming part of SOC 2 compliance.

Types of SOC 2 Evidence Required

  • Screenshots: AWS console showing security configurations with timestamps
  • Reports: CloudTrail logs, Security Hub findings, Config compliance reports
  • Policies: Written security policies, procedures, incident response plans
  • Testing: Vulnerability scans, penetration tests, disaster recovery exercises
  • Monitoring: Real-time alerts, dashboards, ongoing security oversight
  • Changes: Documentation of all system changes and approvals

3.1 Automate Evidence Collection

  • Create a dedicated S3 bucket for SOC 2 evidence
  • Set up automated exports from Security Hub
  • Configure CloudWatch Logs exports
  • Schedule regular IAM credential reports
Evidence Collection Script
#!/bin/bash
# SOC 2 Evidence Collection Script - Run monthly

EVIDENCE_DIR="soc2-evidence-$(date +%Y-%m-%d)"
mkdir -p $EVIDENCE_DIR

echo "Starting SOC 2 evidence collection..."

# 1. IAM Evidence
echo "Collecting IAM evidence..."
aws iam generate-credential-report
sleep 5
aws iam get-credential-report --query 'Content' --output text | base64 --decode > $EVIDENCE_DIR/iam-credential-report.csv
aws iam list-users --output json > $EVIDENCE_DIR/iam-users.json
aws iam list-roles --output json > $EVIDENCE_DIR/iam-roles.json

# 2. Security Configuration Evidence
echo "Collecting security configurations..."
aws ec2 describe-security-groups --output json > $EVIDENCE_DIR/security-groups.json
aws s3api list-buckets --output json > $EVIDENCE_DIR/s3-buckets.json

# 3. Encryption Evidence
echo "Collecting encryption evidence..."
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
    echo "Bucket: $bucket" >> $EVIDENCE_DIR/s3-encryption-status.txt
    aws s3api get-bucket-encryption --bucket $bucket >> $EVIDENCE_DIR/s3-encryption-status.txt 2>&1
done

# 4. CloudTrail Evidence
echo "Collecting CloudTrail evidence..."
aws cloudtrail describe-trails --output json > $EVIDENCE_DIR/cloudtrail-config.json
aws cloudtrail get-trail-status --name soc2-audit-trail --output json > $EVIDENCE_DIR/cloudtrail-status.json

# 5. Security Hub Findings
echo "Collecting Security Hub findings..."
aws securityhub get-findings --output json > $EVIDENCE_DIR/security-hub-findings.json

# 6. Config Compliance
echo "Collecting Config compliance..."
aws configservice get-compliance-summary-by-config-rule --output json > $EVIDENCE_DIR/config-compliance.json

echo "Evidence collection complete. Files saved to: $EVIDENCE_DIR"
⚠️
Evidence Quality Standards: All evidence must include system timestamps, be from the production environment, cover the entire audit period, and clearly demonstrate the control is operating effectively. Screenshots must show full browser windows with URLs visible.
βœ“
Evidence Collection Active: Run this script monthly and store evidence in a secure, organized location. Auditors will request specific evidence during the examination.
4

Continuous Monitoring & Compliance

~1 week setup, then ongoing

SOC 2 Type II requires demonstrating that controls operated effectively throughout the audit period (minimum 3 months, typically 6-12 months). Implement continuous monitoring to ensure ongoing compliance.

Console Steps

4.1 Enable AWS Config Rules

  • Navigate to AWS Config β†’ "Rules"
  • Click "Add rule"
  • Add these critical rules for SOC 2:
Critical AWS Config Rules for SOC 2
# Security Controls
s3-bucket-server-side-encryption-enabled
s3-bucket-public-read-prohibited
s3-bucket-public-write-prohibited
rds-storage-encrypted
encrypted-volumes
cloud-trail-enabled
cloud-trail-encryption-enabled
cloud-trail-log-file-validation-enabled

# Access Controls
iam-password-policy
iam-root-access-key-check
mfa-enabled-for-iam-console-access
root-account-mfa-enabled
iam-user-mfa-enabled

# Logging & Monitoring
cloudwatch-log-group-encrypted
vpc-flow-logs-enabled
guardduty-enabled-centralized

4.2 Create CloudWatch Alarms

  • Navigate to CloudWatch β†’ "Alarms"
  • Click "Create alarm"
  • Create alarms for security events
  • Configure SNS notifications to security team
AWS CLI - Security Alarms
# Create SNS topic for security alerts
aws sns create-topic --name soc2-security-alerts
aws sns subscribe --topic-arn arn:aws:sns:REGION:ACCOUNT:soc2-security-alerts \
    --protocol email --notification-endpoint security@yourcompany.com

# Create metric filter for root account usage
aws logs put-metric-filter \
    --log-group-name CloudTrail/soc2-audit-trail \
    --filter-name RootAccountUsage \
    --filter-pattern '{ $.userIdentity.type = "Root" && $.userIdentity.invokedBy NOT EXISTS && $.eventType != "AwsServiceEvent" }' \
    --metric-transformations \
        metricName=RootAccountUsageCount,metricNamespace=SOC2/Security,metricValue=1

# Create alarm for root account usage
aws cloudwatch put-metric-alarm \
    --alarm-name "Root-Account-Usage" \
    --alarm-description "Alert when root account is used" \
    --metric-name RootAccountUsageCount \
    --namespace SOC2/Security \
    --statistic Sum \
    --period 300 \
    --threshold 1 \
    --comparison-operator GreaterThanOrEqualToThreshold \
    --alarm-actions arn:aws:sns:REGION:ACCOUNT:soc2-security-alerts

# Create metric filter for unauthorized API calls
aws logs put-metric-filter \
    --log-group-name CloudTrail/soc2-audit-trail \
    --filter-name UnauthorizedAPICalls \
    --filter-pattern '{ ($.errorCode = "*UnauthorizedOperation") || ($.errorCode = "AccessDenied*") }' \
    --metric-transformations \
        metricName=UnauthorizedAPICallCount,metricNamespace=SOC2/Security,metricValue=1

# Create alarm for unauthorized API calls
aws cloudwatch put-metric-alarm \
    --alarm-name "Unauthorized-API-Calls" \
    --alarm-description "Alert on unauthorized API calls" \
    --metric-name UnauthorizedAPICallCount \
    --namespace SOC2/Security \
    --statistic Sum \
    --period 300 \
    --threshold 10 \
    --comparison-operator GreaterThanThreshold \
    --alarm-actions arn:aws:sns:REGION:ACCOUNT:soc2-security-alerts
βœ“
Continuous Monitoring Active: Your automated monitoring systems will track SOC 2 compliance and collect evidence throughout the audit period.
5

Audit Preparation & Execution

~4-8 weeks

After operating your controls for the required period (3-12 months), prepare for the formal SOC 2 audit.

SOC 2 Implementation Timeline

  • Month 1: Planning, gap analysis, auditor selection
  • Months 2-3: Implement controls, create policies, begin evidence collection
  • Months 4-9: Operate controls consistently (minimum 3 months for Type II)
  • Month 10: Pre-audit readiness assessment
  • Months 11-12: Formal audit, remediation, final report

5.1 Pre-Audit Readiness Assessment

  • Verify all required evidence is collected for full audit period
  • Test each control to ensure it's operating as designed
  • Confirm all policies are up-to-date and reflect actual practices
  • Train team members who will interact with auditors
  • Organize evidence by control category for easy retrieval

5.2 Auditor Selection

  • Choose a CPA firm with SOC 2 experience in your industry
  • Expect costs: $15,000-$50,000 for SMEs, $50,000-$200,000+ for enterprise
  • Big Four firms cost more but may be required for large enterprise clients
  • Request references and verify AICPA certification
⚠️
Most Common Audit Exceptions: Incomplete evidence for specific time periods, periods where controls weren't operating effectively, lack of documented access reviews, undocumented system changes, and security incidents not properly investigated.
βœ“
Audit Success: With proper preparation and organized evidence, most organizations pass their first SOC 2 audit. The key is thorough preparation and maintaining controls consistently throughout the audit period.

Validate Your Configuration

Complete these checks to ensure your AWS infrastructure meets SOC 2 requirements:

Security Validation Script

Run this script to verify your SOC 2 compliance configuration:

Bash Script
#!/bin/bash
# SOC 2 Control Validation Script

echo "Starting SOC 2 control validation..."
echo ""

# Test 1: Check for root account access keys
echo "1. Testing root account access keys..."
ROOT_KEYS=$(aws iam get-account-summary --query 'SummaryMap.AccountAccessKeysPresent' --output text)
if [ "$ROOT_KEYS" -eq 0 ]; then
    echo "   βœ“ PASS: No root account access keys found"
else
    echo "   βœ— FAIL: Root account access keys detected - remove immediately"
fi

# Test 2: Check MFA on root account
echo "2. Testing root account MFA..."
ROOT_MFA=$(aws iam get-account-summary --query 'SummaryMap.AccountMFAEnabled' --output text)
if [ "$ROOT_MFA" -eq 1 ]; then
    echo "   βœ“ PASS: Root account MFA is enabled"
else
    echo "   βœ— FAIL: Root account MFA is not enabled"
fi

# Test 3: Check CloudTrail status
echo "3. Testing CloudTrail configuration..."
TRAIL_STATUS=$(aws cloudtrail get-trail-status --name soc2-audit-trail --query 'IsLogging' --output text 2>/dev/null)
if [ "$TRAIL_STATUS" = "True" ]; then
    echo "   βœ“ PASS: CloudTrail logging is active"
else
    echo "   βœ— FAIL: CloudTrail logging is not active"
fi

# Test 4: Check S3 bucket encryption
echo "4. Testing S3 bucket encryption..."
UNENCRYPTED=0
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
    ENCRYPTION=$(aws s3api get-bucket-encryption --bucket $bucket 2>/dev/null)
    if [ $? -ne 0 ]; then
        echo "   βœ— Unencrypted bucket: $bucket"
        UNENCRYPTED=$((UNENCRYPTED + 1))
    fi
done
if [ $UNENCRYPTED -eq 0 ]; then
    echo "   βœ“ PASS: All S3 buckets are encrypted"
else
    echo "   βœ— FAIL: $UNENCRYPTED unencrypted buckets found"
fi

# Test 5: Check users without MFA
echo "5. Testing IAM user MFA..."
aws iam generate-credential-report > /dev/null 2>&1
sleep 3
USERS_NO_MFA=$(aws iam get-credential-report --query 'Content' --output text | base64 --decode | grep -c ",false," 2>/dev/null || echo "0")
if [ "$USERS_NO_MFA" -eq 0 ]; then
    echo "   βœ“ PASS: All IAM users have MFA enabled"
else
    echo "   βœ— FAIL: $USERS_NO_MFA users without MFA found"
fi

# Test 6: Check Security Hub status
echo "6. Testing Security Hub..."
SH_STATUS=$(aws securityhub describe-hub --query 'HubArn' --output text 2>/dev/null)
if [ -n "$SH_STATUS" ]; then
    echo "   βœ“ PASS: Security Hub is enabled"
else
    echo "   βœ— FAIL: Security Hub is not enabled"
fi

echo ""
echo "SOC 2 control validation complete!"

Common Mistakes to Avoid

βœ—

Starting too late. Waiting until you need SOC 2 for a specific deal. The 6-7 month timeline means you'll likely lose the opportunity that motivated you to start.

βœ—

Inadequate evidence collection. Failing to collect evidence consistently throughout the operational period leads to gaps that require extending the audit timeline.

βœ—

Over-scoping the audit. Including unnecessary systems or choosing too many Trust Service Principles increases complexity and cost. Start with Security + 1-2 relevant principles.

βœ—

Neglecting policy documentation. Having good technical controls but lacking the documented policies and procedures that auditors require.

βœ—

Choosing the wrong auditor. Selecting an auditor without SOC 2 experience or industry knowledge leads to extended timelines and higher costs.

Want Continuous SOC 2 Compliance Monitoring?

Manual compliance checks are time-consuming and error-prone. AWSight automatically monitors 500+ security controls daily, collecting audit evidence and alerting you to compliance drift before it becomes an audit exception.

References