aws-ssm-params-can-read-secret
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> |
| 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) |
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}).'