问题描述
希望在AWS中,强制用户在扮演角色时使用他们的IAM用户名作为角色会话名称。他尝试在IAM策略中使用以下条件:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<redacted>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringLike": {
"sts:RoleSessionName": "${aws:username}"
}
}
}
当用户以用户身份扮演角色时,这个条件可以正常工作,但当用户以具有管理员权限的角色从另一个角色扮演时,这个条件就不起作用了(Allow * on *
)。唯一阻止这种情况的方法是在一个角色试图扮演另一个角色时,如果没有设置会话名称,则明确地使用Deny
。有没有办法编写一个这样的策略?下面的简单Deny
策略不起作用,因为当Assumed Role
是主体时,aws:username
不存在(参见文档)。
{
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::<redacted>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringNotLike": {
"sts:RoleSessionName": "${aws:username}"
}
}
}
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
根据回答1,如果将拒绝策略更改为一个元素列表,它将起作用。这样做的话,IAM用户可以扮演角色,只要他们使用他们的用户名作为会话名称,其他主体可以扮演角色,只要他们使用”AnotherAllowedName”作为会话名称,但是所有其他会话名称都将被拒绝。在研究这个答案时,我在AWS的博客文章中找到了一些有用的信息。
以下是一个示例策略:
{
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::<redacted>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringNotLike": {
"sts:RoleSessionName": [
"${aws:username}",
"AnotherAllowedName"
]
}
}
}
在上面的示例中,我们将拒绝策略中的sts:RoleSessionName
条件更改为一个元素列表。这将允许IAM用户扮演角色,只要他们使用他们的用户名作为会话名称,同时也允许其他主体扮演角色,只要他们使用”AnotherAllowedName”作为会话名称,但是所有其他会话名称都将被拒绝。
请注意,这种方法无法满足要求将角色会话名称与用户名匹配的要求。如果您的AWS用户名包含公司域名,您可以尝试使用”*@mycompany.com”这样的条件,这可能会提醒用户他们需要使用他们的电子邮件作为会话名称。
方案2
根据评论1,如果您的用户名在AWS中包含公司域名,您可以尝试使用”*@mycompany.com”这样的条件,这可能会提醒用户他们需要使用他们的电子邮件作为会话名称。但是请注意,这种方法仍然无法强制要求角色会话名称与用户名完全匹配。
{
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::<redacted>:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringNotLike": {
"sts:RoleSessionName": "*@mycompany.com"
}
}
}
以上是一个示例策略,其中sts:RoleSessionName
条件使用”*@mycompany.com”来拒绝除了公司域名之外的所有会话名称。
请注意,这种方法仍然无法强制要求角色会话名称与用户名完全匹配。