CloudTrail via SDK Best Practices
Retention policy and log-integrity verification habits for CloudTrail via SDK - baseline trail setup, protecting the audit log itself, and choosing the right query tool for the job.
Busque em todas as páginas da documentação
Retention policy and log-integrity verification habits for CloudTrail via SDK - baseline trail setup, protecting the audit log itself, and choosing the right query tool for the job.
Each rule is stated positively with a one-line reason and how to enforce it via the SDK.
IsOrganizationTrail and IsMultiRegionTrail together give one trail full account coverage instead of a patchwork of per-account, per-region trails.StartLogging right after CreateTrail, every time. A trail with no StartLogging call delivers nothing, and this is a silent gap unless you check GetTrailStatus.GetTrailStatus after setup. IsLogging and LatestDeliveryTime confirm the trail is actually writing logs, not just configured.LookupEvents is a convenient fallback, not durable audit storage - a trail is still required for real retention.# --- Python (boto3) ---
client.create_trail(Name="baseline", S3BucketName=bucket,
IsMultiRegionTrail=True, IsOrganizationTrail=True,
EnableLogFileValidation=True)
client.start_logging(Name="baseline")EnableLogFileValidation=True costs nothing extra and gives you a hash-chain you can verify if tampering is ever suspected.cloudtrail:StopLogging and cloudtrail:DeleteTrail broadly. An attacker's first move is often disabling the audit trail itself - restrict these to a narrow, monitored break-glass role.StopLogging, DeleteTrail, or UpdateTrail event. These are high-signal indicators regardless of who triggers them - wire them to EventBridge, don't just log them.# --- Python (boto3) ---
# Alert if anyone tries to stop or delete the audit trail.
import json
events_client = boto3.client("events")
events_client.put_rule(
Name="alert-on-trail-tampering",
EventPattern=json.dumps({
"source": ["aws.cloudtrail"],
"detail": {"eventName": ["StopLogging", "DeleteTrail", "UpdateTrail"]},
}),
State="ENABLED",
)// --- TypeScript (AWS SDK v3) ---
// Alert if anyone tries to stop or delete the audit trail.
import { EventBridgeClient, PutRuleCommand } from "@aws-sdk/client-eventbridge";
const events = new EventBridgeClient({});
await events.send(new PutRuleCommand({
Name: "alert-on-trail-tampering",
EventPattern: JSON.stringify({
source: ["aws.cloudtrail"],
detail: { eventName: ["StopLogging", "DeleteTrail", "UpdateTrail"] },
}),
State: "ENABLED",
}));LookupEvents only within the 90-day window. It's fast and free, but silently returns nothing for older time ranges - don't mistake an empty result for "nothing happened."LookupEvents pages is a sign Lake is the better tool.LookupAttributes filter per call, and plan for it. Combining filters requires either post-filtering client-side or issuing separate calls.LookupEvents or Lake query spanning more than a few minutes. A single page can miss most matches in an active account.GetQuery in a tight loop wastes calls without speeding up completion.WHERE clause over years of retention costs far more than necessary.GetTrailStatus on a schedule, not just at setup. A delivery failure (bucket policy drift, KMS key rotation issue) can silently stop logging long after initial setup.UpdateTrail calls should be rare and intentional; alert on them the same way you'd alert on StopLogging.TestEventPattern. A subtly malformed pattern silently matches nothing, giving false confidence in alerting coverage.An organization-wide, multi-region trail with log file validation enabled, created and started on day one. It's the foundation everything else in this list builds on.
Disabling the audit trail is frequently one of the first things an attacker with sufficient access attempts, since it removes the evidence of everything that follows.
Once a query needs to go past 90 days, needs SQL-style joins or aggregation, or you find yourself repeatedly paginating and filtering LookupEvents results client-side.
It's not automatic - you (or a scheduled job) verify the digest-file hash chain periodically, ideally via aws cloudtrail validate-logs, rather than assuming enabling the setting is the whole job.
Scope query time ranges and WHERE clauses tightly, set event data store retention to match actual need rather than the maximum available, and enable data events selectively rather than account-wide.
No. Enable data events for buckets holding sensitive or regulated data specifically - blanket-enabling across every bucket usually isn't cost-justified and adds noise.
On a recurring cadence, not once at setup - delivery can silently fail due to bucket policy or KMS drift, and EventBridge patterns can drift out of sync with renamed or new API operations.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Revisado por Chris St. John·Última atualização: 25 de jul. de 2026