-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aws-cli role assumption profiles are incompatible with SDK #803
Comments
Thanks for reaching out to us. We'll talk about this with other SDK/CLI teams to try to reach to a consistent behavior. |
aws/aws-sdk-java#803 documents the incompatibility between the cli and the java sdk that prevents us from Just Being Able to Use The Default Behavior, or at least being able to supply the profile instead of the role explicitly.
Our workaround for this issue is to have duplicate profiles in
|
Hey guys, is there any progress with this ticket? We are using Boto3 SDK + Assuming Roles + Athena. I think the problem could be related to Athena using jdbc and as a result it falls back Java AWS SDK and Python being a wrapper around. As a result we can reach all AWS resources but Athena. Thank you. |
I've read a bit more on the topic and I'm not sure that it is even possible at this moment of time to make python and java work together (use cross accounts, boto3 and jdbc). Here is the error: |
This behaviour is quite annoying. @zhangzhx did you ever talk this one over with the other SDK/CLI contributors? To me this is more of a bug than a feature, here's why: The only thing should go into the credentials file is the The fact that the CLI has a different naming scheme for the profile heading is a separate issue. @uriahcarpenter said that duplicating the profiles in the config file is a workaround but it does not solve the real issue of how the credentials are found. |
Example of both problems
Preferred solution
|
We're baffled as to why this is labelled a feature rather than a bug - the Java SDK is clearly incompatible with the config + credentials formats supported and documented by https://docs.aws.amazon.com/cli/latest/userguide/cli-roles.html . |
It's unfortunately a very difficult issue to fix while maintaining backwards-compatibility. It has been fixed in the 2.0 preview of the SDK. The CLI's behavior isn't something that can be easily reproduced without a major version bump, because it's fundamentally at odds with the 1.11 behavior. In fact, the behavior that the reasonable person would expect is also at odds with the CLI's implementation. For example, the CLI currently merges duplicate profiles between configuration and credential files for assume-role credentials and regions, including non-credential properties like the source_profile. It uses separate logic for session and standard credentials where it looks at each file separately. The feature request for this issue is to create a "cli-compatible mode" for 1.11 that a customer can opt-into, outside of the current default behavior. That would keep the SDK's non-cli-compliant current behavior as the default, but give a workaround other than duplicating profiles. |
Appreciate those points, but don't think either have any bearing on whether this is a bug or not. Here's my hacky workaround, which avoids having to hack the credentials files themselves (not really feasible across a lot of clients), and supports switching roles, which I couldn't get to work even with duplicate profiles.
|
Nice workaround! Whether or not it's considered a bug, I can't see a way to fix it in a backwards-compatible way, because customers could be intentionally or unintentionally relying on this behavior. It's been around for a long time. This is a particularly egregious deviation from the CLI's behavior, but there are others that we'd want to fix as part of any solution we'd come up with. A higher-work, higher-accuracy workaround would be to back-port the 2.0 profile implementation to 1.11 and make it opt-in, which would be my suggestion for how to fix this. |
@adrian-baker thanks a lot for the workaround! Would it be ok if I use it in a closed-source project? Perhaps you could even license it explicitly (under MIT for instance)? |
Of course. I've put it into a gist with MIT license. |
Note a minor niggle with the code above -- while expecting users to drop If you want Great workaround though -- TY. |
For anyone who needs a Scala version of @adrian-baker's snippet: class AssumeRoleCredentialsProvider extends AWSCredentialsProvider {
private lazy val delegate: ProfileAssumeRoleCredentialsProvider = {
val profiles = Seq(
AwsProfileFileLocationProvider.DEFAULT_CONFIG_LOCATION_PROVIDER,
AwsProfileFileLocationProvider.DEFAULT_CREDENTIALS_LOCATION_PROVIDER
)
.map(_.getLocation)
.map(BasicProfileConfigLoader.INSTANCE.loadProfiles)
.flatMap(_.getProfiles.values.asScala)
.map(profile => new BasicProfile(profile.getProfileName.stripPrefix("profile "), profile.getProperties))
.groupBy(_.getProfileName)
.mapValues { profiles =>
new BasicProfile(
profiles.head.getProfileName,
profiles.flatMap(_.getProperties.asScala.toSeq).toMap.asJava
)
}
val profileName = AwsProfileNameLoader.INSTANCE.loadProfileName
val profile = profiles.getOrElse(profileName, throw new RuntimeException(
s"Profile $profileName' not found in ${profiles.keys}"
))
new ProfileAssumeRoleCredentialsProvider(
STSProfileCredentialsServiceLoader.getInstance,
new AllProfiles(profiles.asJava),
profile
)
}
override def getCredentials: AWSCredentials = delegate.getCredentials
override def refresh(): Unit = delegate.refresh()
} |
Hey, thanks for snippet. Now I am going even further, I want to a 2 assume roles in my chain: ~/.aws/credentials:
~/.aws/config:
The code snippet does not seem to support that. And I am unsure how to adjust it. The |
This is not a working workaround for me. |
Any plans to align the behavior of the AWS SDK with the other SDKs? I wonder why you share the same config file with other SDKs but use it differently. This is really confusing for me as a user. |
I just gave up on using the Java SDK at all. At this stage it can be considered broken. Using anything else Javascript, C# or Python gives you a much better option. Luckily the tools that we write are pretty small so it is easy to use the other SDKs. |
@jtheuer Because of this issue, the Java SDK team worked with the other AWS SDKs back in 2017 to write up a (long) profile file standard on which all SDKs can align going forward. That standard was written to (with a few exceptions) directly implement the CLI behavior. That standard was followed for the Java SDK 2.x, so it's quite compatible with the CLI. If you're willing to add the Java SDK 2.x to your classpath ( import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.BasicSessionCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
package com.example;
public class CliCompatibleCredentialsProvider implements AWSCredentialsProvider {
private final ProfileCredentialsProvider delegate;
public CliCompatibleCredentialsProvider() {
this.delegate = ProfileCredentialsProvider.create();
}
public CliCompatibleCredentialsProvider(String profileName) {
this.delegate = ProfileCredentialsProvider.create("my-profile-name");
}
@Override
public AWSCredentials getCredentials() {
AwsCredentials credentials = delegate.resolveCredentials();
if (credentials instanceof AwsSessionCredentials) {
AwsSessionCredentials sessionCredentials = (AwsSessionCredentials) credentials;
return new BasicSessionCredentials(sessionCredentials.accessKeyId(),
sessionCredentials.secretAccessKey(),
sessionCredentials.sessionToken());
}
return new BasicAWSCredentials(credentials.accessKeyId(), credentials.secretAccessKey());
}
@Override
public void refresh() {
throw new UnsupportedOperationException();
}
} We'd ideally like to implement the CLI-compatible standard natively in 1.11.x of the SDK, but because of resource limitations are focusing our efforts on getting 2.x up to feature parity with 1.11.x. |
hi, i just wanted to post our case and confirm that i do the right thing: Our setup is like so:
this is what i do now for local dev so that my app runs locally with the same role as in AWS:
This all works fine but makes the app run locally under the tier 2 user, which is undesirable for several reasons. I have not been able to setup a profile in the So what i do now in my app is this:
Note:what confused me a little was, that with this i got many more of the known warnings:
After debugging the code, i noticed that the internal logic will always parse the @RudolfVonKrugstein this case might be similar to ur's but i'm not sure |
To sum it up: The problem (at least for me) is that the AWS Java SDK will only know the profiles listed in So my
My
When I pass My solution/workaround to this problem is to not use So in my solution i keep
When I pass Extra: |
Hi! Other SDKs seem to swap between the behaviours depending on the environment variable AWS_SDK_LOAD_CONFIG=true. I wouldn't even mind if there is a java version of that environment variable so people can opt in. I think everybody would be happy with that. And I would not consider that a breaking change if you need to opt in via an environment variable. |
Hii, I am facing an issue some kind similar, i.e: my config file looks like: [default] [profile1] am trying to access AmazonElasticMapReduce service which this profile1 has access to. Now if I write ProfileCredentialsProvider("profile1").getCredentials(), it shows me an error like : "Exception in thread "main" com.amazonaws.AmazonClientException: Cannot load credentials from .aws/credentials file. Make sure that the credentials file exists and the profile name is specified within it." My CLI is working perfectly just by changing "profile prifile1" in .aws/config. |
JAVA SDK uses either one of the file, Config or credentials so the work around is [Profile_name] [replace ... with your actual value] in the classpath add dependency of aws-java-sdk-sts to class path Hope this helps...... |
Today's release should hopefully help with some of these issues. The 1.x SDK will now fall back to "profile X" if there is no "X" profile defined and the SDK is configured to look for profile X. There is no longer a warning if a "profile X" exists in the file. |
My setup: ~/.aws/config
~/.aws/credentials
Before version 79 I always got the error message for 4 times (one for each account in config). Now the message is gone, but the only profiles available are source1 and source2. So setting a profile via environment variable is still not working. This is at the moment expected because the SDK uses only one file? |
Yes, you still need to use v2 to get CLI-compatible behavior. v1 still only uses one file. |
Can we get the v2 behaviour hidden behind a flag? As mentioned above, AWS_SDK_LOAD_CONFIG=true worked for aws-sdk-go, I think it would be backward compatible and it would most definitely be a welcome change. I have a lot of code depending on SDKv1, and a rewrite to v2 will most likely never happen, so being able to have the SDK 'just work' by setting an env variable would be great. |
Hello everyone, Java SDK v1 won't get any more changes related to this issue. As a workaround, please check Matthew's comment for an adapter example using Java SDK v2 to have a CLI-compatible behavior in v1. The recommendation here is to migrate to Java SDK v2, which provides the same behavior as CLI. Reference:
|
This issue is now closed. Comments on closed issues are hard for our team to see. |
The CLI userguide instructs you to add delegated profiles to the file
~/.aws/config
. However, profiles added here are incompatible with the SDK.JavaDoc in
com.amazonaws.profile.path.AwsProfileFileLocationProvider
makes it clear that only one config file will be loaded (~/.aws/credentials
or~/.aws/config
).The confusion may be that CLI profiles that use keys are defined in
~/.aws/credentials
but profiles that usesource_profile
should be placed in~/.aws/config
. More details in the CLI configuration section.The workaround for this problem is to define the role assumption profile in
~/.aws/credentials
without theprofile
prefix. However, there are other tools that do not expected delegated profiles in this file, so this solution is imperfect.~/.aws/credentials
It would be very helpful if the Java SDK allowed role assumption profiles to be defined using the documented CLI format.
The text was updated successfully, but these errors were encountered: