This is an automated email from the ASF dual-hosted git repository.

tballison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git


The following commit(s) were added to refs/heads/main by this push:
     new edbfbf34b0 TIKA-5006: Support web identity (IRSA) credentials in the 
S3 plugin (#3439)
edbfbf34b0 is described below

commit edbfbf34b0e74a0f35313533f6503b12d3383970
Author: Bartek Ciszkowski <[email protected]>
AuthorDate: Tue Oct 27 14:36:30 2026 -0300

    TIKA-5006: Support web identity (IRSA) credentials in the S3 plugin (#3439)
    
    * TIKA-5006: Support web identity (IRSA) credentials in the S3 plugin
    
    On EKS, pods get AWS access through IAM roles for service accounts
    (IRSA). The pod is given a web identity token, with AWS_ROLE_ARN and
    AWS_WEB_IDENTITY_TOKEN_FILE set in its environment. The S3 plugin only
    supports instance, profile and key_secret, so there's no way to use the
    pod's role. Using instance picks up the node's role instead.
    
    This adds an `identity` credentialsProvider to the fetcher, emitter and
    pipes iterator, backed by the SDK's WebIdentityTokenFileCredentialsProvider.
    
    Additionally:
    
    * Added the sts module. The web identity provider needs it to exchange
      the token for credentials, but doesn't look for it until the first
      request. Without it, the fetcher builds fine and then fails on its
      first fetch.
    * Moved the fetcher's provider selection into buildCredentialsProvider,
      like the emitter has, so it can be tested without AWS.
    
    * fixup! TIKA-5006: Support web identity (IRSA) credentials in the S3 plugin
    
    * fixup! TIKA-5006: Support web identity (IRSA) credentials in the S3 plugin
    
    * fixup! TIKA-5006: Support web identity (IRSA) credentials in the S3 plugin
    
    * fixup! TIKA-5006: rename credentialsProvider identity to web_identity; 
CHANGES entry
    
    ---------
    
    Co-authored-by: tallison <[email protected]>
---
 CHANGES.txt                                        |  8 ++-
 docs/modules/ROOT/pages/pipes/plugins/s3.adoc      | 17 +++--
 .../tika-pipes-plugins/tika-pipes-s3/pom.xml       |  5 ++
 .../apache/tika/pipes/emitter/s3/S3Emitter.java    |  5 +-
 .../tika/pipes/emitter/s3/S3EmitterConfig.java     |  6 +-
 .../apache/tika/pipes/fetcher/s3/S3Fetcher.java    | 42 +++++++-----
 .../tika/pipes/iterator/s3/S3PipesIterator.java    |  6 +-
 .../tika/pipes/emitter/s3/S3EmitterConfigTest.java | 46 +++++++++++++
 .../pipes/fetcher/s3/S3FetcherCredentialsTest.java | 80 ++++++++++++++++++++++
 9 files changed, 184 insertions(+), 31 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index e36c8e43b2..9826420af3 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,10 @@
-Release 4.2.1 - ???
+Release 4.2.1 - unreleased
+
+  SERVER, PIPES AND OPERATIONS
+
+   * The S3 fetcher, emitter and pipes iterator accept credentialsProvider 
"web_identity"
+     for EKS IAM roles for service accounts (IRSA); the plugin now bundles the 
AWS STS
+     module it needs (TIKA-5006).
 
   OTHER CHANGES
 
diff --git a/docs/modules/ROOT/pages/pipes/plugins/s3.adoc 
b/docs/modules/ROOT/pages/pipes/plugins/s3.adoc
index 2721686204..c6b791fa3e 100644
--- a/docs/modules/ROOT/pages/pipes/plugins/s3.adoc
+++ b/docs/modules/ROOT/pages/pipes/plugins/s3.adoc
@@ -44,10 +44,13 @@ The Amazon S3 plugin (`tika-pipes-s3`) provides fetcher, 
emitter, and iterator i
 All three components share the same `credentialsProvider` selector:
 
 * `profile` — reads credentials from the local AWS profile named by `profile` 
(e.g., `default`).
-* `instance` — uses the instance/container role attached to the host (EC2 IAM 
role, ECS task role, etc.). No additional fields needed.
+* `instance` — uses the IAM role of the EC2 instance the host runs on, read 
from the instance metadata service. No additional fields needed.
+* `web_identity` — assumes a role with a web identity token, as EKS IAM roles 
for service accounts (IRSA) provide. Reads the role from `AWS_ROLE_ARN` and the 
token from `AWS_WEB_IDENTITY_TOKEN_FILE`, which EKS sets on the pod. No 
additional fields needed.
 * `key_secret` — reads `accessKey` and `secretKey` from the config. Avoid 
checking these into source control; prefer environment-variable substitution or 
one of the other providers.
 
-The emitter's `validate()` enforces these values, but the fetcher and iterator 
do not — they fail later when the AWS SDK tries to resolve credentials.
+All three components reject any other value when they are created. If 
`credentialsProvider` is unset, the emitter's `validate()` rejects it, but the 
fetcher and iterator fall back to `instance`.
+
+ECS task roles and EKS Pod Identity are not supported — neither `instance` nor 
`web_identity` picks them up.
 
 [#s3-fetcher]
 == S3 Fetcher (`s3-fetcher`)
@@ -78,8 +81,8 @@ include::example$pipes-s3-fetcher.json[]
 |Optional key prefix, prepended verbatim to the fetch key — include the 
trailing `/` yourself. Leave it unset when the fetch keys already carry the 
prefix (see <<prefix-warning>>).
 
 |`credentialsProvider`
-|_required_
-|One of `profile`, `instance`, `key_secret`. See <<credentials>>.
+|`instance`
+|One of `profile`, `instance`, `web_identity`, `key_secret`. See 
<<credentials>>.
 
 |`profile` / `accessKey` / `secretKey`
 |_conditional_
@@ -141,7 +144,7 @@ include::example$pipes-s3-emitter.json[]
 
 |`credentialsProvider`
 |_required_
-|One of `profile`, `instance`, `key_secret` (validated). See <<credentials>>.
+|One of `profile`, `instance`, `web_identity`, `key_secret` (validated). See 
<<credentials>>.
 
 |`profile` / `accessKey` / `secretKey`
 |_conditional_
@@ -203,8 +206,8 @@ In addition to the required `fetcherId` / `emitterId` (see 
xref:pipes/iterators.
 |Key prefix to scope the listing.
 
 |`credentialsProvider`
-|_none_
-|One of `profile`, `instance`, `key_secret`. See <<credentials>>.
+|`instance`
+|One of `profile`, `instance`, `web_identity`, `key_secret`. See 
<<credentials>>.
 
 |`profile` / `accessKey` / `secretKey` / `endpointConfigurationService`
 |_conditional_
diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/pom.xml 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/pom.xml
index 8e29cb73a2..17156dd5cc 100644
--- a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/pom.xml
+++ b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/pom.xml
@@ -49,6 +49,11 @@
       <groupId>software.amazon.awssdk</groupId>
       <artifactId>apache-client</artifactId>
     </dependency>
+    <dependency>
+      <!-- WebIdentityTokenFileCredentialsProvider ('web_identity') loads STS 
reflectively -->
+      <groupId>software.amazon.awssdk</groupId>
+      <artifactId>sts</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-slf4j2-impl</artifactId>
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3Emitter.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3Emitter.java
index c73a14f638..8ceadde02e 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3Emitter.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3Emitter.java
@@ -39,6 +39,7 @@ import 
software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
 import 
software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider;
 import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
 import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import 
software.amazon.awssdk.auth.credentials.WebIdentityTokenFileCredentialsProvider;
 import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
 import software.amazon.awssdk.core.exception.SdkClientException;
 import software.amazon.awssdk.core.sync.RequestBody;
@@ -140,6 +141,8 @@ public class S3Emitter extends AbstractStreamEmitter {
         switch (config.credentialsProvider()) {
             case "instance":
                 return InstanceProfileCredentialsProvider.builder().build();
+            case "web_identity":
+                return 
WebIdentityTokenFileCredentialsProvider.builder().build();
             case "profile":
                 return ProfileCredentialsProvider.builder()
                         .profileName(config.profile())
@@ -149,7 +152,7 @@ public class S3Emitter extends AbstractStreamEmitter {
                         config.accessKey(), config.secretKey());
                 return StaticCredentialsProvider.create(awsCreds);
             default:
-                throw new TikaConfigException("credentialsProvider must be 
'instance', 'profile' or 'key_secret'");
+                throw new TikaConfigException("credentialsProvider must be 
'instance', 'web_identity', 'profile' or 'key_secret'");
         }
     }
 
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfig.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfig.java
index 868f46cc53..0301abdf30 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfig.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfig.java
@@ -67,13 +67,15 @@ public record S3EmitterConfig(
             throw new TikaConfigException("'region' must not be empty");
         }
         if (credentialsProvider == null || credentialsProvider.isBlank()) {
-            throw new TikaConfigException("'credentialsProvider' must be set 
to 'profile', 'instance' or 'key_secret'");
+            throw new TikaConfigException("'credentialsProvider' must be set 
to 'profile', 'instance', 'web_identity' or 'key_secret'");
         }
         if (!credentialsProvider.equals("profile")
                 && !credentialsProvider.equals("instance")
+                && !credentialsProvider.equals("web_identity")
                 && !credentialsProvider.equals("key_secret")) {
             throw new TikaConfigException(
-                    "credentialsProvider must be 'profile', 'instance' or 
'key_secret', but was: " + credentialsProvider);
+                    "credentialsProvider must be 'profile', 'instance', 
'web_identity' or 'key_secret', but was: "
+                            + credentialsProvider);
         }
         if (credentialsProvider.equals("profile") && (profile == null || 
profile.isBlank())) {
             throw new TikaConfigException("'profile' must be set when 
credentialsProvider is 'profile'");
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/S3Fetcher.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/S3Fetcher.java
index 88748941f6..2d2a175b13 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/S3Fetcher.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/S3Fetcher.java
@@ -34,6 +34,7 @@ import 
software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
 import 
software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider;
 import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
 import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import 
software.amazon.awssdk.auth.credentials.WebIdentityTokenFileCredentialsProvider;
 import software.amazon.awssdk.awscore.exception.AwsServiceException;
 import software.amazon.awssdk.core.ResponseInputStream;
 import software.amazon.awssdk.core.exception.SdkClientException;
@@ -106,25 +107,7 @@ public class S3Fetcher extends AbstractTikaExtension 
implements Fetcher, RangeFe
         ConfigValidator.mustNotBeEmpty("bucket", config.getBucket());
         ConfigValidator.mustNotBeEmpty("region", config.getRegion());
 
-        AwsCredentialsProvider provider;
-        String credentialsProvider = config.getCredentialsProvider();
-        if (credentialsProvider == null) {
-            credentialsProvider = "instance";
-        }
-        switch (credentialsProvider) {
-            case "instance":
-                provider = 
InstanceProfileCredentialsProvider.builder().build();
-                break;
-            case "profile":
-                provider = 
ProfileCredentialsProvider.builder().profileName(config.getProfile()).build();
-                break;
-            case "key_secret":
-                AwsBasicCredentials awsCreds = 
AwsBasicCredentials.create(config.getAccessKey(), config.getSecretKey());
-                provider = StaticCredentialsProvider.create(awsCreds);
-                break;
-            default:
-                throw new TikaConfigException("credentialsProvider must be set 
and must be either 'instance', 'profile' or 'key_secret'");
-        }
+        AwsCredentialsProvider provider = buildCredentialsProvider(config);
 
         int maxConnections = config.getMaxConnections();
         if (maxConnections <= 0) {
@@ -153,6 +136,27 @@ public class S3Fetcher extends AbstractTikaExtension 
implements Fetcher, RangeFe
         }
     }
 
+    static AwsCredentialsProvider buildCredentialsProvider(S3FetcherConfig 
config) throws TikaConfigException {
+        String credentialsProvider = config.getCredentialsProvider();
+        if (credentialsProvider == null) {
+            credentialsProvider = "instance";
+        }
+        switch (credentialsProvider) {
+            case "instance":
+                return InstanceProfileCredentialsProvider.builder().build();
+            case "web_identity":
+                return 
WebIdentityTokenFileCredentialsProvider.builder().build();
+            case "profile":
+                return 
ProfileCredentialsProvider.builder().profileName(config.getProfile()).build();
+            case "key_secret":
+                AwsBasicCredentials awsCreds = 
AwsBasicCredentials.create(config.getAccessKey(), config.getSecretKey());
+                return StaticCredentialsProvider.create(awsCreds);
+            default:
+                throw new TikaConfigException("credentialsProvider must be set 
and must be either "
+                        + "'instance', 'web_identity', 'profile' or 
'key_secret'");
+        }
+    }
+
     @Override
     public TikaInputStream fetch(String fetchKey, Metadata metadata, 
ParseContext parseContext) throws TikaException, IOException {
         return fetch(fetchKey, -1, -1, metadata, parseContext);
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/iterator/s3/S3PipesIterator.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/iterator/s3/S3PipesIterator.java
index 328732b10c..55507fee39 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/iterator/s3/S3PipesIterator.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/iterator/s3/S3PipesIterator.java
@@ -31,6 +31,7 @@ import 
software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
 import 
software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider;
 import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
 import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import 
software.amazon.awssdk.auth.credentials.WebIdentityTokenFileCredentialsProvider;
 import software.amazon.awssdk.core.exception.SdkClientException;
 import software.amazon.awssdk.http.SdkHttpClient;
 import software.amazon.awssdk.http.apache.ApacheHttpClient;
@@ -84,6 +85,9 @@ public class S3PipesIterator extends PipesIteratorBase {
             case "instance":
                 provider = 
InstanceProfileCredentialsProvider.builder().build();
                 break;
+            case "web_identity":
+                provider = 
WebIdentityTokenFileCredentialsProvider.builder().build();
+                break;
             case "profile":
                 provider = 
ProfileCredentialsProvider.builder().profileName(config.getProfile()).build();
                 break;
@@ -92,7 +96,7 @@ public class S3PipesIterator extends PipesIteratorBase {
                 provider = StaticCredentialsProvider.create(awsCreds);
                 break;
             default:
-                throw new TikaConfigException("credentialsProvider must be set 
and " + "must be either 'instance', 'profile' or 'key_secret'");
+                throw new TikaConfigException("credentialsProvider must be set 
and must be either 'instance', 'web_identity', 'profile' or 'key_secret'");
         }
 
         SdkHttpClient httpClient = 
ApacheHttpClient.builder().maxConnections(config.getMaxConnections()).build();
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/test/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfigTest.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/test/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfigTest.java
new file mode 100644
index 0000000000..cc91d27f9d
--- /dev/null
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/test/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfigTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.pipes.emitter.s3;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+import org.apache.tika.exception.TikaConfigException;
+
+public class S3EmitterConfigTest {
+
+    @Test
+    public void testWebIdentityIsValid() throws Exception {
+        S3EmitterConfig config = load("web_identity");
+        assertDoesNotThrow(config::validate);
+    }
+
+    @Test
+    public void testUnknownProviderIsInvalid() throws Exception {
+        S3EmitterConfig config = load("bogus");
+        TikaConfigException e = assertThrows(TikaConfigException.class, 
config::validate);
+        assertTrue(e.getMessage().contains("'web_identity'"), e.getMessage());
+    }
+
+    private static S3EmitterConfig load(String credentialsProvider) throws 
TikaConfigException {
+        return S3EmitterConfig.load("{\"bucket\": \"bucket\", \"region\": 
\"us-east-1\", "
+                + "\"credentialsProvider\": \"" + credentialsProvider + "\"}");
+    }
+}
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/test/java/org/apache/tika/pipes/fetcher/s3/S3FetcherCredentialsTest.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/test/java/org/apache/tika/pipes/fetcher/s3/S3FetcherCredentialsTest.java
new file mode 100644
index 0000000000..b16917c6d7
--- /dev/null
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/test/java/org/apache/tika/pipes/fetcher/s3/S3FetcherCredentialsTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.pipes.fetcher.s3;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import 
software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import 
software.amazon.awssdk.auth.credentials.WebIdentityTokenFileCredentialsProvider;
+
+import org.apache.tika.exception.TikaConfigException;
+import org.apache.tika.pipes.fetcher.s3.config.S3FetcherConfig;
+import org.apache.tika.plugins.ExtensionConfig;
+
+public class S3FetcherCredentialsTest {
+
+    @Test
+    public void testWebIdentity() throws Exception {
+        assertInstanceOf(WebIdentityTokenFileCredentialsProvider.class,
+                S3Fetcher.buildCredentialsProvider(new 
S3FetcherConfig().setCredentialsProvider("web_identity")));
+    }
+
+    @Test
+    public void testDefaultsToInstance() throws Exception {
+        assertInstanceOf(InstanceProfileCredentialsProvider.class,
+                S3Fetcher.buildCredentialsProvider(new S3FetcherConfig()));
+    }
+
+    @Test
+    public void testKeySecret() throws Exception {
+        S3FetcherConfig config = new S3FetcherConfig()
+                .setCredentialsProvider("key_secret")
+                .setAccessKey("access")
+                .setSecretKey("secret");
+        assertInstanceOf(StaticCredentialsProvider.class, 
S3Fetcher.buildCredentialsProvider(config));
+    }
+
+    @Test
+    public void testUnknownProvider() {
+        TikaConfigException e = assertThrows(TikaConfigException.class,
+                () -> S3Fetcher.buildCredentialsProvider(new 
S3FetcherConfig().setCredentialsProvider("bogus")));
+        assertTrue(e.getMessage().contains("'web_identity'"), e.getMessage());
+    }
+
+    @Test
+    public void testBuildWithWebIdentity() throws Exception {
+        // Credentials resolve on the first request, so the fetcher builds 
without a web identity
+        // token in the environment.
+        String json = "{\"bucket\": \"bucket\", \"region\": \"us-east-1\", 
\"credentialsProvider\": \"web_identity\"}";
+        assertNotNull(S3Fetcher.build(new ExtensionConfig("s3", "s3-fetcher", 
json)));
+    }
+
+    @Test
+    public void testStsAvailable() {
+        // The web identity provider loads this from the sts module when 
resolving credentials.
+        // Without it, every request fails with "To use web identity tokens, 
the 'sts' service
+        // module must be on the class path."
+        assertDoesNotThrow(() -> Class.forName(
+                
"software.amazon.awssdk.services.sts.internal.StsWebIdentityCredentialsProviderFactory"));
+    }
+}

Reply via email to