Documentation
ReferenceConnectorsAWS Connector

AWS Connector

Complete reference for collecting SOC 2 evidence from AWS using the evidence SDK.

Overview

Controls supported:

  • CC6.1 - Logical Access Controls (IAM password policy)
  • CC7.2 - Change Management (CloudTrail audit logging, log retention)

What it collects:

  • IAM account password policy
  • CloudTrail trail status and configuration
  • CloudWatch Logs log group retention settings

What it does NOT collect:

  • ❌ EC2 instance configurations or code
  • ❌ Database data or schemas
  • ❌ S3 bucket contents
  • ❌ Secrets from Secrets Manager or Parameter Store
  • ❌ IAM user passwords or access keys
  • ❌ Application logs content (only retention settings)

Configuration Schema

Required Fields

FieldTypeDescriptionExample
modeenumAuthentication mode: env or assume_roleenv
regionstringAWS regionus-east-1

Optional Fields

FieldTypeDefaultDescription
regionsarray-Multiple regions for multi-region collection
role_arnstring-IAM role ARN (required if mode: assume_role)
external_idstring-External ID for assume role (recommended)
log_groupsarray[]CloudWatch log groups to check retention
cloudtrailobject-CloudTrail configuration
cloudtrail.trailsarray[]CloudTrail trail names to verify
session_durationnumber3600Session duration for assume role (seconds)
timeout_secondsnumber60Request timeout in seconds

Authentication Modes

Environment Variables (env mode)

Use AWS credentials from environment variables:

sources:
  aws:
    mode: env
    region: us-east-1

Required environment variables:

export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=us-east-1  # Optional, uses config value if not set

Use cases:

  • Local development
  • CI/CD with static credentials
  • Simple setup

Assume Role (assume_role mode)

Assume an IAM role for collection:

sources:
  aws:
    mode: assume_role
    role_arn: arn:aws:iam::123456789012:role/evidence-collector
    external_id: evidence-sdk
    region: us-east-1

Environment variables:

export AWS_ACCESS_KEY_ID=AKIA...      # Source credentials
export AWS_SECRET_ACCESS_KEY=...      # Source credentials

Process:

  1. SDK authenticates with source credentials
  2. SDK assumes specified role
  3. SDK uses temporary role credentials for collection
  4. Temporary credentials expire after session_duration

Use cases:

  • Cross-account collection
  • Enhanced security (temporary credentials)
  • Multi-organization setups

Basic Configuration

Minimal (IAM Only)

framework: soc2_type1
controls:
  - CC6.1
sources:
  aws:
    mode: env
    region: us-east-1

Collects:

  • ✅ IAM account password policy

Requires:

  • AWS credentials in environment variables

With CloudTrail

sources:
  aws:
    mode: env
    region: us-east-1
    cloudtrail:
      trails:
        - production-audit-trail

Collects:

  • ✅ IAM account password policy
  • ✅ CloudTrail trail status and configuration

With CloudWatch Logs

sources:
  aws:
    mode: env
    region: us-east-1
    log_groups:
      - /aws/lambda/production-api
      - /aws/lambda/production-worker
      - /aws/ecs/backend

Collects:

  • ✅ IAM account password policy
  • ✅ CloudWatch log group retention settings

Complete Configuration

sources:
  aws:
    mode: env
    region: us-east-1
    log_groups:
      - /aws/lambda/production-*
      - /aws/ecs/backend
    cloudtrail:
      trails:
        - production-audit-trail
        - security-trail

Collects:

  • ✅ IAM password policy
  • ✅ CloudTrail configuration
  • ✅ CloudWatch log retention

Multi-Region Configuration

Explicit Regions

sources:
  aws:
    mode: env
    regions:
      - us-east-1
      - us-west-2
      - eu-west-1
    cloudtrail:
      trails:
        - production-audit-trail

Behavior:

  • Collects IAM password policy once (global)
  • Checks CloudTrail in each region
  • Checks CloudWatch log groups in each region

Wildcard Log Groups

sources:
  aws:
    mode: env
    region: us-east-1
    log_groups: '*'  # All log groups

