Search code examples
amazon-web-servicesamazon-ec2amazon-iamssm

How-to restrict AWS IAM User to be able execute "SSM Run Commands" on a specific EC2 server


I am trying to setup and assign a policy so that a user can only trigger AWS Systems Manager Services (SSM) Run Commands on only authorized or assigned EC2 instances to them.

To do this, I am following instructions from https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/sysman-configuring-access-iam-create.html and as per it, I created below custom policy with provisioning access for only 1 EC2 instance:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ssm:ListDocuments",
                "ssm:DescribeDocument*",
                "ssm:GetDocument",
                "ssm:DescribeInstance*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Action": "ssm:SendCommand",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0",
                "arn:aws:s3:::test-ssm-logs/TESTSERV",
                "arn:aws:ssm:us-east-1:123456789012:document/AWS-RunPowerShellScript"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/Name": "TESTSERV"
                }
            }
        },
        {
            "Action": [
                "ssm:CancelCommand",
                "ssm:ListCommands",
                "ssm:ListCommandInvocations"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Action": "ec2:DescribeInstanceStatus",
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

After I assigned above policy to a test user and when I log in using it and navigate to "Run Command", under Target Instances I see other EC2 instances as well and I am even able to execute commands to them as well. Shouldn't the user only see the 1 instance that is specified in above policy?

I do not understand what am I doing wrong here and how to fix it? Appreciate your help.

Thanks!


I have below IAM policy assigned to all my EC2 system instances:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeAssociation",
                "ssm:GetDeployablePatchSnapshotForInstance",
                "ssm:GetDocument",
                "ssm:GetParameters",
                "ssm:ListAssociations",
                "ssm:ListInstanceAssociations",
                "ssm:PutInventory",
                "ssm:UpdateAssociationStatus",
                "ssm:UpdateInstanceAssociationStatus",
                "ssm:UpdateInstanceInformation"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2messages:AcknowledgeMessage",
                "ec2messages:DeleteMessage",
                "ec2messages:FailMessage",
                "ec2messages:GetEndpoint",
                "ec2messages:GetMessages",
                "ec2messages:SendReply"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:PutMetricData"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstanceStatus"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ds:CreateComputer",
                "ds:DescribeDirectories"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts",
                "s3:ListBucketMultipartUploads"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::amazon-ssm-packages-*"
        }
    ]
}

Also, I have below IAM policy assigned to test user to so that they can Start/Stop/Restart EC2 instances:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:Describe*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances",
                "ec2:RebootInstances"
            ],
            "Resource": "arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0",
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/Name": "TESTSERV"
                }
            }
        }
    ]
}

Solution

  • I was able to make this work by adjusting policy as below:

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "ssm:ListDocuments",
                    "ssm:DescribeDocument*",
                    "ssm:GetDocument",
                    "ssm:DescribeInstance*"
                ],
                "Effect": "Allow",
                "Resource": "*"
            },
            {
                "Action": "ssm:SendCommand",
                "Effect": "Allow",
                "Resource": [
                    "arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0",
                    "arn:aws:s3:::nsight-ssm-logs/TESTSERV",
                    "arn:aws:ssm:us-east-1::document/AWS-RunPowerShellScript"
                ]
            },
            {
                "Action": [
                    "ssm:CancelCommand",
                    "ssm:ListCommands",
                    "ssm:ListCommandInvocations"
                ],
                "Effect": "Allow",
                "Resource": "*"
            },
            {
                "Action": "ec2:DescribeInstanceStatus",
                "Effect": "Allow",
                "Resource": "*"
            }
        ]
    }
    

    My requirement was to only allow execution of PowerShell scripts so the line:

    "arn:aws:ssm:us-east-1::document/AWS-RunPowerShellScript"

    You can replace AWS-RunPowerShellScript with * to allow all commands.

    Also, the EC2 Role assignment was necessary since without it I couldn't see any instances under Run Command.

    Please also know that the user would see all instances under Run Command but will only be able to execute commands for the EC2 instances for which the policies are assigned to, user account. I do not think there is any option to suppress this.

    Thanks for your contribution and helpful tips.