Skip to content

Policy to allow Session Manager resource condition not working

0

I have setup this policy, and while the session works, the condition isn't restricting to that one host. Using the policy generator, I found I had to add the sts:getcalleridentity, but the policy generator also included the ssm:StartSession. If ssm:StartSession in the bottom is removed, or the sts:getcalleridentity is moved elsewhere in the policy, the session won't connect. I tried restricting the resource in the bottom part but it also doesn't work.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:StartSession",
                "ssm:DescribeInstanceInformation",
                "ssm:GetParameters",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:CreateControlChannel"
            ],
            "Resource": [
                "arn:aws:ec2:ap-southeast-1:111111111111:instance/i-yyyyyyyyyyyyyyyyy",
                "arn:aws:ssm:ap-southeast-1:111111111111:document/SSM-SessionManagerRunShell",
                "arn:aws:ssm:ap-southeast-1::document/AWS-StartPortForwardingSessionToRemoteHost"
            ],
            "Condition": {
                "StringEquals": {
                    "ssm:resourceTag/host": "our-rds.yyyyyyyyyyyy.ap-southeast-1.rds.amazonaws.com"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:ResumeSession",
                "ssm:TerminateSession"
            ],
            "Resource": "arn:aws:ssm:*:*:session/${aws:userid}-*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:StartSession",
                "sts:GetCallerIdentity"
            ],
            "Resource": "*"
        }
    ]
}


asked a year ago1.3K views
3 Answers
0

The issue with your policy is that the resource condition is not being applied effectively due to the structure of your policy. Here's an explanation of the problem and how to fix it:

  1. The condition you've set up in the first statement block is correct, but it's being overridden by the last statement block that allows "ssm:StartSession" on all resources ("Resource": "*").

  2. The "sts:GetCallerIdentity" action doesn't require any specific resource, so it can be separated from the "ssm:StartSession" action.

  3. To fix this, you should remove the "ssm:StartSession" action from the last statement block and keep it only in the first block where you have the condition applied.

Here's how you can restructure your policy to make the condition work as intended:

  1. Keep the first statement block as is, with the condition applied to the specific resources.
  2. Keep the second statement block for session management (resume and terminate) as is.
  3. Create a new statement block just for "sts:GetCallerIdentity" with "Resource": "*".

This structure will ensure that the "ssm:StartSession" action is only allowed on the specified instance and with the specified tag condition. The "sts:GetCallerIdentity" action will be allowed separately without interfering with the Session Manager restrictions.

Remember to test the policy after making these changes to ensure it works as expected. If you still encounter issues, double-check that the instance you're trying to connect to has the correct tag ("host": "our-rds.yyyyyyyyyyyy.ap-southeast-1.rds.amazonaws.com") applied to it.
Sources
Use Session Manager to control access to your instances | AWS re:Post
Sample IAM policies for Session Manager - AWS Systems Manager
Add Session Manager permissions to an existing IAM role - AWS Systems Manager

answered a year ago
  • As mentioned, but not picked up by the AI, is I tried keeping the 3rd block with just sts:GetCallerIdentity; but am still not allowed

    An error occurred (AccessDeniedException) when calling the StartSession operation: User: arn:aws:iam::11111111:user/testuser is not authorized to perform: ssm:StartSession on resource: arn:aws:ec2:ap-southeast-1:11111111:instance/i-yyyyyyyyyyy because no identity-based policy allows the ssm:StartSession action

0

The reason the policy can't work is because the SSM documents specified in the Resource element of the first policy statement do not match the ssm:resourceTag/host condition. That's causing the authorisation checks to fail for all the resources that aren't tagged, such as the documents.

You should separate the first policy statement into two. The first statement should specify the resources that are tagged, such as possibly your EC2 instances, and the second statement should specify the resources that aren't tagged, like the standard AWS-provided documents. You should include the Condition block that requires the presence of the tag only in the first of these statements.

