Skip to content

Adds accountId as a parameter to AWS credentials identity #4029

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

Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -20,6 +20,7 @@
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.CredentialUtils;
import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute;
import software.amazon.awssdk.awscore.AwsExecutionAttribute;
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.core.RequestOverrideConfiguration;
import software.amazon.awssdk.core.SdkRequest;
Expand Down Expand Up @@ -80,6 +81,8 @@ public void addCredentialsToExecutionAttributes(ExecutionAttributes executionAtt
AwsCredentials credentials = CredentialUtils.toCredentials(resolveCredentials(credentialsProvider, metricCollector));
// TODO: Should the signer be changed to use AwsCredentialsIdentity? Maybe with Signer SRA work, not now.
executionAttributes.putAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS, credentials);
// TODO: A separate execution attribute is not strictly needed; this can be optimized before release
executionAttributes.putAttribute(AwsExecutionAttribute.AWS_AUTH_ACCOUNT_ID, credentials.accountId().orElse(null));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package software.amazon.awssdk.identity.spi;

import java.util.Optional;
import software.amazon.awssdk.annotations.SdkPublicApi;
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.identity.spi.internal.DefaultAwsCredentialsIdentity;
Expand Down Expand Up @@ -43,6 +44,13 @@ public interface AwsCredentialsIdentity extends Identity {
*/
String secretAccessKey();

/**
* Retrieve the AWS account id associated with this credentials identity, if found.
*/
default Optional<String> accountId() {
return Optional.empty();
}

static Builder builder() {
return DefaultAwsCredentialsIdentity.builder();
}
Expand Down Expand Up @@ -70,6 +78,11 @@ interface Builder {
*/
Builder secretAccessKey(String secretAccessKey);

/**
* The AWS account id associated with this credentials identity.
*/
Builder accountId(String accountId);

AwsCredentialsIdentity build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ interface Builder extends AwsCredentialsIdentity.Builder {
@Override
Builder secretAccessKey(String secretAccessKey);

@Override
Builder accountId(String accountId);

/**
* The AWS session token, retrieved from an AWS token service, used for authenticating that this user has
* received temporary permission to access some resource.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package software.amazon.awssdk.identity.spi.internal;

import java.util.Objects;
import java.util.Optional;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
import software.amazon.awssdk.utils.ToString;
Expand All @@ -26,10 +27,12 @@ public final class DefaultAwsCredentialsIdentity implements AwsCredentialsIdenti

private final String accessKeyId;
private final String secretAccessKey;
private final String accountId;

private DefaultAwsCredentialsIdentity(Builder builder) {
this.accessKeyId = builder.accessKeyId;
this.secretAccessKey = builder.secretAccessKey;
this.accountId = builder.accountId;

Validate.paramNotNull(accessKeyId, "accessKeyId");
Validate.paramNotNull(secretAccessKey, "secretAccessKey");
Expand All @@ -49,10 +52,16 @@ public String secretAccessKey() {
return secretAccessKey;
}

@Override
public Optional<String> accountId() {
return Optional.ofNullable(accountId);
}

@Override
public String toString() {
return ToString.builder("AwsCredentialsIdentity")
.add("accessKeyId", accessKeyId)
.add("accountId", accountId)
.build();
}

Expand All @@ -66,20 +75,23 @@ public boolean equals(Object o) {
}
AwsCredentialsIdentity that = (AwsCredentialsIdentity) o;
return Objects.equals(accessKeyId, that.accessKeyId()) &&
Objects.equals(secretAccessKey, that.secretAccessKey());
Objects.equals(secretAccessKey, that.secretAccessKey()) &&
Objects.equals(accountId, that.accountId().orElse(null));
}

@Override
public int hashCode() {
int hashCode = 1;
hashCode = 31 * hashCode + Objects.hashCode(accessKeyId);
hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey);
hashCode = 31 * hashCode + Objects.hashCode(accountId);
return hashCode;
}

private static final class Builder implements AwsCredentialsIdentity.Builder {
private String accessKeyId;
private String secretAccessKey;
private String accountId;

private Builder() {
}
Expand All @@ -96,6 +108,12 @@ public Builder secretAccessKey(String secretAccessKey) {
return this;
}

@Override
public Builder accountId(String accountId) {
this.accountId = accountId;
return this;
}

@Override
public AwsCredentialsIdentity build() {
return new DefaultAwsCredentialsIdentity(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package software.amazon.awssdk.identity.spi.internal;

import java.util.Objects;
import java.util.Optional;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity;
import software.amazon.awssdk.utils.ToString;
Expand All @@ -27,11 +28,14 @@ public final class DefaultAwsSessionCredentialsIdentity implements AwsSessionCre
private final String accessKeyId;
private final String secretAccessKey;
private final String sessionToken;
private final String accountId;


private DefaultAwsSessionCredentialsIdentity(Builder builder) {
this.accessKeyId = builder.accessKeyId;
this.secretAccessKey = builder.secretAccessKey;
this.sessionToken = builder.sessionToken;
this.accountId = builder.accountId;

Validate.paramNotNull(accessKeyId, "accessKeyId");
Validate.paramNotNull(secretAccessKey, "secretAccessKey");
Expand All @@ -52,6 +56,11 @@ public String secretAccessKey() {
return secretAccessKey;
}

@Override
public Optional<String> accountId() {
return Optional.ofNullable(accountId);
}

@Override
public String sessionToken() {
return sessionToken;
Expand All @@ -61,6 +70,7 @@ public String sessionToken() {
public String toString() {
return ToString.builder("AwsSessionCredentialsIdentity")
.add("accessKeyId", accessKeyId)
.add("accountId", accountId)
.build();
}

Expand All @@ -75,7 +85,8 @@ public boolean equals(Object o) {
AwsSessionCredentialsIdentity that = (AwsSessionCredentialsIdentity) o;
return Objects.equals(accessKeyId, that.accessKeyId()) &&
Objects.equals(secretAccessKey, that.secretAccessKey()) &&
Objects.equals(sessionToken, that.sessionToken());
Objects.equals(sessionToken, that.sessionToken()) &&
Objects.equals(accountId, that.accountId().orElse(null));
}

@Override
Expand All @@ -84,13 +95,15 @@ public int hashCode() {
hashCode = 31 * hashCode + Objects.hashCode(accessKeyId);
hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey);
hashCode = 31 * hashCode + Objects.hashCode(sessionToken);
hashCode = 31 * hashCode + Objects.hashCode(accountId);
return hashCode;
}

private static final class Builder implements AwsSessionCredentialsIdentity.Builder {
private String accessKeyId;
private String secretAccessKey;
private String sessionToken;
private String accountId;

private Builder() {
}
Expand All @@ -113,6 +126,13 @@ public Builder sessionToken(String sessionToken) {
return this;
}


@Override
public Builder accountId(String accountId) {
this.accountId = accountId;
return this;
}

@Override
public AwsSessionCredentialsIdentity build() {
return new DefaultAwsSessionCredentialsIdentity(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
package software.amazon.awssdk.identity.spi;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.jupiter.api.Test;
Expand All @@ -26,6 +28,7 @@
public class AwsCredentialsIdentityTest {
private static final String ACCESS_KEY_ID = "accessKeyId";
private static final String SECRET_ACCESS_KEY = "secretAccessKey";
private static final String ACCOUNT_ID = "accountId";

@Test
public void equalsHashcode() {
Expand Down Expand Up @@ -53,15 +56,19 @@ public void create_isSuccessful() {
AwsCredentialsIdentity identity = AwsCredentialsIdentity.create(ACCESS_KEY_ID, SECRET_ACCESS_KEY);
assertEquals(ACCESS_KEY_ID, identity.accessKeyId());
assertEquals(SECRET_ACCESS_KEY, identity.secretAccessKey());
assertFalse(identity.accountId().isPresent());
}

@Test
public void build_isSuccessful() {
AwsCredentialsIdentity identity = AwsCredentialsIdentity.builder()
.accessKeyId(ACCESS_KEY_ID)
.secretAccessKey(SECRET_ACCESS_KEY)
.accountId(ACCOUNT_ID)
.build();
assertEquals(ACCESS_KEY_ID, identity.accessKeyId());
assertEquals(SECRET_ACCESS_KEY, identity.secretAccessKey());
assertTrue(identity.accountId().isPresent());
assertEquals(ACCOUNT_ID, identity.accountId().get());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
package software.amazon.awssdk.identity.spi;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.jupiter.api.Test;
Expand All @@ -27,6 +29,7 @@ public class AwsSessionCredentialsIdentityTest {
private static final String ACCESS_KEY_ID = "accessKeyId";
private static final String SECRET_ACCESS_KEY = "secretAccessKey";
private static final String SESSION_TOKEN = "sessionToken";
private static final String ACCOUNT_ID = "accountId";

@Test
public void equalsHashcode() {
Expand Down Expand Up @@ -63,6 +66,7 @@ public void create_isSuccessful() {
assertEquals(ACCESS_KEY_ID, identity.accessKeyId());
assertEquals(SECRET_ACCESS_KEY, identity.secretAccessKey());
assertEquals(SESSION_TOKEN, identity.sessionToken());
assertFalse(identity.accountId().isPresent());
}

@Test
Expand All @@ -71,9 +75,12 @@ public void build_isSuccessful() {
.accessKeyId(ACCESS_KEY_ID)
.secretAccessKey(SECRET_ACCESS_KEY)
.sessionToken(SESSION_TOKEN)
.accountId(ACCOUNT_ID)
.build();
assertEquals(ACCESS_KEY_ID, identity.accessKeyId());
assertEquals(SECRET_ACCESS_KEY, identity.secretAccessKey());
assertEquals(SESSION_TOKEN, identity.sessionToken());
assertTrue(identity.accountId().isPresent());
assertEquals(ACCOUNT_ID, identity.accountId().get());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,13 @@ public void fipsEnabledBuiltIn_returnsAttrValue() {
assertThat(AwsEndpointProviderUtils.fipsEnabledBuiltIn(attrs)).isEqualTo(true);
}

@Test
public void accountIdAuthBuiltIn_returnsAttrValue() {
ExecutionAttributes attrs = new ExecutionAttributes();
attrs.putAttribute(AwsExecutionAttribute.AWS_AUTH_ACCOUNT_ID, "1234567890");
assertThat(AwsEndpointProviderUtils.accountIdBuiltIn(attrs)).isEqualTo("1234567890");
}

@Test
public void endpointBuiltIn_doesNotIncludeQueryParams() {
URI endpoint = URI.create("https://example.com/path?foo=bar");
Expand Down