aws-cloudtrail-delete-trail
Principal with cloudtrail:DeleteTrail can permanently destroy a trail, creating an irreversible audit blind spot. Existing S3 log objects are unaffected; only future event capture is eliminated.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?trail) ==
LoggingService
?trail.provider_type == 'AWS::CloudTrail::Trail'
effective_action(?principal, ?trail) includes 'cloudtrail:DeleteTrail'
emit
| source type | Identity |
|---|---|
| target type | LoggingService |
| source | ?principal |
| target | ?trail |
| permissions | cloudtrail:DeleteTrail |
| conditions | iam_permission scp_or_org_policy |
| state logic | ACTIVE when the principal holds cloudtrail:DeleteTrail with no effective deny on the trail ARN scope. BLOCKED when an SCP or permission boundary denies cloudtrail:DeleteTrail or cloudtrail:*. Organization trails: manageable only from the management account in the trail's home region; emit BLOCKED for member-account principals or when the caller's region differs from the trail's HomeRegion. Note: deletion of an org trail silences the entire organization simultaneously — annotate IsOrganizationTrail=true trails with elevated impact (analyst note, not a separate edge type). |
Narrative
{principal.name} can permanently delete {trail.name} (cloudtrail:DeleteTrail), eliminating future audit capture for the trail's scope. This is an anti-forensic / cover-tracks primitive with no accompanying access gain.
Raw rule rules/derived/aws/cloudtrail.yaml
id: aws-cloudtrail-delete-trail
emits: CanDelete
description: Principal with cloudtrail:DeleteTrail can permanently destroy a trail, creating an irreversible
audit blind spot. Existing S3 log objects are unaffected; only future event capture is eliminated.
match:
- - principal: null
- HasPermission
- trail: null
where:
- node_type(?trail) == LoggingService
- ?trail.provider_type == 'AWS::CloudTrail::Trail'
- effective_action(?principal, ?trail) includes 'cloudtrail:DeleteTrail'
emit:
source_type: Identity
target_type: LoggingService
source: ?principal
target: ?trail
permissions:
- cloudtrail:DeleteTrail
conditions:
- iam_permission
- scp_or_org_policy
state_logic: "ACTIVE when the principal holds cloudtrail:DeleteTrail with no effective deny on the trail\
\ ARN scope. BLOCKED when an SCP or permission boundary denies cloudtrail:DeleteTrail or cloudtrail:*.\
\ Organization trails: manageable only from the management account in the trail's home region; emit\
\ BLOCKED for member-account principals or when the caller's region differs from the trail's HomeRegion.\
\ Note: deletion of an org trail silences the entire organization simultaneously \u2014 annotate IsOrganizationTrail=true\
\ trails with elevated impact (analyst note, not a separate edge type)."
confidence: 0.97
derived_from:
- HasPermission(?principal, cloudtrail:DeleteTrail, ?trail)
false_positive_note: "DEFENSE EVASION ONLY. DeleteTrail is permanent and higher-impact than StopLogging,\
\ but equally does not grant access to any resource. Do NOT emit CanEnterAccount or any escalation\
\ edge from this capability. Log objects already written to S3 survive trail deletion \u2014 the attacker\
\ must separately target the S3 bucket to destroy historical evidence. SCP deny on cloudtrail:DeleteTrail\
\ is common in security-baseline accounts and renders this edge BLOCKED. NOTE: CanDelete edges have\
\ traversal: {walkable: false} in edges.yaml, so this edge will not appear in default attack paths;\
\ this is correct for destructive-only operations."
narrative: '{principal.name} can permanently delete {trail.name} (cloudtrail:DeleteTrail), eliminating
future audit capture for the trail''s scope. This is an anti-forensic / cover-tracks primitive with
no accompanying access gain.'