2

I'm using a third-party SDK that needs temporary AWS credentials to access AWS services. I'm using this SDK as part of an application that is running on EC2. All SDKs in my application need access to the same role, which is attached to my the EC2 instance. Below, I have listed two options I have found for getting temporary credentials. Which one of these options is the recommended way for getting temporary credentials for my third-party SDK?

AWS.config

var AWS = require("aws-sdk");
AWS.config.getCredentials();
var creds = AWS.config.credentials

Security Token Service (STS)

var sts = new AWS.STS();
var params = {
    RoleArn: "arn:aws:iam::123456789012:role/demo",
    RoleSessionName: "Bob",
};
sts.assumeRole(params, function(err, data) {
    var creds = data.Credentials;
});
johnnyodonnell
  • 1,838
  • 3
  • 16
  • 34
  • I'm not an expert in AWS IAM, but these seem to be doing quite different things - the first is acting as "yourself", the second is acting as an assumed role. – Oliver Charlesworth Jan 28 '18 at 23:27
  • @OliverCharlesworth That's true. However, in my particular use case, I need to get credentials for the same IAM role associated with my EC2 instance. So AWS.config and STS should be getting temporary credentials for the same role. Thus, I'm lead to the question of which option to use. – johnnyodonnell Jan 28 '18 at 23:33
  • 1
    What is your objective? This is not clear in your question. If your goal is security and you want to hand off temporary credentials to another piece of software on the same EC2 instance -- that software can still access your original credentials from the Metadata. I would create a "least privilege" role, assign that role to EC2 and then hand those credentials to the app. – John Hanley Jan 28 '18 at 23:45
  • 1
    The first method is not equivalent to the STS method. The STS method actually generates new credentials. The getCredentials() method simply gives you access to a credentials object that represents *existing* credentials (unless you have implemented some custom credentials source, which I assume you haven't). Launch your EC2 instance with the minimum IAM role, and if the other SDK requires you to provide credentials explicitly, then get them using getCredentials(). – jarmod Jan 29 '18 at 00:46
  • Thanks @JohnHanley. I added a bit more to my question to make my objective more clear. – johnnyodonnell Jan 29 '18 at 02:47
  • I think JohnHanley and @jarmod have pretty much answered my question. Although I would also like to know why I should get my credentials from the Metadata. Or in other words why I should use AWS.config.getCredentials(). – johnnyodonnell Jan 29 '18 at 02:47
  • 1
    If the SDK that you’re using leverages the standard AWS credential sources (EC2 instance profile, environment variables etc.) then you presumably don’t need to give it credentials. If it can’t get them for itself then you’ll have to provide them. – jarmod Jan 29 '18 at 02:52
  • @jarmod The SDK I am using can't get them for itself, so I either need to use getCredentials() or assumRole, but I'm not sure which option to use. – johnnyodonnell Jan 29 '18 at 03:04
  • Use your first example. This will obtain the credentials from the IAM Role that you assigned to the EC2 instance. AssumeRole is used when you want to switch the credentials (for example to get less privileged credentials or to switch the IAM User). If you are going to give the SDK the same privileges as the EC2 IAM Role, then you don't need to call AssumeRole. – John Hanley Jan 29 '18 at 03:58

1 Answers1

4

Should in this case is a bit fluid, but when you launch an EC2 instance and assign it an instance profile, (somewhat) temporary credentials are made available as instance metadata. You access instance metadata via a local HTTP server bound on 169.254.169.254

e.g. curl http://169.254.169.254/latest/meta-data/ami-id

returns the AMI-ID of the running instance. AWS credentials associated with the instance profile assigned to the instance can be accessed in this manner.

Anything running on the instance can access this data, meaning that if you're trying to isolate the third-party SDK from your instance profile, you've already failed.

However, it doesn't sound like that's what you're trying to do. When you execute AWS.config.getCredentials();, it uses the instance metadata (among other things) to look up the credentials. This is advantageous because it allows you to supply the credentials in a variety of manners without changing the code that looks them up.

The STS use case, however, is if you want to temporarily change a given user to a particular role. The user you're requesting from must have the sts:AssumeRole permission and have the same permissions as the target role. This can be used for auditing purposes, etc.

Chris Thompson
  • 35,167
  • 12
  • 80
  • 109