aws-sdk-java icon indicating copy to clipboard operation
aws-sdk-java copied to clipboard

ProfileCredentialsProvider fails if credentials file has a profile with an assume role configuration when using Ec2InstanceMetadata

Open Lock128 opened this issue 6 years ago • 7 comments

Hey,

I have a problem with the credentials file with the following profile:

[default] region = eu-central-1 credential_source=Ec2InstanceMetadata

[profile1] role_arn = arn:aws:iam::xxxxxx:role/Jenkins-Deployment-Role credential_source=Ec2InstanceMetadata source_profile=default

When using the credentials file and specifying profile1, I am getting the following error: Exception in thread "main" com.amazonaws.SdkClientException: Unable to load credentials into profile

[default]: AWS Access Key ID is not specified. at com.amazonaws.auth.profile.internal.ProfileStaticCredentialsProvider.fromStaticCredentials(ProfileStaticCredentialsProvider.java:55) at com.amazonaws.auth.profile.internal.ProfileStaticCredentialsProvider.(ProfileStaticCredentialsProvider.java:40) at com.amazonaws.auth.profile.internal.ProfileAssumeRoleCredentialsProvider.fromAssumeRole(ProfileAssumeRoleCredentialsProvider.java:72) at com.amazonaws.auth.profile.internal.ProfileAssumeRoleCredentialsProvider.(ProfileAssumeRoleCredentialsProvider.java:46) at com.amazonaws.auth.profile.ProfilesConfigFile.fromProfile(ProfilesConfigFile.java:204) at com.amazonaws.auth.profile.ProfilesConfigFile.getCredentials(ProfilesConfigFile.java:160) at com.amazonaws.auth.profile.ProfileCredentialsProvider.getCredentials(ProfileCredentialsProvider.java:161) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1166) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:762) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:724) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) at com.amazonaws.services.ecs.AmazonECSClient.doInvoke(AmazonECSClient.java:2745) at com.amazonaws.services.ecs.AmazonECSClient.invoke(AmazonECSClient.java:2721) at com.amazonaws.services.ecs.AmazonECSClient.executeDescribeClusters(AmazonECSClient.java:951) at com.amazonaws.services.ecs.AmazonECSClient.describeClusters(AmazonECSClient.java:926)

Version of sdk used for this test: 1.11.374

I was not able to find out of using Ec2InstanceMetadata is supported as "default" profile officially, but based on the documentation I read above should be correct.

Lock128 avatar Aug 06 '18 15:08 Lock128

We have now been able to workaround this problem by using

private void initEcsClient(){ AWSStaticCredentialsProvider credentialsProvider;

  logger.debug("DBG: roleArn=" + this.roleArn);
  
  AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
  	.withRegion(awsRegion)
  	.build();
  
  AssumeRoleRequest roleRequest = new AssumeRoleRequest()		
  	.withRoleArn(this.roleArn)
  	.withRoleSessionName(customer + "-" + environment + "-restart-acm-tool");

  AssumeRoleResult assumeRoleResult = stsClient.assumeRole(roleRequest);
  logger.info ("assumed user arn: " + assumeRoleResult.getAssumedRoleUser());
  
  Credentials sessionCredentials = assumeRoleResult.getCredentials();
  logger.info ("assumed user credentials: " + sessionCredentials.toString());
  
  BasicSessionCredentials basicSessionCredentials = new BasicSessionCredentials(
  	sessionCredentials.getAccessKeyId(), 
  	sessionCredentials.getSecretAccessKey(),
  	sessionCredentials.getSessionToken()
  );		

  credentialsProvider = new AWSStaticCredentialsProvider(basicSessionCredentials);
  

  
  AmazonECSClientBuilder ecsClientBuilder = AmazonECSClientBuilder.standard().withRegion(awsRegion)
  	.withCredentials(credentialsProvider);
  amazonECS = ecsClientBuilder.build();
  
  logger.debug("ECSClient: Using credentials Acc-Key: "+ecsClientBuilder.getCredentials().getCredentials().getAWSAccessKeyId());
  logger.debug("ECSClient: Using credentials Sec-Key: "+ecsClientBuilder.getCredentials().getCredentials().getAWSSecretKey());		
  

}

...but this doesnt solve the original problem that we can not use the Java SDK with the same strategy as the aws-cli where the assumeRole stuff is handled automatically.

Lock128 avatar Aug 08 '18 04:08 Lock128

Looks like we don't support the credentials_source at the moment. I'll go ahead and mark this as a feature request so others can +1 to aide in prioritization.

As for the workaround I suggest using the STSAssumeRoleSessionCredentialsProvider which handles automatically refreshing credentials when close to expiry and actually making the call to STS.

STSAssumeRoleSessionCredentialsProvider credentialsProvider = new STSAssumeRoleSessionCredentialsProvider.Builder(roleArn, customer + "-" + environment + "-restart-acm-tool")
            .withStsClient(AWSSecurityTokenServiceClientBuilder.defaultClient())
            .build();

  AmazonECSClientBuilder ecsClientBuilder = AmazonECSClientBuilder.standard().withRegion(awsRegion)
  	.withCredentials(credentialsProvider);
  amazonECS = ecsClientBuilder.build();

shorea avatar Aug 15 '18 20:08 shorea

👍 I just ran into this.

phene avatar Nov 15 '18 19:11 phene

possible duplicate of #1521.

iancward avatar Dec 04 '18 21:12 iancward

Just ran into this issue myself Other SDKs already support the credential_source setting so this caught me by surprise

carlosrodf avatar Dec 12 '18 01:12 carlosrodf

Would like this feature in SDK and SDK 2, breaks our dev work flow.

ShibaBandit avatar Mar 13 '19 17:03 ShibaBandit

Supported in 2.5.30 https://github.com/aws/aws-sdk-java-v2/issues/1169

revbingo avatar Oct 03 '19 18:10 revbingo