aws-acm-exposes-private-key

An exportable ACM certificate exposes its private key to any principal that can export it.

derived aws emits ExposesCredential

match

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

{'principal': None} CanExportKey {'cert': None}

where

node_class(?cert) == Secret node_subtype(?cert) == Certificate ?cert.exportable == true # per-cert flag: Type==PRIVATE OR a public cert requested exportable (>=2025-06-17)

emit

source?cert
target<ExternalIdentity: the out-of-AWS server/DNS principal for ?cert.DomainName + SANs>
conditionscondition_expression
state logicinherit state from the contributing explicit CanExportKey edge (aws-acm-can-export-key): ACTIVE only when ?cert.exportable == true AND acm:ExportCertificate is effective; BLOCKED(non_exportable) when exportable == false; CONDITIONAL(condition_expression) when the flag is unresolved from collection.

Narrative

Certificate {cert.name} exposes its private key: any principal able to export it can impersonate the TLS server for {cert.DomainName} and its SANs.

Raw rule rules/derived/aws/acm.yaml

id: aws-acm-exposes-private-key
emits: ExposesCredential
description: An exportable ACM certificate exposes its private key to any principal that can export it.
match:
- - principal: null
  - CanExportKey
  - cert: null
where:
- node_class(?cert) == Secret
- node_subtype(?cert) == Certificate
- '?cert.exportable == true  # per-cert flag: Type==PRIVATE OR a public cert requested exportable (>=2025-06-17)'
emit:
  source: ?cert
  target: '<ExternalIdentity: the out-of-AWS server/DNS principal for ?cert.DomainName + SANs>'
  permissions: []
  conditions:
  - condition_expression
  state_logic: 'inherit state from the contributing explicit CanExportKey edge (aws-acm-can-export-key):
    ACTIVE only when ?cert.exportable == true AND acm:ExportCertificate is effective; BLOCKED(non_exportable)
    when exportable == false; CONDITIONAL(condition_expression) when the flag is unresolved from collection.'
  confidence: min(contributing_confidences)
  derived_from:
  - <CanExportKey(acm:ExportCertificate) explicit edge_id (aws-acm-can-export-key)>
  false_positive_note: "Not an escalation by itself; expresses that exporting the key equals holding credentials\
    \ that impersonate the certificate's DNS/TLS server identity. Emitted ONLY for certs whose per-cert\
    \ exportable flag is true \u2014 this now INCLUDES public (AMAZON_ISSUED) certs requested exportable\
    \ on/after 2025-06-17, not just Type==PRIVATE. NEVER emitted for certs whose exportable flag is false\
    \ (all public certs before 2025-06-17, and any cert not requested exportable). Do NOT gate on Type\
    \ alone \u2014 that would false-negative on exportable public certs. The target is an EXTERNAL (out-of-AWS)\
    \ server identity (ExternalIdentity), not an AWS IAM principal \u2014 do not resolve it to an account\
    \ role."
  narrative: 'Certificate {cert.name} exposes its private key: any principal able to export it can impersonate
    the TLS server for {cert.DomainName} and its SANs.'
move · open · esc close