Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,23 @@ public interface ChildProfileCredentialsProviderFactory {
* provider.
* @return The credentials provider with permissions derived from the source credentials provider and profile.
*/
AwsCredentialsProvider create(AwsCredentialsProvider sourceCredentialsProvider, Profile profile);
default AwsCredentialsProvider create(AwsCredentialsProvider sourceCredentialsProvider, Profile profile) {
return create(sourceCredentialsProvider, profile, null);
}

/**
* Create a credentials provider for the provided profile, using the provided source credentials provider to authenticate
* with AWS. In the case of STS, the returned credentials provider is for a role that has been assumed, and the provided
* source credentials provider is the credentials that should be used to authenticate that the user is allowed to assume
* that role.
*
* @param sourceCredentialsProvider The credentials provider that should be used to authenticate the child credentials
* provider. This credentials provider should be closed when it is no longer used.
* @param profile The profile that should be used to load the configuration necessary to create the child credentials
* provider.
* @param source A string list of {@link software.amazon.awssdk.core.useragent.BusinessMetricFeatureId} denoting
* previous credentials providers that are chained with this one.
* @return The credentials provider with permissions derived from the source credentials provider and profile.
*/
AwsCredentialsProvider create(AwsCredentialsProvider sourceCredentialsProvider, Profile profile, String source);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package software.amazon.awssdk.auth.credentials;

import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
import software.amazon.awssdk.utils.SdkAutoCloseable;

/**
Expand Down Expand Up @@ -49,7 +50,8 @@ interface Builder<TypeToBuildT extends HttpCredentialsProvider, BuilderT extends
BuilderT endpoint(String endpoint);

/**
* Configure the source of this credentials provider. This is used for business metrics tracking.
* An optional string list of {@link BusinessMetricFeatureId} denoting previous credentials providers
* that are chained with this one.
*/
default BuilderT source(String source) {
throw new UnsupportedOperationException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.auth.credentials.SystemPropertyCredentialsProvider;
import software.amazon.awssdk.core.internal.util.ClassLoaderHelper;
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
import software.amazon.awssdk.profiles.Profile;
import software.amazon.awssdk.profiles.ProfileFile;
import software.amazon.awssdk.profiles.ProfileProperty;
Expand Down Expand Up @@ -161,6 +162,7 @@ private AwsCredentialsProvider basicProfileCredentialsProvider() {
.accessKeyId(properties.get(ProfileProperty.AWS_ACCESS_KEY_ID))
.secretAccessKey(properties.get(ProfileProperty.AWS_SECRET_ACCESS_KEY))
.accountId(properties.get(ProfileProperty.AWS_ACCOUNT_ID))
.providerName(BusinessMetricFeatureId.CREDENTIALS_PROFILE.value())
.build();
return StaticCredentialsProvider.create(credentials);
}
Expand All @@ -177,6 +179,7 @@ private AwsCredentialsProvider sessionProfileCredentialsProvider() {
.secretAccessKey(properties.get(ProfileProperty.AWS_SECRET_ACCESS_KEY))
.sessionToken(properties.get(ProfileProperty.AWS_SESSION_TOKEN))
.accountId(properties.get(ProfileProperty.AWS_ACCOUNT_ID))
.providerName(BusinessMetricFeatureId.CREDENTIALS_PROFILE.value())
.build();
return StaticCredentialsProvider.create(credentials);
}
Expand All @@ -187,28 +190,36 @@ private AwsCredentialsProvider credentialProcessCredentialsProvider() {
return ProcessCredentialsProvider.builder()
.command(properties.get(ProfileProperty.CREDENTIAL_PROCESS))
.staticAccountId(properties.get(ProfileProperty.AWS_ACCOUNT_ID))
.source(BusinessMetricFeatureId.CREDENTIALS_PROFILE_PROCESS.value())
.build();
}

/**
* Create the SSO credentials provider based on the related profile properties.
*/
private AwsCredentialsProvider ssoProfileCredentialsProvider() {
validateRequiredPropertiesForSsoCredentialsProvider();
boolean isLegacy = validateRequiredPropertiesForSsoCredentialsProvider();
String source = isLegacy ?
BusinessMetricFeatureId.CREDENTIALS_PROFILE_SSO_LEGACY.value() :
BusinessMetricFeatureId.CREDENTIALS_PROFILE_SSO.value();

return ssoCredentialsProviderFactory().create(
ProfileProviderCredentialsContext.builder()
.profile(profile)
.profileFile(profileFile)
.source(source)
.build());
}

private void validateRequiredPropertiesForSsoCredentialsProvider() {
private boolean validateRequiredPropertiesForSsoCredentialsProvider() {
requireProperties(ProfileProperty.SSO_ACCOUNT_ID,
ProfileProperty.SSO_ROLE_NAME);

if (!properties.containsKey(ProfileSection.SSO_SESSION.getPropertyKeyName())) {
requireProperties(ProfileProperty.SSO_REGION, ProfileProperty.SSO_START_URL);
return true;
}
return false;
}

private AwsCredentialsProvider roleAndWebIdentityTokenProfileCredentialsProvider() {
Expand All @@ -223,6 +234,7 @@ private AwsCredentialsProvider roleAndWebIdentityTokenProfileCredentialsProvider
.roleArn(roleArn)
.roleSessionName(roleSessionName)
.webIdentityTokenFile(webIdentityTokenFile)
.source(BusinessMetricFeatureId.CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN.value())
.build();

return WebIdentityCredentialsUtils.factory().create(credentialProperties);
Expand Down Expand Up @@ -260,18 +272,20 @@ private AwsCredentialsProvider roleAndCredentialSourceBasedProfileCredentialsPro
requireProperties(ProfileProperty.CREDENTIAL_SOURCE);

CredentialSourceType credentialSource = CredentialSourceType.parse(properties.get(ProfileProperty.CREDENTIAL_SOURCE));
AwsCredentialsProvider credentialsProvider = credentialSourceCredentialProvider(credentialSource);
return stsCredentialsProviderFactory().create(credentialsProvider, profile);
String source = BusinessMetricFeatureId.CREDENTIALS_PROFILE_NAMED_PROVIDER.value();
AwsCredentialsProvider credentialsProvider = credentialSourceCredentialProvider(credentialSource, source);
return stsCredentialsProviderFactory().create(credentialsProvider, profile, source);
}

private AwsCredentialsProvider credentialSourceCredentialProvider(CredentialSourceType credentialSource) {
private AwsCredentialsProvider credentialSourceCredentialProvider(CredentialSourceType credentialSource, String source) {
switch (credentialSource) {
case ECS_CONTAINER:
return ContainerCredentialsProvider.builder().build();
return ContainerCredentialsProvider.builder().source(source).build();
case EC2_INSTANCE_METADATA:
return InstanceProfileCredentialsProvider.builder()
.profileFile(profileFile)
.profileName(name)
.source(source)
.build();
case ENVIRONMENT:
return AwsCredentialsProviderChain.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
import software.amazon.awssdk.utils.StringUtils;
import software.amazon.awssdk.utils.ToString;
import software.amazon.awssdk.utils.Validate;
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
Expand All @@ -49,8 +51,9 @@
public final class StsAssumeRoleCredentialsProvider
extends StsCredentialsProvider
implements ToCopyableBuilder<StsAssumeRoleCredentialsProvider.Builder, StsAssumeRoleCredentialsProvider> {
private static final String PROVIDER_NAME = "StsAssumeRoleCredentialsProvider";
private static final String PROVIDER_NAME = BusinessMetricFeatureId.CREDENTIALS_STS_ASSUME_ROLE.value();
private final Supplier<AssumeRoleRequest> assumeRoleRequestSupplier;
private final String source;

/**
* @see #builder()
Expand All @@ -60,6 +63,7 @@ private StsAssumeRoleCredentialsProvider(Builder builder) {
Validate.notNull(builder.assumeRoleRequestSupplier, "Assume role request must not be null.");

this.assumeRoleRequestSupplier = builder.assumeRoleRequestSupplier;
this.source = builder.source;
}

/**
Expand All @@ -75,7 +79,7 @@ protected AwsSessionCredentials getUpdatedCredentials(StsClient stsClient) {
Validate.notNull(assumeRoleRequest, "Assume role request must not be null.");
AssumeRoleResponse assumeRoleResponse = stsClient.assumeRole(assumeRoleRequest);
return fromStsCredentials(assumeRoleResponse.credentials(),
PROVIDER_NAME,
providerName(),
accountIdFromArn(assumeRoleResponse.assumedRoleUser()));
}

Expand All @@ -93,7 +97,11 @@ public Builder toBuilder() {

@Override
String providerName() {
return PROVIDER_NAME;
String providerName = PROVIDER_NAME;
if (!StringUtils.isEmpty(this.source)) {
providerName = String.format("%s,%s", this.source, providerName);
}
return providerName;
}

/**
Expand All @@ -103,6 +111,7 @@ String providerName() {
@NotThreadSafe
public static final class Builder extends BaseBuilder<Builder, StsAssumeRoleCredentialsProvider> {
private Supplier<AssumeRoleRequest> assumeRoleRequestSupplier;
private String source;

private Builder() {
super(StsAssumeRoleCredentialsProvider::new);
Expand All @@ -111,6 +120,7 @@ private Builder() {
private Builder(StsAssumeRoleCredentialsProvider provider) {
super(StsAssumeRoleCredentialsProvider::new, provider);
this.assumeRoleRequestSupplier = provider.assumeRoleRequestSupplier;
this.source = provider.source;
}

/**
Expand Down Expand Up @@ -145,6 +155,15 @@ public Builder refreshRequest(Consumer<AssumeRoleRequest.Builder> assumeRoleRequ
return refreshRequest(AssumeRoleRequest.builder().applyMutation(assumeRoleRequest).build());
}

/**
* An optional string list of {@link BusinessMetricFeatureId} denoting previous credentials providers
* that are chained with this one.
*/
public Builder source(String source) {
this.source = source;
return this;
}

@Override
public StsAssumeRoleCredentialsProvider build() {
return super.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsSessionCredentials;
import software.amazon.awssdk.core.useragent.BusinessMetricFeatureId;
import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.model.AssumeRoleWithSamlRequest;
import software.amazon.awssdk.services.sts.model.AssumeRoleWithSamlResponse;
import software.amazon.awssdk.utils.StringUtils;
import software.amazon.awssdk.utils.Validate;
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;

Expand All @@ -48,8 +50,9 @@
public final class StsAssumeRoleWithSamlCredentialsProvider
extends StsCredentialsProvider
implements ToCopyableBuilder<StsAssumeRoleWithSamlCredentialsProvider.Builder, StsAssumeRoleWithSamlCredentialsProvider> {
private static final String PROVIDER_NAME = "StsAssumeRoleWithSamlCredentialsProvider";
private static final String PROVIDER_NAME = BusinessMetricFeatureId.CREDENTIALS_STS_ASSUME_ROLE_SAML.value();
private final Supplier<AssumeRoleWithSamlRequest> assumeRoleWithSamlRequestSupplier;
private final String source;


/**
Expand All @@ -60,6 +63,7 @@ private StsAssumeRoleWithSamlCredentialsProvider(Builder builder) {
Validate.notNull(builder.assumeRoleWithSamlRequestSupplier, "Assume role with SAML request must not be null.");

this.assumeRoleWithSamlRequestSupplier = builder.assumeRoleWithSamlRequestSupplier;
this.source = builder.source;
}

/**
Expand All @@ -75,7 +79,7 @@ protected AwsSessionCredentials getUpdatedCredentials(StsClient stsClient) {
Validate.notNull(assumeRoleWithSamlRequest, "Assume role with saml request must not be null.");
AssumeRoleWithSamlResponse assumeRoleResponse = stsClient.assumeRoleWithSAML(assumeRoleWithSamlRequest);
return fromStsCredentials(assumeRoleResponse.credentials(),
PROVIDER_NAME,
providerName(),
accountIdFromArn(assumeRoleResponse.assumedRoleUser()));
}

Expand All @@ -86,7 +90,11 @@ public Builder toBuilder() {

@Override
String providerName() {
return PROVIDER_NAME;
String providerName = PROVIDER_NAME;
if (!StringUtils.isEmpty(this.source)) {
providerName = String.format("%s,%s", this.source, providerName);
}
return providerName;
}

/**
Expand All @@ -96,6 +104,7 @@ String providerName() {
@NotThreadSafe
public static final class Builder extends BaseBuilder<Builder, StsAssumeRoleWithSamlCredentialsProvider> {
private Supplier<AssumeRoleWithSamlRequest> assumeRoleWithSamlRequestSupplier;
private String source;

private Builder() {
super(StsAssumeRoleWithSamlCredentialsProvider::new);
Expand All @@ -104,6 +113,7 @@ private Builder() {
public Builder(StsAssumeRoleWithSamlCredentialsProvider provider) {
super(StsAssumeRoleWithSamlCredentialsProvider::new, provider);
this.assumeRoleWithSamlRequestSupplier = provider.assumeRoleWithSamlRequestSupplier;
this.source = provider.source;
}

/**
Expand Down Expand Up @@ -138,6 +148,18 @@ public Builder refreshRequest(Consumer<AssumeRoleWithSamlRequest.Builder> assume
return refreshRequest(AssumeRoleWithSamlRequest.builder().applyMutation(assumeRoleWithSamlRequest).build());
}

/**
* Configure the source of this credentials provider. This is used for business metrics tracking
* to identify the credential provider chain.
*
* @param source The source identifier for business metrics tracking.
* @return This object for chained calls.
*/
public Builder source(String source) {
this.source = source;
return this;
}

@Override
public StsAssumeRoleWithSamlCredentialsProvider build() {
return super.build();
Expand Down
Loading