Can AWS IAM roles be used for app running outside AWS?

Viewed 330

So I think that the simplest solution is my problem is to use AWS for everything but I wanted to understand what is possible:

I understand that IAM roles can be associated with an AWS service such as EC2 or Lambda so that an application/function running within that service can retrieve credentials to sign API requests to other AWS services. I have a previous application running on Heroku and using Amazon S3. Currently I have an IAM user set up for this application which signs requests to the AWS API using the access keys associated with the IAM user account. I think that best practice is to use an IAM role rather than a user for application source code AWS API calls, however is it possible to set this up for the application hosted outside of AWS or would I need to migrate the application to AWS EC2 in order to use IAM roles?

3 Answers

It doesn't matter where the application is hosted but to assume an IAM role you will need IAM credentials (chicken and egg). Typically you would design a secure way for your app to retrieve these base credentials. This is one disadvantage of running your compute outside of AWS (because it can't automatically assume an IAM role).

One option would be to create an IAM user whose only permissions were to be able to assume a given IAM role. Supply those IAM user credentials to your application, outside of AWS, securely and have the application assume the IAM role, ideally with an ExternalId that itself is also securely stored and securely retrieved by your application. Additionally, you can manage access to the IAM role, for example defining which principals can assume the role, and under which conditions.

AWS announced a new feature AWS IAM Anywhere that should help if you need to avoid using access/secret keys. It's more complicated but follows security best practices.

AWS Identity and Access Management (IAM) now enables workloads that run outside of AWS to access AWS resources using IAM Roles Anywhere. IAM Roles Anywhere allows your workloads such as servers, containers, and applications to use X.509 digital certificates to obtain temporary AWS credentials and use the same IAM roles and policies that you have configured for your AWS workloads to access AWS resources.

and more here:

create a trust anchor where you either reference your AWS Certificate Manager Private Certificate Authority (ACM Private CA) or register your own certificate authorities (CAs) with IAM Roles Anywhere. By adding one or more roles to a profile and enabling IAM Roles Anywhere to assume these roles, your applications can now use the client certificate issued by your CAs to make secure requests to AWS and get temporary credentials to access the AWS environment.

AWS Announcement: https://aws.amazon.com/about-aws/whats-new/2022/07/aws-identity-access-management-iam-roles-anywhere-workloads-outside-aws/

User Guide: https://docs.aws.amazon.com/rolesanywhere/latest/userguide/introduction.html

From Heroku docs:

Because of the sensitive nature of your S3 credentials, you should never commit them to version control. Instead, set them as the values of config vars for the Heroku apps that will use them.

Use the heroku config:set to set both keys

heroku config:set AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=yyy
Adding config vars and restarting app... done, v21
  AWS_ACCESS_KEY_ID     => xxx
  AWS_SECRET_ACCESS_KEY => yyy

The above is in line with AWS's own best practices for managing AWS access keys, specifically not embedding access keys directly in code.

You can't use IAM roles in the sense that it is picked up automatically by AWS, outside of AWS, without specifying credentials specifically.

Your next best option is environment variables (as detailed above), specifying the access key ID and secret access key for a user with a role granting the least privilege required for the files they need to read from S3 e.g. specific bucket name, specific files, even specific IP addresses if possible, etc.

Related