aws-acm-can-export-key
match (effective permission)
{
"action": "acm:ExportCertificate",
"resource_type": "AWS::CertificateManager::Certificate"
}
emit
| source type | Identity |
|---|---|
| source | <principal> |
| target | <certificate node> |
| permissions | acm:ExportCertificate |
| conditions | condition_expression |
| state logic | if ?cert.exportable == true: ACTIVE elif ?cert.exportable == false: BLOCKED(non_exportable) else: CONDITIONAL(condition_expression) # exportability unresolved from collection |
Narrative
{principal.name} can export certificate {cert.name} (acm:ExportCertificate) - private key retrievable only if the cert's exportable flag is set (Type==PRIVATE, or a public cert requested exportable on/after 2025-06-17).
Raw rule rules/explicit/aws-acm.yaml
id: aws-acm-can-export-key
emits: CanExportKey
applies_to:
- aws
match_effective_permission:
action: acm:ExportCertificate
resource_type: AWS::CertificateManager::Certificate
emit:
source_type: Identity
source: <principal>
target: <certificate node>
api_source: iam:SimulatePrincipalPolicy | policy evaluation
permissions:
- acm:ExportCertificate
conditions:
- condition_expression
evidence_field: DescribeCertificate exportable flag (Type==PRIVATE OR a public cert requested exportable)
state_logic: 'if ?cert.exportable == true: ACTIVE elif ?cert.exportable == false: BLOCKED(non_exportable)
else: CONDITIONAL(condition_expression) # exportability unresolved from collection'
false_positive_note: "The gate is the PER-CERT exportable flag, NOT the certificate Type. As of 2025-06-17\
\ AWS launched EXPORTABLE PUBLIC certificates: a public (AMAZON_ISSUED) cert requested with the exportable\
\ option CAN have its private key exported via acm:ExportCertificate. So do NOT hardcode BLOCKED for\
\ Type in [AMAZON_ISSUED, IMPORTED] \u2014 that false-negatives on exportable public certs. exportable==false\
\ (all public certs issued before 2025-06-17, and any cert not requested exportable) -> BLOCKED(non_exportable).\
\ Do NOT confuse with acm:GetCertificate, which returns only the public cert + chain (no private key)\
\ and must NOT produce this edge. The Passphrase parameter is attacker-chosen and is NOT a gate; export\
\ does NOT require kms:Decrypt on aws/acm, so do NOT add a key_permission condition. An SCP/boundary\
\ denying acm:ExportCertificate -> BLOCKED(scp_or_org_policy)."
narrative: "{principal.name} can export certificate {cert.name} (acm:ExportCertificate) \u2014 private\
\ key retrievable only if the cert's exportable flag is set (Type==PRIVATE, or a public cert requested\
\ exportable on/after 2025-06-17)."