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.

derived aws emits CanDelete

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} HasPermission {'trail': None}

where

node_type(?trail) == LoggingService ?trail.provider_type == 'AWS::CloudTrail::Trail' effective_action(?principal, ?trail) includes 'cloudtrail:DeleteTrail'

emit

source typeIdentity
target typeLoggingService
source?principal
target?trail
permissionscloudtrail:DeleteTrail
conditionsiam_permission scp_or_org_policy
state logicACTIVE 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.'
move · open · esc close