amazon-web-servicesamazon-iam

AWS IAM role principal vs role session principal


AWS documentation for IAM role principals[1] states the following:

To specify the role ARN in the Principal element, use the following format:

"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:role/role-name" }

However, when is it ever meaningful for a resource-based policy to use a Principal element with an IAM role principal, as shown in the snippet? Aren't all IAM actions performed by a role identity actually performed by a role session principal[2] like arn:aws:sts::XXXXXXXXXXXX:assumed-role/MyRole/MyRoleSessionName?

For instance, the following S3 bucket policy has a Principal element with an IAM role principal:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Principal": {
            "AWS": "arn:aws:iam::XXXXXXXXXXXX:role/MyRole"
        },
        "Action": "s3:ListBucket",
        "Resource": "arn:aws:s3:::my-bucket",
    }
}

but it does not grant access to principals who assumed MyRole (both the role and the bucket are in the same AWS account). To do that rather, the policy needs to use a role session principal with a specific role session name:

"Principal": {
    "AWS": "arn:aws:sts::XXXXXXXXXXXX:role:assumed-role/MyRole/MyRoleSessionName"
}

Alternatively, the policy can grant access to all MyRole role sessions, regardless of session name:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": "s3:ListBucket",
        "Resource": "arn:aws:s3:::my-bucket",
        "Condition": {
            "ArnEquals": {
                "aws:PrincipalArn": "arn:aws:iam::XXXXXXXXXXXX:role/MyRole"
            }
        }
    }
}

Here, an IAM role principal is used in the Condition element. But returning to the question, is it ever applicable to use it in the Principal element?

References

  1. IAM role principals. AWS JSON policy elements: Principal. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-roles
  2. Role session principals. AWS JSON policy elements: Principal. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-role-session

Solution

  • Actually, it looks like an IAM role Principal in a resource-based policy does affect role session principals for that role. I confirmed this recently, and double-checked with AWS support. See below for more information.

    Side note: This contradicts earlier findings

    In September 2022, when I posted this question, I distinctly remember that the opposite was true (IAM role principal has no effect, as described in the question itself). The same result is confirmed in another, very similar StackOverflow question (API Gateway resource policy: specify IAM role as AWS principal) from 2020, which uses API gateway (instead of S3) as the resource in question.

    If IAM policy evaluation logic had been changed between then and now, that would certainly explain this difference. However, it seems highly unlikely that a major change like this would be silently released, unless it was unintentional. Nonetheless, AWS support confirmed that the new (current) behavior is correct.

    Side note: Role principals have multiple ARNs

    Thanks to ravron's answer about the NotPrincipal caveat and the AWS blog post it links to, it's clearer why an IAM role can be targeted via the Principal element using either a role ARN or a role-session ARN:

    However, this inverted logic approach proves problematic with IAM roles because the role’s Principal value is composed of two Amazon Resource Names (ARNs), the role ARN and the assumed-role ARN. The role ARN is the identifier for the IAM role itself and the assumed-role ARN is what identifies the role session in the logs.

    Steps to reproduce

    In this example, an S3 bucket is used as the resource to which a resource-based policy is attached.

    1. Create a role (EmptyRole) which has no permissions (identity-based policies), but has a trust policy which allows you to assume it.

    2. Create an S3 bucket (aws-iam-resource-based-policy-test) with the following bucket policy:

      {
          "Version": "2012-10-17",
          "Statement": {
              "Effect": "Allow",
              "Principal": {
                  "AWS": "arn:aws:iam::XXXXXXXXXXXX:role/EmptyRole"
              },
              "Action": "s3:ListBucket",
              "Resource": "arn:aws:s3:::aws-iam-resource-based-policy-test"
          }
      }
      
    3. Assume the role EmptyRole.

      $ aws sts assume-role --role-arn arn:aws:iam::XXXXXXXXXXXX:role/EmptyRole --role-session-name TestRoleSession
      {
          "Credentials": {
              "AccessKeyId": "ASIA...",
              "SecretAccessKey": "...",
              "SessionToken": "...",
              "Expiration": "2024-06-18T03:55:09+00:00"
          },
          "AssumedRoleUser": {
              "AssumedRoleId": "AROA...:TestRoleSession",
              "Arn": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/EmptyRole/TestRoleSession"
          }
      }
      
    4. Use the resulting role session credentials to list the S3 bucket aws-iam-resource-based-policy-test:

      $ aws s3api list-objects --bucket aws-iam-resource-based-policy-test 
      {
          "RequestCharged": null
      }
      

    Documentation?

    The AWS documentation does not say much about what is expected to happen when an IAM role session principal interacts with a resource-based policy which targets that IAM role in a Principal element.

    One reference occurs in IAM role principals:

    When you specify a role principal in a resource-based policy, the effective permissions for the principal are limited by any policy types that limit permissions for the role. This includes session policies and permissions boundaries. For more information about how the effective permissions for a role session are evaluated, see Policy evaluation logic.

    Another reference occurs in Resource-based policies and implicit denies in other policy types (same account):

    Principal making the request Resource-based policy Identity-based policy Permissions boundary Session Policy Result Reason
    IAM role session Allows role ARN Implicit deny Implicit deny Implicit deny DENY Permissions boundary and session policy are evaluated as part of the final decision. An implicit deny in either policy results in a DENY decision.
    • IAM role – Resource-based policies that grant permissions to an IAM role ARN are limited by an implicit deny in a permissions boundary or session policy.

      Example role ARN

        arn:aws:iam::111122223333:role/examplerole
      

    Both snippets clearly state that permission boundaries and session policies (which limit permissions) can result in a DENY decision, but neither says what happens when these limiting policies are not present or allow the access.

    After raising this concern with AWS support, the AWS representative confirmed that AWS may be revising their docs around this:

    Our Senior Technical Writer is diligently working to investigate and rectify the documentation issue. Once a suitable solution is identified, it will undergo the necessary internal process to ensure the documentation is updated accordingly.