This check fires when no CloudTrail trail is capturing management events in your AWS account, which means API activity like IAM changes, security group edits, and console logins go unrecorded. Create a multi-region trail that logs management events and ship the logs to a locked-down S3 bucket.
CloudTrail is the audit log of your AWS account. Every time someone creates an access key, deletes a security group, assumes a role, or disables logging, that action passes through the AWS API, and CloudTrail is the service that records it. If no trail is configured to capture management events, you lose visibility into all of that activity. When something goes wrong, whether it is a misconfiguration or an active intrusion, you have nothing to investigate.
The account_cloudtrailevents check flags accounts where no trail is logging management events. This is one of the most foundational findings in any cloud security baseline, and it is also one of the most commonly missed in accounts that were spun up quickly or inherited from another team.
What this check detects
The check inspects your CloudTrail configuration and looks for at least one trail that is actively logging management events. Management events (also called control plane events) record operations performed on resources in your account, such as:
- IAM actions like
CreateUser,AttachRolePolicy, andCreateAccessKey - Network changes like
AuthorizeSecurityGroupIngressandCreateRoute - Configuration changes to CloudTrail, GuardDuty, and Config themselves
- Console sign-in events and role assumption via STS
The check fails when one of the following is true:
- No CloudTrail trail exists at all
- A trail exists but logging is turned off
- A trail exists and is logging, but its event selectors exclude management events
Note: CloudTrail keeps a 90-day Event history of management events for free even without a trail, but it is read-only, cannot be exported to S3, and is not configurable. It is not a substitute for a real trail. Relying on it means you have no long-term, tamper-evident record.
Why it matters
Without management event logging, you are flying blind on every change made to your account. The business and security impact falls into a few clear buckets.
You cannot investigate incidents
Imagine an access key gets leaked in a public Git repo. An attacker uses it to create a new IAM user with admin permissions, then disables GuardDuty and starts launching EC2 instances for crypto mining. Without CloudTrail, you have no record of who created that user, when, from what IP, or what API calls followed. Incident response turns into guesswork, and you cannot establish a timeline or scope the blast radius.
Attackers actively target logging
Disabling or deleting CloudTrail is a textbook step in cloud attacks. It maps directly to the MITRE ATT&CK technique Impair Defenses: Disable or Modify Tools. If you have no trail in the first place, the attacker does not even need to bother. The absence of logging is the gap they are hoping for.
Warning: Even when a trail exists, an attacker with sufficient permissions can call StopLogging or DeleteTrail. This is why you should alert on those specific API calls and protect the trail with strong IAM controls, covered below.
Compliance failures
Nearly every compliance framework treats account-level audit logging as table stakes. CIS AWS Foundations Benchmark 3.1 requires CloudTrail to be enabled in all regions. PCI DSS, SOC 2, HIPAA, and ISO 27001 all expect a verifiable audit trail of administrative activity. A missing trail is a finding auditors flag immediately, and it can hold up certification.
How to fix it
The fix is to create a multi-region trail that logs management events and delivers them to a dedicated S3 bucket. You can do this from the console, the CLI, or infrastructure as code. Whichever you choose, the same principles apply: multi-region, management events on, logs in a locked-down bucket, log file validation enabled.
Option 1: AWS CLI
First, create an S3 bucket to hold the logs. Use a dedicated bucket, not one shared with application data.
aws s3api create-bucket \
--bucket my-org-cloudtrail-logs \
--region us-east-1
Attach a bucket policy that grants CloudTrail permission to write logs. Replace the account ID and bucket name.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AWSCloudTrailAclCheck",
"Effect": "Allow",
"Principal": { "Service": "cloudtrail.amazonaws.com" },
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::my-org-cloudtrail-logs"
},
{
"Sid": "AWSCloudTrailWrite",
"Effect": "Allow",
"Principal": { "Service": "cloudtrail.amazonaws.com" },
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::my-org-cloudtrail-logs/AWSLogs/111122223333/*",
"Condition": {
"StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" }
}
}
]
}
Now create the trail, enable multi-region coverage, turn on log file validation, and start logging.
aws cloudtrail create-trail \
--name org-management-trail \
--s3-bucket-name my-org-cloudtrail-logs \
--is-multi-region-trail \
--enable-log-file-validation
aws cloudtrail start-logging \
--name org-management-trail
Confirm management events are actually being captured by checking the event selectors. By default a new trail records all management events, but it is worth verifying.
aws cloudtrail get-event-selectors \
--trail-name org-management-trail
You should see ReadWriteType set to All and IncludeManagementEvents set to true.
Option 2: AWS Console
- Open the CloudTrail console and choose Create trail.
- Give the trail a name, for example
org-management-trail. - Under Storage location, create a new S3 bucket or select an existing dedicated one.
- Enable Log file SSE-KMS encryption and Log file validation.
- Leave Apply trail to all regions enabled.
- On the next screen, under Event type, ensure Management events is checked and the API activity is set to Read and Write.
- Review and create the trail. Logging starts automatically.
Option 3: Terraform
If you manage infrastructure as code, define the trail and bucket so the configuration is version controlled and reproducible.
resource "aws_s3_bucket" "cloudtrail" {
bucket = "my-org-cloudtrail-logs"
}
resource "aws_cloudtrail" "main" {
name = "org-management-trail"
s3_bucket_name = aws_s3_bucket.cloudtrail.id
is_multi_region_trail = true
enable_log_file_validation = true
include_global_service_events = true
event_selector {
read_write_type = "All"
include_management_events = true
}
}
Tip: In AWS Organizations, create a single organization trail from the management account. It automatically applies to every member account, including new ones, so you never have to remember to enable CloudTrail again. Add --is-organization-trail to the CLI command or set is_organization_trail = true in Terraform.
Warning: CloudTrail management events for the first trail in an account are free, but S3 storage and any KMS key usage carry cost. The bigger cost driver is usually data events (S3 object-level and Lambda invocation logging), which are billed per event and can add up fast in busy accounts. Enable data events deliberately, not by default.
How to prevent it from happening again
Fixing the trail once is not enough. You want logging to be guaranteed across every account, today and in the future.
Use an organization trail
As mentioned above, an organization trail created from the management account covers all current and future member accounts automatically. This is the single most effective prevention because it removes the manual step entirely.
Block changes with a Service Control Policy
Attach an SCP that denies stopping or deleting CloudTrail to everyone except a break-glass role. This stops both attackers and well-meaning engineers from turning logging off.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyCloudTrailTampering",
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"cloudtrail:UpdateTrail"
],
"Resource": "*",
"Condition": {
"StringNotLike": {
"aws:PrincipalArn": "arn:aws:iam::*:role/BreakGlassAdmin"
}
}
}
]
}
Gate infrastructure in CI/CD
If you provision accounts through Terraform or CloudFormation, add a policy-as-code check to your pipeline. Tools like Checkov, tfsec, or OPA can fail a build when a trail is missing or misconfigured. A Checkov run, for example, enforces this out of the box:
checkov -d . --check CKV_AWS_67 # Ensure CloudTrail has log file validation
checkov -d . --check CKV_AWS_36 # Ensure CloudTrail logs management events
Alert on tampering
Send CloudTrail logs to CloudWatch Logs and create a metric filter plus alarm on StopLogging, DeleteTrail, and UpdateTrail calls. This is CIS control 4.5 and gives you a near real-time signal if someone touches logging.
Tip: Run the account_cloudtrailevents check on a schedule in Lensix so a regression is caught within hours rather than at the next audit. Continuous detection closes the gap between someone disabling a trail and you finding out.
Best practices
- One organization trail, multi-region. Centralize logging instead of managing per-account trails that drift out of sync.
- Dedicated, locked-down log bucket. Store logs in a separate account if possible, block public access, and enable bucket versioning and MFA delete.
- Enable log file validation. This lets you prove logs were not altered after delivery, which matters for forensics and compliance.
- Encrypt with a customer-managed KMS key. Control who can read the logs and detect attempts to decrypt them.
- Forward to CloudWatch Logs or a SIEM. S3 is durable storage, but real-time analysis needs the logs streamed somewhere queryable.
- Add data events selectively. Turn on S3 and Lambda data events for sensitive buckets and functions, but be mindful of cost and noise.
- Treat logging as protected infrastructure. Guard it with SCPs and IAM so that disabling it is hard and noisy.
Getting CloudTrail right is the foundation everything else in your security program builds on. GuardDuty, Security Hub, anomaly detection, and incident response all depend on having a complete, trustworthy record of what happened in your account. Fix this check first, then make sure it can never quietly regress.

