aws-ssm-params-can-read-secret

explicit aws emits CanReadSecret

match (effective permission)

{ "action": [ "ssm:GetParameter", "ssm:GetParameters", "ssm:GetParameterHistory" ], "resource_type": "AWS::SSM::Parameter" }

where

target parameter Type == SecureString

emit

target typeSecret
source<principal>
target<Secret node for the SecureString>
permissionsssm:GetParameter ssm:GetParameters ssm:GetParameterHistory kms:Decrypt
conditionskey_permission
state logicif ?param.kms_key is the AWS-managed alias/aws/ssm (or its key ARN) and principal.account == param.account: ACTIVE (same-account SSM read implies decrypt on the AWS-managed key); elif principal has CanDecrypt on ?param.kms_key (the CMK): ACTIVE; else: CONDITIONAL(key_permission)

Narrative

{principal.name} can read SecureString {param.name} (ssm:GetParameter[s] / ssm:GetParameterHistory with WithDecryption + kms:Decrypt on {param.kms_key}).

Raw rule rules/explicit/aws-ssm-params.yaml

id: aws-ssm-params-can-read-secret
emits: CanReadSecret
applies_to:
- aws
match_effective_permission:
  action:
  - ssm:GetParameter
  - ssm:GetParameters
  - ssm:GetParameterHistory
  resource_type: AWS::SSM::Parameter
where:
- target parameter Type == SecureString
emit:
  target_type: Secret
  source: <principal>
  target: <Secret node for the SecureString>
  api_source: iam:SimulatePrincipalPolicy | policy evaluation
  permissions:
  - ssm:GetParameter
  - ssm:GetParameters
  - ssm:GetParameterHistory
  - kms:Decrypt
  conditions:
  - key_permission
  state_logic: 'if ?param.kms_key is the AWS-managed alias/aws/ssm (or its key ARN) and principal.account
    == param.account: ACTIVE (same-account SSM read implies decrypt on the AWS-managed key); elif principal
    has CanDecrypt on ?param.kms_key (the CMK): ACTIVE; else: CONDITIONAL(key_permission)'
  false_positive_note: 'Only SecureString parameters are Secret nodes. For a CMK-encrypted SecureString,
    ssm:GetParameter[s]/GetParameterHistory alone is NOT enough: without kms:Decrypt on that customer-managed
    key the caller receives ciphertext only -> CONDITIONAL(key_permission). Only the AWS-managed alias/aws/ssm
    key makes same-account decrypt implicit. GetParameterHistory additionally exposes rotated-out versions
    whose credentials may still authenticate.'
  narrative: '{principal.name} can read SecureString {param.name} (ssm:GetParameter[s] / ssm:GetParameterHistory
    with WithDecryption + kms:Decrypt on {param.kms_key}).'
move · open · esc close