Warning: May collect many log groups, check bundle size limits


Artifacts Collected

FilenameAPI CallControlsDescription
iam_password_policy.jsoniam:GetAccountPasswordPolicyCC6.1Account-wide password complexity requirements
cloudtrail_trail_{name}_status.jsoncloudtrail:GetTrailStatusCC7.2CloudTrail logging status (active/inactive)
cloudtrail_trail_{name}_config.jsoncloudtrail:DescribeTrailsCC7.2CloudTrail configuration (S3 bucket, encryption)
cloudwatch_log_group_{name}.jsonlogs:DescribeLogGroupsCC7.2Log retention settings

Artifact Details

IAM Password Policy (iam_password_policy.json)

Purpose: Verify password complexity requirements

Sample artifact:

{
  "MinimumPasswordLength": 14,
  "RequireSymbols": true,
  "RequireNumbers": true,
  "RequireUppercaseCharacters": true,
  "RequireLowercaseCharacters": true,
  "AllowUsersToChangePassword": true,
  "ExpirePasswords": true,
  "MaxPasswordAge": 90,
  "PasswordReusePrevention": 12,
  "HardExpiry": false
}

Control mapping:

  • CC6.1: Password policy must meet NIST standards

Pass criteria:

  • MinimumPasswordLength ≥ 12 (recommended: 14+)
  • RequireSymbols: true
  • RequireNumbers: true
  • RequireUppercaseCharacters: true
  • RequireLowercaseCharacters: true
  • ExpirePasswords: true with MaxPasswordAge ≤ 90
  • PasswordReusePrevention ≥ 12

Remediation if failing:

  1. Go to AWS Console → IAM → Account settings → Password policy
  2. Set minimum length to 14 characters
  3. Require uppercase, lowercase, numbers, and symbols
  4. Enable password expiration (90 days)
  5. Prevent password reuse (12 passwords)

CloudTrail Status (cloudtrail_trail_{name}_status.json)

Purpose: Verify audit logging is active

Sample artifact:

{
  "IsLogging": true,
  "LatestDeliveryAttemptTime": "2026-01-09T12:30:00Z",
  "LatestDeliveryAttemptSucceeded": "2026-01-09T12:30:00Z",
  "LatestNotificationAttemptTime": "",
  "LatestNotificationAttemptSucceeded": "",
  "StartLoggingTime": "2025-06-01T00:00:00Z",
  "TimeLoggingStarted": "2025-06-01T00:00:00Z",
  "TimeLoggingStopped": ""
}

Control mapping:

  • CC7.2: CloudTrail must be actively logging

Pass criteria:

  • IsLogging: true
  • LatestDeliveryAttemptSucceeded is recent (< 24 hours)
  • TimeLoggingStopped is empty (not stopped)

Remediation if failing:

  1. Go to AWS Console → CloudTrail → Trails
  2. Select trail
  3. If logging stopped, click "Start logging"
  4. Verify S3 bucket is accessible
  5. Check IAM permissions for CloudTrail service

CloudTrail Configuration (cloudtrail_trail_{name}_config.json)

Purpose: Verify CloudTrail settings

Sample artifact:

{
  "Name": "production-audit-trail",
  "S3BucketName": "acme-cloudtrail-logs",
  "IncludeGlobalServiceEvents": true,
  "IsMultiRegionTrail": true,
  "HomeRegion": "us-east-1",
  "TrailARN": "arn:aws:cloudtrail:us-east-1:123456789012:trail/production-audit-trail",
  "LogFileValidationEnabled": true,
  "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/abc-123",
  "IsOrganizationTrail": false
}

Control mapping:

  • CC7.2: CloudTrail configuration best practices

Pass criteria:

  • IsMultiRegionTrail: true (recommended)
  • LogFileValidationEnabled: true (tamper detection)
  • KmsKeyId set (encryption at rest)
  • IncludeGlobalServiceEvents: true

Remediation if failing:

  1. Go to CloudTrail trail settings
  2. Enable "Multi-region trail"
  3. Enable "Log file validation"
  4. Enable "SSE-KMS encryption" with KMS key