EXPERT
answered a year ago
  • Hi Leo that makes sense, but I'm unable to figure out how to fully split this. This is what I have so far, and it allows everything, not just the tagged resource. The only tagged resource is the RDS instance. The bastion host is not tagged, nor should it need to be.

    {
    	"Version": "2012-10-17",
    	"Statement": [
    		{
    			"Effect": "Allow",
    			"Action": [
    				"ssm:StartSession",
    				"ssm:DescribeInstanceInformation",
    				"ssm:GetParameters",
    				"ssmmessages:CreateDataChannel",
    				"ssmmessages:OpenDataChannel",
    				"ssmmessages:OpenControlChannel",
    				"ssmmessages:CreateControlChannel"
    			],
    			"Resource": "*"
    			],
    			"Condition": {
    				"StringEquals": {
    					"ssm:resourceTag/Name": "our-RDS-tag"
    				}
    			}
    		},
    		{
    			"Effect": "Allow",
    			"Action": [
    				"ssm:StartSession",
    				"ssm:DescribeInstanceInformation",
    				"ssm:GetParameters",
    				"ssmmessages:CreateDataChannel",
    				"ssmmessages:OpenDataChannel",
    				"ssmmessages:OpenControlChannel",
    				"ssmmessages:CreateControlChannel"
    			],
    			"Resource": [
    				"arn:aws:ec2:ap-southeast-1:1111111111:instance/i-2222222222222",
    				"arn:aws:ssm:ap-southeast-1:1111111111:document/SSM-SessionManagerRunShell",
    				"arn:aws:ssm:ap-southeast-1::document/AWS-StartPortForwardingSessionToRemoteHost"
    			]
    		},
                 (just included the 1st policy statement into two)
    

    I can't figure out how to properly split.

0

I'd suggest starting with the policy shown as an example in documentation and only expanding it if it's necessary. Here's the policy example from the Session Manager documentation (https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-restrict-access-quickstart.html) adjusted to require your instance tag.

Note that if you specify the individual EC2 instance ID (i-11111111111111111) in the Resource element, the permission will only ever apply to that single instance, making the resource tag check probably redundant. I set the instance resource to a wildcard in this example, so that it would only require the tag with the key host and value our-rds.yyyyyyyyyyyy.ap-southeast-1.rds.amazonaws.com to be set on the EC2 instance to permit starting the session.

On another note, based on what seems to be the DNS name of an RDS database in your policy, it's currently set to test for the presence of a resource tag on the EC2 instance. If your intent is instead to allow remote port forwarding sessions only to a specific target host, I believe the parameters given to the document are not available for evaluation in IAM policies.

What you'd have to do instead is clone the AWS standard document AWS-StartPortForwardingSessionToRemoteHost and modify the host parameter's attributes in the document content to specify the expected host in the default attribute and modify allowedPattern not to allow any other values. For example, allowedPattern could contain ^our-rds\.yyyyyyyyyyyy\.ap-southeast-1\.rds\.amazonaws\.com$ to conform to regular expression syntax. In the IAM policy, you would permit access to the cloned document in your account instead of the AWS-owned standard document.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ssm:StartSession",
      "Resource": "arn:aws:ec2:ap-southeast-1:000000000000:instance/*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/host": "our-rds.yyyyyyyyyyyy.ap-southeast-1.rds.amazonaws.com"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "ssm:StartSession",
      "Resource": [
        "arn:aws:ssm:ap-southeast-1:000000000000:document/SSM-SessionManagerRunShell",
        "arn:aws:ssm:ap-southeast-1::document/AWS-StartPortForwardingSessionToRemoteHost"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "ssm:DescribeSessions",
        "ssm:GetConnectionStatus",
        "ssm:DescribeInstanceProperties",
        "ec2:DescribeInstances"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ssm:TerminateSession",
        "ssm:ResumeSession"
      ],
      "Resource": "arn:aws:ssm:*:*:session/${aws:userid}-*"
    }
  ]
}
EXPERT
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.