An auditor asks: "Show who disabled logging in production last quarter." You open three accounts, find CloudTrail off in one, logs scattered in local S3 buckets, and AWS Config never enabled in the region where the incident happened.
Audit-ready logging is not "turn on CloudTrail somewhere." It is organization-wide trails, immutable central storage, Config recorders in every active region, and queries you have tested before the audit.
This article shows how to build an audit-ready CloudTrail and AWS Config baseline with AWS CLI examples and verification checks.
Who this is for: Platform and DevSecOps engineers preparing for SOC 2, ISO 27001, internal security reviews on AWS.
Prerequisites:
- AWS Organizations management account access
- Dedicated log archive account recommended
- S3 bucket for centralized logs with encryption
TL;DR
- Organization CloudTrail should write to a central, encrypted S3 bucket with log file validation turned on.
- AWS Config needs a recorder and delivery channel in every active region, plus an aggregator for org-wide visibility.
- Managed rules or a conformance pack should cover critical controls like public S3 access, root MFA, and CloudTrail enabled.
- Saved queries in Athena or CloudTrail Lake should answer common audit questions without manual console digging.
- Block log tampering with bucket policy, MFA delete, and SCP denies on
StopLogging.
Why Per-Account Ad-Hoc Logging Fails
| Gap | Audit impact |
|---|---|
| Trail only in one region | Actions in other regions invisible |
| Logs in member account buckets | Deleted during account compromise |
| No Config | Cannot prove continuous compliance state |
| No saved queries | Week-long manual click-through during audit |
Key idea: Detective controls must survive the account they monitor.
Create the Log Archive Account and Bucket
In the log archive account:
aws s3api create-bucket \
--bucket org-cloudtrail-logs-ACCOUNT_ID \
--region eu-west-1 \
--create-bucket-configuration LocationConstraint=eu-west-1
Enable versioning, encryption, and block public access:
aws s3api put-public-access-block \
--bucket org-cloudtrail-logs-ACCOUNT_ID \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
Use a CMK in the log archive account for bucket encryption.
Enable Organization CloudTrail
From the management account:
aws cloudtrail create-trail \
--name organization-trail \
--s3-bucket-name org-cloudtrail-logs-ACCOUNT_ID \
--is-organization-trail \
--enable-log-file-validation
aws cloudtrail start-logging --name organization-trail
Verify all regions and management events:
aws cloudtrail put-event-selectors \
--trail-name organization-trail \
--event-selectors '[{
"ReadWriteType": "All",
"IncludeManagementEvents": true
}]'
Bucket policy must allow the CloudTrail service to write; use the AWS documentation template for organization trails.
Enable AWS Config in Active Regions
For each region in use, in the member or delegated admin account:
aws configservice put-configuration-recorder \
--configuration-recorder name=default,roleARN=arn:aws:iam::ACCOUNT_ID:role/config-role \
--recording-group allSupported=true,includeGlobalResourceTypes=true
aws configservice put-delivery-channel \
--delivery-channel name=default,s3BucketName=org-config-snapshots-ACCOUNT_ID
aws configservice start-configuration-recorder --configuration-recorder-name default
Use AWS Config aggregators for org-wide view:
aws configservice put-configuration-aggregator \
--configuration-aggregator-name org-aggregator \
--account-aggregation-sources AccountIds=111111111111,222222222222,333333333333
Deploy Managed Rules or a Conformance Pack
Example critical rules:
| Rule | Proves |
|---|---|
cloudtrail-enabled |
Trail active |
s3-bucket-public-read-prohibited |
No public data leaks |
root-account-mfa-enabled |
Root protected |
encrypted-volumes |
EBS encryption default |
Deploy conformance pack (example):
aws configservice put-conformance-pack \
--conformance-pack-name baseline-security \
--template-body file://conformance-pack.yaml \
--delivery-s3-bucket org-config-snapshots-ACCOUNT_ID
Protect Logs From Tampering
SCP on workload OUs (see SCP tutorial):
{
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"s3:DeleteBucket",
"s3:PutBucketPolicy"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:PrincipalAccount": ["LOG_ARCHIVE_ACCOUNT_ID"]
}
}
}
Restrict S3 delete on log buckets to break-glass roles only.
Build Saved Queries
CloudTrail Lake or Athena query, who changed security groups:
SELECT eventTime, userIdentity.arn, eventSource, eventName, sourceIPAddress
FROM cloudtrail_logs
WHERE eventName = 'AuthorizeSecurityGroupIngress'
AND eventTime > current_timestamp - interval '7' day
ORDER BY eventTime DESC;
Save as security-group-changes. Run weekly in security sync.
Tabletop Verification
Run these scenarios:
- Create test IAM user with access key, appears in CloudTrail within 15 minutes.
- Toggle public S3 block; Config flags non-compliance.
- Attempt
StopLoggingfrom workload account, denied by SCP.
Document results in docs/audit-evidence.md.
How to Verify the Baseline
| Check | Command / location |
|---|---|
| Org trail logging | aws cloudtrail get-trail-status --name organization-trail |
| Log validation | Trail settings show LogFileValidationEnabled: true
|
| Config recording | aws configservice describe-configuration-recorder-status |
| Aggregator | Config console → Aggregators → all accounts green |
When This Breaks Down
- Cost at scale: high-volume APIs fill S3, use data events selectively, lifecycle to Glacier.
- Multi-region delay: Config and CloudTrail are regional; enable every region you operate in.
- Delegated admin confusion: Security Hub admin ≠ Config aggregator admin; document roles.
- Evidence without process: Logs exist, but nobody runs queries until audit week.
Conclusion
In this tutorial, you learned how to build audit-ready CloudTrail and AWS Config controls: organization trail, central S3, Config recorders, conformance rules, tamper protection, and saved queries.
Use it as evidence of how you design controls that survive account compromise, prove compliance, and turn audit questions into repeatable checks.

Top comments (0)