Cross-account IAM assume role policy without external ID or MFA
This product is not supported for your selected
Datadog site. (
).
Id: 85138beb-ce7c-4ca3-a09f-e8fbcc57ddd7
Cloud Provider: AWS
Platform: CloudFormation
Severity: High
Category: Access Control
Learn More
Description
Cross-account IAM role trust policies must require either an external ID or MFA to prevent confused-deputy attacks and reduce the risk of unauthorized cross-account access.
Check AWS::IAM::Role resources’ AssumeRolePolicyDocument for Allow statements that grant sts:AssumeRole to external AWS principals. Those statements must include a Condition requiring either the sts:ExternalId condition key (for example, StringEquals) or aws:MultiFactorAuthPresent set to true. Resources missing a Condition with sts:ExternalId or aws:MultiFactorAuthPresent will be flagged.
Acceptable secure configurations include requiring an external ID or enforcing MFA in the trust policy, for example:
MyRoleWithExternalId:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: arn:aws:iam::123456789012:root
Action: sts:AssumeRole
Condition:
StringEquals:
sts:ExternalId: my-external-id
MyRoleWithMFA:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: arn:aws:iam::123456789012:root
Action: sts:AssumeRole
Condition:
Bool:
aws:MultiFactorAuthPresent: "true"
Compliant Code Examples
AWSTemplateFormatVersion: "2010-09-09"
Resources:
RootRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument: >
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::987654321145:root"
},
"Effect": "Allow",
"Resource": "*",
"Sid": "",
"Condition": {
"StringEquals": {
"sts:ExternalId": "98765"
}
}
}
]
}
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"RootRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::987654321145:root"
},
"Effect": "Allow",
"Resource": "*",
"Sid": "",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
},
"Path": "/"
}
}
}
}
AWSTemplateFormatVersion: "2010-09-09"
Resources:
RootRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument: >
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::987654321145:root"
},
"Effect": "Allow",
"Resource": "*",
"Sid": "",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
Non-Compliant Code Examples
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"RootRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::987654321145:root"
},
"Effect": "Allow",
"Resource": "*",
"Sid": ""
}
]
},
"Path": "/"
}
}
}
}
AWSTemplateFormatVersion: "2010-09-09"
Resources:
RootRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument: >
{
"Version": "2012-10-17",
"Statement": {
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::987654321145:root"
},
"Effect": "Allow",
"Resource": "*",
"Sid": "",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
}
AWSTemplateFormatVersion: "2010-09-09"
Resources:
RootRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument: >
{
"Version": "2012-10-17",
"Statement": {
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::987654321145:root"
},
"Effect": "Allow",
"Resource": "*",
"Sid": "",
"Condition": {
"StringEquals": {
"sts:ExternalId": ""
}
}
}
}