Use-cases for IAM roles

Roles can give cross-account access, federated login capabilities, and a lot more

Author's image
Tamás Sallai
5 mins

Roles in AWS

Roles are one of the two identity types in AWS. Users are more suited for permanent credentials, either as a person who needs access to perform work or a third-party service that uses access keys to get access to protected resources. Roles provide temporary credentials and rely on IAM permissions to allow usage.

With policies attached to a role, it can provide access to protected resources inside the account. The keys are short-lived which makes them a more secure alternative to long-lived user access keys.

Let’s see the use-cases when roles are used in AWS!

Cross-account access

The canonical example for roles is to provide cross-account access to an account. The role’s trust policy defines the other account, then users can obtain temporary credentials that are valid in the role’s account. Using a permissions policy you can give selective access to resources in the account.

Account 2Account 1«User»Trusted user[]«policy»{"Action": ["sts:AssumeRole"],"Effect": "Allow","Resource":"arn:aws:iam::1:role/role",}«IAMRole»role[]«trust policy»{"Action": ["sts:AssumeRole"],"Effect": "Allow","Principal": {"AWS": "arn:aws:iam::2:root"}}«permissions policy»{"Action": ["s3:GetObject"],"Effect": "Allow","Resource": "*"}«S3Bucket»[]allowedassumeCross-account role

The alternative approach would be to create an IAM user, generate an access key, then send it to the other account. While this works, it requires transferring a secret (the access key). With a cross-account role, no secrets are exchanged.

Learn the services needed to build a serverless HTTP-based API on AWS from our free email course.

AWS service

By default, even AWS services have no access to your account. To allow them to use some resources, they can use a role that has the necessary permissions.

For example, CloudTrail can send the events to CloudWatch Logs. To give it access to the log group, you need to specify a role that it can use.

CloudTrail log role config

Even though the role is configured to the service, it also needs to allow access through its trust policy. The Principal in this case is the service.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

The permissions are attached as the role’s permissions policies:

CloudTrail permissions

This setup gives CloudTrail access to CloudWatch Logs in a controlled way.

Many other services use a role to get access to resources. S3 replication is another example:

S3 replication role

Delegate access to code

A special case of allowing an AWS service to use a role is to use it to delegate permissions to code you write.

For example, you can configure a role for a Lambda function. When the function is invoked, the Lambda service assumes the role and then passes the credentials to the code.

Lambda role config

With this setup, the Lambda code automatically gets the permissions of the role and you don’t need to include secrets in the codebase.

The lambda code does not contain secrets

This is the preferred way to add permissions to a Lambda function. It’s not only easier but also more secure.

Another example is EC2. Through the instance profile, it allows you to specify a role.

EC2 instances can use roles

The credentials the role provides are available in the instance metadata.

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role>
{
	"Code" : "Success",
	"LastUpdated" : "2012-04-26T16:39:16Z",
	"Type" : "AWS-HMAC",
	"AccessKeyId" : "ASIAIOSFODNN7EXAMPLE",
	"SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
	"Token" : "token",
	"Expiration" : "2017-05-17T15:09:54Z"
}

AWS tools, such as the CLI and the SDKs support the common ways roles are attached. You don’t need to implement your own logic in a Lambda function or when using the CLI in an EC2 instance.

Note that it does not protect the keys when somebody has access to the instance or the code. It just makes sure that no secrets are hardcoded and that credentials expire.

Federated login

With federated login, users sign in on a separate server and it assumes a role for them in the AWS account. This allows users to use the account without having an IAM user for each of them. With the configured role, you can give them permission to access protected resources.

AWS account«IAMRole»role[]«trust policy»{"Effect": "Allow","Action": "sts:AssumeRoleWithSAML","Principal": {"Federated": "..."},"Condition": {...}}«permissions policy»{"Action": ["s3:GetObject"],"Effect": "Allow","Resource": "*"}«S3Bucket»[]«TraditionalServer»IdP[]«User»User[]allowedloginassumeSAML federation

Cognito is another example that works the same. It logs in users then you can define which role it assigns for them.

Cognito roles configuration

Using these roles you can assign permissions to a group of users managed in Cognito User Pools.

Extending permissions

Roles can also give same-account access to protected resources. In this case, you give permissions to the role then define who can use that role. From a permissions point of view, this is equivalent to giving the user the permissions but gives more control over how it is used.

For example, you can set up a notification whenever the role is used, which is called a break-glass role. This is a good solution for rare admin tasks.

What are rare admin tasks? The common example is KMS key management, but it can be anything that you consider “sensitive”. Deleting the production database, managing admin users in IAM, configuring CloudTrail are all tasks that fall into this category.

Using roles to gain new permissionsSTSSTSuseruserS3S3User credentialsAccess deniedUser credentialsAssume roleRole credentialsRole credentialsresult

Removing permissions

Roles can also limit what a user can do. This is a good practice when an admin does not want to break the production system and instead uses a role that has no access to those resources.

Using roles to limit permissionsSTSSTSadminadminProduction bucketProduction bucketAdmin credentialsresultAdmin credentialsAssume roleRole credentialsRole credentialsAccess denied

Conclusion

Roles are used throughout AWS for many use-cases and they are often a superior alternative to IAM users. They are used throughout many services and it’s a best practice to use them when they are available.

13 November 2020
In this article