CloudWatch Log Group (cloudwatch_log_group_{name}.json)

Purpose: Verify log retention settings

Sample artifact:

{
  "logGroupName": "/aws/lambda/production-api",
  "creationTime": 1640995200000,
  "retentionInDays": 90,
  "metricFilterCount": 0,
  "arn": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/production-api:*",
  "storedBytes": 12456789
}

Control mapping:

  • CC7.2: Logs must be retained for audit purposes

Pass criteria:

  • retentionInDays ≥ 90 (recommended)
  • retentionInDays set (not null = indefinite)

Remediation if failing:

  1. Go to CloudWatch → Log groups
  2. Select log group
  3. Click "Actions" → "Edit retention setting"
  4. Set retention to 90 days or longer
  5. Consider cost vs. compliance requirements

Required Permissions

IAM Policy (Minimal)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EvidenceCollectionMinimal",
      "Effect": "Allow",
      "Action": [
        "iam:GetAccountPasswordPolicy"
      ],
      "Resource": "*"
    }
  ]
}

Collects: IAM password policy only


IAM Policy (Complete)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EvidenceCollection",
      "Effect": "Allow",
      "Action": [
        "iam:GetAccountPasswordPolicy",
        "cloudtrail:DescribeTrails",
        "cloudtrail:GetTrailStatus",
        "logs:DescribeLogGroups"
      ],
      "Resource": "*"
    }
  ]
}

Collects: All AWS artifacts


Assume Role Trust Policy

If using assume_role mode:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::SOURCE_ACCOUNT:user/evidence-collector"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "evidence-sdk"
        }
      }
    }
  ]
}

External ID: Prevents "confused deputy" attacks


Environment Variables

Basic Environment Mode

export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=us-east-1

Assume Role Mode

export AWS_ACCESS_KEY_ID=AKIA...         # Source credentials
export AWS_SECRET_ACCESS_KEY=...         # Source credentials
# AWS SDK will assume role specified in config

AWS Profile

export AWS_PROFILE=evidence-collection

~/.aws/credentials:

[evidence-collection]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
region = us-east-1

Collection Process

Step 1: Authenticate

Authenticating with AWS...
  → STS GetCallerIdentity
  ✓ Account: 123456789012
  ✓ User: arn:aws:iam::123456789012:user/evidence-collector
  ✓ Region: us-east-1

Step 2: Fetch IAM Password Policy

Fetching IAM password policy...
  → iam:GetAccountPasswordPolicy
  ✓ Minimum length: 14 characters
  ✓ Complexity requirements: enabled
  ✓ Expiration: 90 days

Step 3: Fetch CloudTrail Status

Fetching CloudTrail trails...
  → cloudtrail:DescribeTrails
  ✓ Found 2 trails

Checking trail status...
  → production-audit-trail
    ✓ Logging: active
    ✓ Last delivery: 2 minutes ago
  → security-trail
    ✓ Logging: active
    ✓ Last delivery: 5 minutes ago

Step 4: Fetch CloudWatch Log Groups

Fetching CloudWatch log groups...
  → logs:DescribeLogGroups
  ✓ /aws/lambda/production-api (retention: 90 days)
  ✓ /aws/lambda/production-worker (retention: 90 days)
  ✓ /aws/ecs/backend (retention: 365 days)

✓ 3 log groups checked

Common Patterns

Minimal IAM Only

sources:
  aws:
    mode: env
    region: us-east-1

Use case: Quick start, CC6.1 only


Production Single-Region

sources:
  aws:
    mode: env
    region: us-east-1
    log_groups:
      - /aws/lambda/production-*
    cloudtrail:
      trails:
        - production-audit-trail

Use case: Standard production setup


Multi-Region with Assume Role

sources:
  aws:
    mode: assume_role
    role_arn: arn:aws:iam::123456789012:role/evidence-collector
    external_id: evidence-sdk
    regions:
      - us-east-1
      - us-west-2
      - eu-west-1
    cloudtrail:
      trails:
        - global-audit-trail

