3

While running on EC2, the accesskey and secret key can be accessed by the curl command

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<rolename>

These credentials are not constant and keep changing.

I am wondering if there is a way to get these credentials using the aws-java-sdk?

I know this can be done using boto3 in python. But don't know how to accomplish the same in java.

Community
  • 1
  • 1
Anthony
  • 33,838
  • 42
  • 169
  • 278

2 Answers2

4

Yes, via EC2MetadataUtils.getIAMSecurityCredentials() EC2MetadataUtils is a Java adapter for the metadata service that you are accessing via curl, and exposes these fields in EC2MetadataUtils.IAMSecurityCredential.

Signature:

public static class EC2MetadataUtils.IAMSecurityCredential

Fields:

String accessKeyId 
String secretAccessKey 

To access these fields, use EC2MetadataUtils.getIAMSecurityCredentials():

public static Map<String,EC2MetadataUtils.IAMSecurityCredential> getIAMSecurityCredentials()

Documentation:


It is outside the scope of this question, but also worth noting that if you are using these credentials for the AWS SDK for Java on this instance that you don't need to define these credentials explicitly -- AWS Clients using the default constructor will search for these credentials as part of the default credentials provider chain. More info in this documentation.

Anthony Neace
  • 25,013
  • 7
  • 114
  • 129
  • hmm that class doesn't seem to have any getters for those fields? How would I access them? For example...I'd like to simply print them to stdout. – Anthony Dec 22 '16 at 16:54
  • FWIW, I need access to these credentials because my code is using third party libraries to access S3 resources and those libraries need the accesskey and secretkey in order to access the resources. My plan is to fetch them from AWS SDK and pass them through to the third party libs. – Anthony Dec 22 '16 at 16:57
  • @Anthony Use `EC2MetadataUtils.getIAMSecurityCredentials()`. Updated answer with links to appropriate doc – Anthony Neace Dec 22 '16 at 17:00
  • Awesome, thanks. Wondering how this would be different than the way mentioned in this doc? http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/prog-services-sts.html – Anthony Dec 22 '16 at 17:02
  • @Anthony Not too different. That method is just as valid and indeed preferred if, for example, you didn't want to reuse your IAM instance profile's role, or weren't working from an EC2 instance where the credential cycling was already being done for you. – Anthony Neace Dec 22 '16 at 17:04
  • Thank you . How would I get the accessKey and secret key? from the returned map? `EC2MetadataUtils.getIAMSecurityCredentials().get("accessKeyId")`? – Anthony Dec 22 '16 at 17:08
  • Hey, sorry, stepped away from PC but yeah that should work if the key matches IAMSecurityCredential definitions. Here's some more details about how to broadly work with maps, if it helps: http://stackoverflow.com/documentation/java/90/collections/12413/usage-of-hashmap#t=20161222171138663057 – Anthony Neace Dec 22 '16 at 17:15
1

Here is a working example

// This prints the EC2 instance role and then the keys
void printCredentials() {
    Map<String,EC2MetadataUtils.IAMSecurityCredential> credMap = EC2MetadataUtils.getIAMSecurityCredentials();
    Iterator<Map.Entry<String,EC2MetadataUtils.IAMSecurityCredential>> it = credMap.entrySet().iterator();
    while (it.hasNext()) {
        // First print the role associated with this instance
        Map.Entry<String,EC2MetadataUtils.IAMSecurityCredential> pair = (Map.Entry<String,EC2MetadataUtils.IAMSecurityCredential>)it.next();
        System.out.println("Role: " + pair.getKey() + " = Value: " + pair.getValue());

        // Next print the access key and secret key
        EC2MetadataUtils.IAMSecurityCredential cred = pair.getValue();
        System.out.println("Access key: " + cred.accessKeyId + ", Secret key: " + cred.secretAccessKey);
    }
}
user2434291
  • 149
  • 11