Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Check for Untrusted Cross-Account IAM Roles

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Medium (should be achieved)
Rule ID: IAM-057

Ensure that your Amazon IAM roles are configured to be used only by trusted AWS accounts in order to protect against unauthorized cross-account access. Before running this rule by the Conformity engine, the list with the trusted AWS account identifiers must be configured in the rule settings, on your Trend Cloud One™ – Conformity account console.

This rule can help you with the following compliance standards:

  • PCI
  • APRA
  • MAS
  • NIST4

For further details on compliance standards supported by Conformity, see here.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Security

Allowing unknown cross-account access to your Amazon IAM roles will enable foreign accounts to assume these roles and gain control over your AWS services and resources. To prevent unauthorized cross-account access, allow only trusted entities to assume your Amazon IAM roles by implementing the appropriate policies.


Audit

To determine if there are any IAM roles configured to allow unknown cross-account access, available in your AWS cloud account, perform the following actions:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.

03 In the navigation panel, under Access management, choose Roles.

04 Click on the name of the IAM role that you want to examine.

05 Select the Trust relationships tab and identify the IDs of the entities that can assume this role, listed in the Trusted entities section.

06 Sign in to your Trend Cloud One™ – Conformity account, access Cross-Account IAM Roles conformity rule settings, and compare the account ID(s) identified at the previous step against each AWS account ID defined in the rule configuration section. If one or more AWS account IDs are not included in the list of trusted account IDs defined in the conformity rule settings, the selected Amazon IAM role can be assumed by untrusted AWS entities, therefore the cross-account access is not secured.

07 Repeat steps no. 4 – 6 for each IAM role available within your AWS cloud account.

Using AWS CLI

01 Run list-roles command (OSX/Linux/UNIX) with custom query filters to list the names of all the IAM roles available in your AWS cloud account:

aws iam list-roles
  --output table
  --query 'Roles[*].RoleName'

02 The command output should return a table with the requested IAM role identifiers:

---------------------------
|        ListRoles        |
+-------------------------+
|  cc-external-mgmt-role  |
|  cc-lambda-admin-role   |
|  cc-prod-manager-role   |
+-------------------------+

03 Run get-role command (OSX/Linux/UNIX) using the name of the Amazon IAM role that you want to examine as the identifier parameter, to describe the policy that grants another entity the permission to assume the selected role:

aws iam get-role
  --role-name cc-external-mgmt-role
  --query 'Role.AssumeRolePolicyDocument'

04 The command output should return the trust policy defined for the selected IAM role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Condition": {
                "StringEquals": {
                    "sts:ExternalId": "<external_id>"
                }
            },
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            }
        }
    ]
}

Identify the AWS account ID configured for cross-account access, included within the Amazon Resource Name (ARN) listed as value for the "Principal" element (highlighted).

05 Sign in to your Trend Cloud One™ – Conformity account, access Cross-Account IAM Roles conformity rule settings, and compare the account ID returned by the get-role command output at the previous step against each AWS account ID defined in the rule configuration section. If one or more AWS account IDs are not included in the list of trusted account IDs defined in the conformity rule settings, the selected Amazon IAM role can be assumed by untrusted AWS entities, therefore the cross-account access is not secured.

06 Repeat steps no. 3 – 5 for each IAM role available within your AWS cloud account.

Remediation / Resolution

To update your IAM roles permissions in order to authorize only trusted AWS accounts to assume your roles, regardless of MFA/external ID support, perform the following actions:

Using AWS CloudFormation

01 CloudFormation template (JSON). Replace <trusted-account-id> with the ID of the trusted AWS account that can assume your IAM role:

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Authorize Trusted AWS Account to Assume IAM Role",
  "Resources": {
    "CrossAccountIAMRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": "cc-external-mgmt-role",
        "Description": "Full Access to Amazon EC2",
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:iam::<trusted-account-id>:root"
              },
              "Condition": {
                 "StringEquals": {
                    "sts:ExternalId": "<external_id>"
                 }
              },
              "Action": [
                "sts:AssumeRole"
              ]
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/AmazonEC2FullAccess"
        ],
        "Path": "/"
      }
    }
  }
}

02 CloudFormation template (YAML). Replace <trusted-account-id> with the ID of the trusted AWS account that can assume your IAM role:

AWSTemplateFormatVersion: '2010-09-09'
Description: Authorize Trusted AWS Account to Assume IAM Role
Resources:
  CrossAccountIAMRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: cc-external-mgmt-role
      Description: Full Access to Amazon EC2
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              AWS: arn:aws:iam::<trusted-account-id>:root
            Condition:
              StringEquals:
                sts:ExternalId: <external_id>
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEC2FullAccess
      Path: /

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf). Replace <trusted-account-id> with the ID of the trusted AWS account that can assume your IAM role:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

provider "aws" {
  profile = "default"
  region  = "us-east-1"
}

resource "aws_iam_role" "iam-role" {
  name = "cc-external-mgmt-role"
  path = "/"
  managed_policy_arns = [ "arn:aws:iam::aws:policy/AmazonEC2FullAccess" ]

  assume_role_policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::<trusted-account-id>:root"
          },
          "Condition": {
             "StringEquals": {
                "sts:ExternalId": "<external_id>"
             }
          },
          "Action": [
            "sts:AssumeRole"
          ]
        }
    ]
}
EOF
}

Using AWS Console

01 Sign in to your Trend Cloud One™ – Conformity account, access Cross-Account IAM Roles conformity rule settings, and copy the ID of the AWS account authorized to assume and use your IAM role(s).

02 Sign in to the AWS Management Console.

03 Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.

04 In the navigation panel, under Access management, choose Roles.

05 Click on the name of the cross-account IAM role that you want to reconfigure.

06 Select the Trust relationships tab and choose Edit trust relationship to update the trust policy defined for the selected role.

07 On the Edit Trust Relationship page, in the Policy Document box, replace the 12-digit AWS account number included in the "Principal" element value, with the trusted AWS account ID copied at step no. 1. If required, repeat this step for other entities that are authorized to assume the selected role. Click Update Trust Policy to apply the configuration changes.

08 Repeat steps no. 5 – 7 for each cross-account IAM role that you want to reconfigure.

Using AWS CLI

01 Sign in to your Trend Cloud One™ – Conformity account, access Cross-Account IAM Roles conformity rule settings, and copy the ID of the AWS account authorized to assume and use your IAM role(s).

02 Modify the trust relationship policy defined for the IAM role that you want to reconfigure to authorize only trusted AWS accounts to assume the selected IAM role. Replace the 12-digit AWS account number included in the "Principal" element value, with the trusted AWS account ID copied at step no. 1, then save the policy document to a JSON file named trusted-cross-account-access.json, e.g.:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Condition": {
                "StringEquals": {
                    "sts:ExternalId": "<external_id>"
                }
            },
            "Principal": {
                "AWS": "arn:aws:iam::123412341234:root"
            }
        }
    ]
}

03 Run update-assume-role-policy command (OSX/Linux/UNIX) to replace the trust policy defined for the selected Amazon IAM role with the one modified at the previous step, i.e. trusted-cross-account-access.json (the command does not produce an output):

aws iam update-assume-role-policy
  --role-name cc-external-mgmt-role
  --policy-document file://trusted-cross-account-access.json

04 Repeat steps no. 1 – 3 for each cross-account IAM role that you want to reconfigure.

References

Publication date Oct 21, 2019