diff --git a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3BasicCredentialsRestIT.java b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3BasicCredentialsRestIT.java
index 10901424512a3..cd17138a16fea 100644
--- a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3BasicCredentialsRestIT.java
+++ b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3BasicCredentialsRestIT.java
@@ -33,7 +33,7 @@ public class RepositoryS3BasicCredentialsRestIT extends AbstractRepositoryS3Rest
private static final String SECRET_KEY = PREFIX + "secret-key";
private static final String CLIENT = "basic_credentials_client";
- private static final S3HttpFixture s3Fixture = new S3HttpFixture(true, BUCKET, BASE_PATH, fixedAccessKey(ACCESS_KEY));
+ private static final S3HttpFixture s3Fixture = new S3HttpFixture(true, BUCKET, BASE_PATH, fixedAccessKey(ACCESS_KEY, "*", "s3"));
public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
.module("repository-s3")
diff --git a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3RestReloadCredentialsIT.java b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3RestReloadCredentialsIT.java
index 065d1c6c9ea27..0d133b30b5e39 100644
--- a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3RestReloadCredentialsIT.java
+++ b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3RestReloadCredentialsIT.java
@@ -39,7 +39,12 @@ public class RepositoryS3RestReloadCredentialsIT extends ESRestTestCase {
private static volatile String repositoryAccessKey;
- public static final S3HttpFixture s3Fixture = new S3HttpFixture(true, BUCKET, BASE_PATH, mutableAccessKey(() -> repositoryAccessKey));
+ public static final S3HttpFixture s3Fixture = new S3HttpFixture(
+ true,
+ BUCKET,
+ BASE_PATH,
+ mutableAccessKey(() -> repositoryAccessKey, "*", "s3")
+ );
private static final MutableSettingsProvider keystoreSettings = new MutableSettingsProvider();
diff --git a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3SessionCredentialsRestIT.java b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3SessionCredentialsRestIT.java
index a8009d594926f..c0b5aa989281c 100644
--- a/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3SessionCredentialsRestIT.java
+++ b/modules/repository-s3/src/javaRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3SessionCredentialsRestIT.java
@@ -38,7 +38,7 @@ public class RepositoryS3SessionCredentialsRestIT extends AbstractRepositoryS3Re
true,
BUCKET,
BASE_PATH,
- fixedAccessKeyAndToken(ACCESS_KEY, SESSION_TOKEN)
+ fixedAccessKeyAndToken(ACCESS_KEY, SESSION_TOKEN, "*", "s3")
);
public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
diff --git a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java
index d7f5a6e6dfe36..6963e329ddc86 100644
--- a/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java
+++ b/modules/repository-s3/src/main/java/org/elasticsearch/repositories/s3/S3BlobContainer.java
@@ -469,7 +469,7 @@ void executeSingleUpload(
S3BlobStore.configureRequestForMetrics(putRequest, blobStore, Operation.PUT_OBJECT, purpose);
try (AmazonS3Reference clientReference = s3BlobStore.clientReference()) {
- SocketAccess.doPrivilegedVoid(() -> { clientReference.client().putObject(putRequest); });
+ SocketAccess.doPrivilegedVoid(() -> clientReference.client().putObject(putRequest));
} catch (final AmazonClientException e) {
throw new IOException("Unable to upload object [" + blobName + "] using a single upload", e);
}
diff --git a/modules/repository-s3/src/yamlRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ClientYamlTestSuiteIT.java b/modules/repository-s3/src/yamlRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ClientYamlTestSuiteIT.java
index 89919f0f3ddf1..c0b7b447f8860 100644
--- a/modules/repository-s3/src/yamlRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ClientYamlTestSuiteIT.java
+++ b/modules/repository-s3/src/yamlRestTest/java/org/elasticsearch/repositories/s3/RepositoryS3ClientYamlTestSuiteIT.java
@@ -36,7 +36,7 @@ public class RepositoryS3ClientYamlTestSuiteIT extends AbstractRepositoryS3Clien
true,
"bucket",
"base_path_integration_tests",
- fixedAccessKey(ACCESS_KEY)
+ fixedAccessKey(ACCESS_KEY, "*", "s3")
);
public static ElasticsearchCluster cluster = ElasticsearchCluster.local()
diff --git a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2EnvironmentVariableCredentialsIT.java b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2EnvironmentVariableCredentialsIT.java
index 7fc5a2b4bcfae..620aa3d9b7282 100644
--- a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2EnvironmentVariableCredentialsIT.java
+++ b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2EnvironmentVariableCredentialsIT.java
@@ -29,7 +29,7 @@ public class DiscoveryEc2EnvironmentVariableCredentialsIT extends DiscoveryEc2Cl
private static final String ACCESS_KEY = PREFIX + "-access-key";
private static final AwsEc2HttpFixture ec2ApiFixture = new AwsEc2HttpFixture(
- fixedAccessKey(ACCESS_KEY),
+ fixedAccessKey(ACCESS_KEY, REGION, "ec2"),
DiscoveryEc2EnvironmentVariableCredentialsIT::getAvailableTransportEndpoints
);
diff --git a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreCredentialsIT.java b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreCredentialsIT.java
index c198ae5903ad4..8721b944d87de 100644
--- a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreCredentialsIT.java
+++ b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreCredentialsIT.java
@@ -29,7 +29,7 @@ public class DiscoveryEc2KeystoreCredentialsIT extends DiscoveryEc2ClusterFormat
private static final String ACCESS_KEY = PREFIX + "-access-key";
private static final AwsEc2HttpFixture ec2ApiFixture = new AwsEc2HttpFixture(
- fixedAccessKey(ACCESS_KEY),
+ fixedAccessKey(ACCESS_KEY, REGION, "ec2"),
DiscoveryEc2KeystoreCredentialsIT::getAvailableTransportEndpoints
);
diff --git a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreSessionCredentialsIT.java b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreSessionCredentialsIT.java
index e26ca0889e7b5..5e38f80d22611 100644
--- a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreSessionCredentialsIT.java
+++ b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2KeystoreSessionCredentialsIT.java
@@ -30,7 +30,7 @@ public class DiscoveryEc2KeystoreSessionCredentialsIT extends DiscoveryEc2Cluste
private static final String SESSION_TOKEN = PREFIX + "-session-token";
private static final AwsEc2HttpFixture ec2ApiFixture = new AwsEc2HttpFixture(
- fixedAccessKeyAndToken(ACCESS_KEY, SESSION_TOKEN),
+ fixedAccessKeyAndToken(ACCESS_KEY, SESSION_TOKEN, REGION, "ec2"),
DiscoveryEc2KeystoreSessionCredentialsIT::getAvailableTransportEndpoints
);
diff --git a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2SystemPropertyCredentialsIT.java b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2SystemPropertyCredentialsIT.java
index 28ca11696569b..745cd0a76b4ff 100644
--- a/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2SystemPropertyCredentialsIT.java
+++ b/plugins/discovery-ec2/src/javaRestTest/java/org/elasticsearch/discovery/ec2/DiscoveryEc2SystemPropertyCredentialsIT.java
@@ -29,7 +29,7 @@ public class DiscoveryEc2SystemPropertyCredentialsIT extends DiscoveryEc2Cluster
private static final String ACCESS_KEY = PREFIX + "-access-key";
private static final AwsEc2HttpFixture ec2ApiFixture = new AwsEc2HttpFixture(
- fixedAccessKey(ACCESS_KEY),
+ fixedAccessKey(ACCESS_KEY, REGION, "ec2"),
DiscoveryEc2SystemPropertyCredentialsIT::getAvailableTransportEndpoints
);
diff --git a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java
index 9000e06ca1350..aab6504f2d8c3 100644
--- a/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java
+++ b/test/fixtures/aws-fixture-utils/src/main/java/fixture/aws/AwsCredentialsUtils.java
@@ -24,26 +24,55 @@ public enum AwsCredentialsUtils {
;
/**
- * @return an authorization predicate that ensures the access key matches the given values.
+ * @return an authorization predicate that ensures the authorization header matches the given access key, region and service name.
+ * @see AWS v4 Signatures
+ * @param region the name of the AWS region used to sign the request, or {@code *} to skip validation of the region parameter
*/
- public static BiPredicate fixedAccessKey(String accessKey) {
- return mutableAccessKey(() -> accessKey);
+ public static BiPredicate fixedAccessKey(String accessKey, String region, String serviceName) {
+ return mutableAccessKey(() -> accessKey, region, serviceName);
}
/**
- * @return an authorization predicate that ensures the access key matches one supplied by the given supplier.
+ * @return an authorization predicate that ensures the authorization header matches the access key supplied by the given supplier,
+ * and also matches the given region and service name.
+ * @see AWS v4 Signatures
+ * @param region the name of the AWS region used to sign the request, or {@code *} to skip validation of the region parameter
*/
- public static BiPredicate mutableAccessKey(Supplier accessKeySupplier) {
- return (authorizationHeader, sessionTokenHeader) -> authorizationHeader != null
- && authorizationHeader.contains(accessKeySupplier.get());
+ public static BiPredicate mutableAccessKey(Supplier accessKeySupplier, String region, String serviceName) {
+ return (authorizationHeader, sessionTokenHeader) -> {
+ if (authorizationHeader == null) {
+ return false;
+ }
+
+ final var accessKey = accessKeySupplier.get();
+ final var expectedPrefix = "AWS4-HMAC-SHA256 Credential=" + accessKey + "/";
+ if (authorizationHeader.startsWith(expectedPrefix) == false) {
+ return false;
+ }
+
+ if (region.equals("*")) {
+ // skip region validation; TODO eliminate this when region is fixed in all tests
+ return authorizationHeader.contains("/" + serviceName + "/aws4_request, ");
+ }
+
+ final var remainder = authorizationHeader.substring(expectedPrefix.length() + "YYYYMMDD".length() /* skip over date field */);
+ return remainder.startsWith("/" + region + "/" + serviceName + "/aws4_request, ");
+ };
}
/**
- * @return an authorization predicate that ensures the access key and session token both match the given values.
+ * @return an authorization predicate that ensures the access key, session token, region and service name all match the given values.
+ * @see AWS v4 Signatures
+ * @param region the name of the AWS region used to sign the request, or {@code *} to skip validation of the region parameter
*/
- public static BiPredicate fixedAccessKeyAndToken(String accessKey, String sessionToken) {
+ public static BiPredicate fixedAccessKeyAndToken(
+ String accessKey,
+ String sessionToken,
+ String region,
+ String serviceName
+ ) {
Objects.requireNonNull(sessionToken);
- final var accessKeyPredicate = fixedAccessKey(accessKey);
+ final var accessKeyPredicate = fixedAccessKey(accessKey, region, serviceName);
return (authorizationHeader, sessionTokenHeader) -> accessKeyPredicate.test(authorizationHeader, sessionTokenHeader)
&& sessionToken.equals(sessionTokenHeader);
}
diff --git a/test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpFixture.java b/test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpFixture.java
index 538c57bc2bdea..2cb9627d4a087 100644
--- a/test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpFixture.java
+++ b/test/fixtures/s3-fixture/src/main/java/fixture/s3/S3HttpFixture.java
@@ -33,7 +33,7 @@ public class S3HttpFixture extends ExternalResource {
private final BiPredicate authorizationPredicate;
public S3HttpFixture(boolean enabled) {
- this(enabled, "bucket", "base_path_integration_tests", fixedAccessKey("s3_test_access_key"));
+ this(enabled, "bucket", "base_path_integration_tests", fixedAccessKey("s3_test_access_key", "*", "s3"));
}
public S3HttpFixture(boolean enabled, String bucket, String basePath, BiPredicate authorizationPredicate) {
diff --git a/x-pack/plugin/searchable-snapshots/qa/s3/src/javaRestTest/java/org/elasticsearch/xpack/searchablesnapshots/s3/S3SearchableSnapshotsCredentialsReloadIT.java b/x-pack/plugin/searchable-snapshots/qa/s3/src/javaRestTest/java/org/elasticsearch/xpack/searchablesnapshots/s3/S3SearchableSnapshotsCredentialsReloadIT.java
index bb5df5d37dba3..5889140bf2bab 100644
--- a/x-pack/plugin/searchable-snapshots/qa/s3/src/javaRestTest/java/org/elasticsearch/xpack/searchablesnapshots/s3/S3SearchableSnapshotsCredentialsReloadIT.java
+++ b/x-pack/plugin/searchable-snapshots/qa/s3/src/javaRestTest/java/org/elasticsearch/xpack/searchablesnapshots/s3/S3SearchableSnapshotsCredentialsReloadIT.java
@@ -47,7 +47,12 @@ public class S3SearchableSnapshotsCredentialsReloadIT extends ESRestTestCase {
private static volatile String repositoryAccessKey;
- public static final S3HttpFixture s3Fixture = new S3HttpFixture(true, BUCKET, BASE_PATH, mutableAccessKey(() -> repositoryAccessKey));
+ public static final S3HttpFixture s3Fixture = new S3HttpFixture(
+ true,
+ BUCKET,
+ BASE_PATH,
+ mutableAccessKey(() -> repositoryAccessKey, "*", "s3")
+ );
private static final MutableSettingsProvider keystoreSettings = new MutableSettingsProvider();