Allow me to paint the picture of Identity of Access Management (IAM), and its challenges.
For our personal AWS accounts, the login process is simple, and the number of users is minimal too - you are probably using an IAM user with a role that has AdministratorAccess policy attached. It’s not an issue when you are the sole user, taking in the full risks and responsibilities of the AWS account.
For larger scale cases, such as enterprises, typically the login is through federation. Federation is a trust relationship between an external identity provider and AWS.
Users can sign in to a web identity provider, such as Login with Amazon, Facebook, Google, or any IdP that is compatible with OpenID Connect (OIDC). Users can also sign in to an enterprise identity system that is compatible with Security Assertion Markup Language (SAML) 2.0, such as Microsoft Active Directory Federation Services. When you use OIDC and SAML 2.0 to configure a trust relationship between these external identity providers and AWS, the user is assigned to an IAM role. The user also receives temporary credentials that allow the user to access your AWS resources.
For those users, when they log in, typically their IAM roles are only granted a set of least privileges necessary for their daily work. However, there will definitely be times when higher privileges are needed. How do we do that?
Role escalation/role chaining
In short, the user can switch roles, from the IAM role with typical privileges to an IAM role with higher privileges.
From the above user’s perspective, switching roles is easy. However, as administrators and guardians of our AWS accounts, how do we limit access to only the right people?
The answer is, of cause, using policies.
Simple example: switch from IAM user in account A to IAM role in account B
What do you need:
Account A IAM user
Attached permission policy for STS AssumeRole action
Account B role
Trust policy that allows assume role
As you can see, how secure is this switching depending on how we craft our policies.
For the account A IAM user, the permission policy need to have the STS AssumeRole action, something like this:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::account_id_number:role/role-name-you-want-to-assume"
}
For the account B IAM role, supposedly called “role-name-you-want-to-assume”, the trust policy need to trust a particular principal’s action, something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole"
}
]
}
Next, let’s level up with even finer-grain control for a Role to Role switch.
More complex example: switch from a Role in account A to a Role in account B
In this example, we use a combination of the Principal attribute, RoleID, and the aws:UserId, to scope down to only the allowed UserID with RoleId from a particular AWS account principal.
To capture the RoleId for the role you want to be able to assume, you can run the following command using the AWS CLI:
# aws iam get-role --role-name trusted-role-in-jas3
With that, we can draft our trust policy that limits access to only that IAM role (with RoleID AROA5XDQ3YE6PJTM7JI3W) from AWS Account 111122223333.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringLike": {
"aws:userId": "AROA5XDQ3YE6PJTM7JI3W:alvinbrandoncharles@gmail.com"
}
}
}
]
}
To explain the above, it’s basically locking down through the 1) Principal portion and 2) Condition portion.
Principal: only authenticated users originating from the 111122223333 account is allowed, and not any IAM users from any other accounts.
The suffix root in the policy’s Principal attribute equates to “authenticated and authorized principals in the account,” not the special and all-powerful root user principal that is created when an AWS account is created.
A principal can be an IAM user, machine, or other authenticated identity
Condition: We can locking down to the previous IAM role’s Role ID (AROA5XDQ3YE6PJTM7JI3W). So only if you are previously taking on that IAM role, can you take on the new role. The userID is typically the user’s email address, assuming the organisation is using Active Directory as the identity provider.
Additional resources
An organisation’s IAM is always so integral and complex, and it’s important to get the solution that fits the needs. Feel free to dive deeper here:
https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/
https://repost.aws/knowledge-center/iam-switch-role