Use case: Multi-region deployments, cross-account access


Troubleshooting

Access Denied (IAM Permissions)

Symptom:

✗ AWS connector failed

Error: User is not authorized to perform: iam:GetAccountPasswordPolicy (HTTP 403)

Cause: IAM user/role lacks required permissions

Solution:

  1. Check current permissions:

    aws iam get-user-policy --user-name evidence-collector --policy-name EvidenceCollection
  2. Attach required policy:

    aws iam put-user-policy --user-name evidence-collector \
      --policy-name EvidenceCollection \
      --policy-document file://evidence-policy.json
  3. Verify permissions:

    aws iam get-account-password-policy

Invalid Credentials

Symptom:

✗ AWS connector failed

Error: The security token included in the request is invalid (HTTP 403)

Causes:

  • Access key ID incorrect
  • Secret access key incorrect
  • Credentials expired (temporary credentials)

Solutions:

  1. Verify credentials are set:

    echo $AWS_ACCESS_KEY_ID
    echo $AWS_SECRET_ACCESS_KEY
  2. Test credentials:

    aws sts get-caller-identity
  3. Rotate credentials:

    • Create new access key in IAM console
    • Update environment variables
    • Delete old access key

CloudTrail Not Found

Symptom:

✗ AWS connector failed

Error: Trail 'production-audit-trail' not found in region us-east-1

Causes:

  • Trail name incorrect
  • Trail in different region
  • Trail doesn't exist

Solutions:

  1. List all trails:

    aws cloudtrail describe-trails
  2. Check trail name:

    cloudtrail:
      trails:
        - production-audit-trail  # Exact name required
  3. Check trail region:

    • CloudTrail trails are regional
    • Use regions to check multiple regions
    • Multi-region trails visible in home region only

Log Group Not Found

Symptom:

Warning: Log group '/aws/lambda/production-api' not found

Not an error, but indicates misconfiguration

Solutions:

  1. List log groups:

    aws logs describe-log-groups --log-group-name-prefix /aws/lambda
  2. Check log group name:

    • Names are case-sensitive
    • Must match exactly
    • Use wildcard: /aws/lambda/production-*
  3. Verify log group exists:

    • Application must have created logs
    • Check CloudWatch Logs console

Assume Role Failed

Symptom:

✗ AWS connector failed

Error: User is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/evidence-collector

Causes:

  • Trust policy doesn't allow source user
  • External ID mismatch
  • Role doesn't exist

Solutions:

  1. Verify role exists:

    aws iam get-role --role-name evidence-collector
  2. Check trust policy:

    aws iam get-role --role-name evidence-collector --query 'Role.AssumeRolePolicyDocument'
  3. Update trust policy:

    • Allow source user ARN in Principal
    • Match ExternalId with config
    • Ensure sts:AssumeRole action allowed

Best Practices

1. Use Dedicated IAM User

Create dedicated IAM user for evidence collection:

User name: evidence-collector Permissions: Minimal IAM policy (read-only) Access keys: Rotate annually

Don't use:

  • ❌ Admin users
  • ❌ Personal users
  • ❌ Root account

2. Enable CloudTrail in All Regions

Organization trail:

  • Enable multi-region trail
  • Enable in all accounts (AWS Organizations)
  • Enable log file validation
  • Encrypt with KMS

3. Set CloudWatch Log Retention

Standard retention:

  • Production logs: 90 days minimum (recommended: 365 days)
  • Development logs: 30 days
  • Security logs: 365+ days

Balance:

  • Compliance requirements
  • Storage costs
  • Query performance

4. Use External ID for Assume Role

Always set external_id:

sources:
  aws:
    mode: assume_role
    role_arn: arn:aws:iam::123456789012:role/evidence-collector
    external_id: evidence-sdk-production-2026

Benefits:

  • Prevents "confused deputy" attacks
  • Adds extra authentication layer
  • Best practice for cross-account access

5. Rotate Access Keys Annually

Schedule:

  1. Create new access key (January 1st)
  2. Update environment variables
  3. Test collection with new key
  4. Delete old access key

See Also