It's not really clear in the documentation but to limit ssm:SendCommand
, you must use the Resource
field to specify both what document(s) the IAM user is allowed to run and what instance(s) you allow commands to be run on.
The user would see all instances when trying to run a command but will only be able to execute commands for the EC2 instance IDs specified in the IAM policy.
You can specify the policy to allow any instance like below if needs be or specify a limited list of instance IDs in line with the standard security advice of granting least privilege in IAM policies.
As to why the AWS managed document works, it's probably some internal magic 🤷♂️
This should work:
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"ssm:SendCommand","Resource":["arn:aws:ec2:us-west-2:999999999999:instance/*","arn:aws:ssm:us-west-2:999999999999:document/AWS-RunShellScript"]}]}
Slightly similar unexpected behaviour (not really clear in the documentation either): if you define 2 blocks for the same action, they are considered by AWS as just one, eg:
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"ssm:SendCommand","Resource":["arn:aws:ec2:us-west-2:999999999999:instance/i-1","arn:aws:ssm:us-west-2:999999999999:document/AWS-RunShellScript"]},{"Effect":"Allow","Action":"ssm:SendCommand","Resource":["arn:aws:ec2:us-west-2:999999999999:instance/i-2","arn:aws:ssm:us-west-2:999999999999:document/AWS-SecondDoc"]}]}
will allow you to connect to i-1 with both "AWS-RunShellScript" and "AWS-SecondDoc" (and same for i-2).