Skip to content

Support AWS EKS Pod Identity in IamAwsProvider - #1719

Merged
balamurugana merged 1 commit into
minio:masterfrom
balamurugana:fix-issue-1717
Sep 16, 2026
Merged

balamurugana merged 1 commit into
minio:masterfrom
balamurugana:fix-issue-1717

Conversation

@balamurugana

@balamurugana balamurugana commented Sep 15, 2026

Copy link
Copy Markdown
Member

EKS Pod Identity Agent exposes credentials over a container credential endpoint; it injects AWS_CONTAINER_CREDENTIALS_FULL_URI pointing to its link-local address and passes the authorization token in a file. Two gaps denied it.

  • AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE was not read at all, hence no authorization token was sent. It is read now and takes precedence over AWS_CONTAINER_AUTHORIZATION_TOKEN as done by AWS. Trailing newline of the file is removed as it is denied as HTTP header value.
  • The host of AWS_CONTAINER_CREDENTIALS_FULL_URI was denied unless it resolved to loopback addresses only. As done by AWS, the ECS and EKS Pod Identity link-local addresses 169.254.170.2, 169.254.170.23 and fd00:ec2::23 are allowed as well, and the check is skipped for HTTPS endpoints.

Along with it, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is parsed as URI than added as path segments; AWS sets the value with leading slash which resulted in an empty path segment like http://169.254.170.2//v2/xxx. A malformed value of either variable raises ProviderException than NPE.

Fixes #1717

Summary by CodeRabbit

  • New Features

    • Expanded AWS credential support to include EKS service account roles, ECS task roles, and EKS Pod Identity.
    • Added support for container authorization tokens supplied through a file or environment variable.
    • Preserved query parameters in container credential endpoints.
  • Bug Fixes

    • Strengthened validation of credential service endpoints and accepted secure HTTPS and approved container addresses.

EKS Pod Identity Agent exposes credentials over a container credential
endpoint; it injects AWS_CONTAINER_CREDENTIALS_FULL_URI pointing to its
link-local address and passes the authorization token in a file. Two
gaps denied it.

- AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE was not read at all, hence no
  authorization token was sent. It is read now and takes precedence over
  AWS_CONTAINER_AUTHORIZATION_TOKEN as done by AWS. Trailing newline of
  the file is removed as it is denied as HTTP header value.
- The host of AWS_CONTAINER_CREDENTIALS_FULL_URI was denied unless it
  resolved to loopback addresses only. As done by AWS, the ECS and EKS
  Pod Identity link-local addresses 169.254.170.2, 169.254.170.23 and
  fd00:ec2::23 are allowed as well, and the check is skipped for HTTPS
  endpoints.

Along with it, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is parsed as URI
than added as path segments; AWS sets the value with leading slash which
resulted in an empty path segment like http://169.254.170.2//v2/xxx. A
malformed value of either variable raises ProviderException than NPE.

Fixes minio#1717

Signed-off-by: Bala.FA <bala@minio.io>
@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 2ec4d0bc-7a7a-4706-a227-75ffa2555ad1

📥 Commits

Reviewing files that changed from the base of the PR and between c9ce119 and c8c37bb.

📒 Files selected for processing (1)
  • api/src/main/java/io/minio/credentials/IamAwsProvider.java

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

IamAwsProvider now supports EKS, ECS, and EKS Pod Identity container credential endpoints. It validates endpoint hosts, reads authorization tokens from files, preserves relative-URI query parameters, and handles URI parsing errors.

Changes

AWS container credentials

Layer / File(s) Summary
Container endpoint validation
api/src/main/java/io/minio/credentials/IamAwsProvider.java
The provider defines allowed ECS and EKS container addresses. HTTP endpoints must resolve to loopback or allowed addresses. HTTPS endpoints are accepted.
Credential token and URI handling
api/src/main/java/io/minio/credentials/IamAwsProvider.java
The provider reads AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE before AWS_CONTAINER_AUTHORIZATION_TOKEN. It parses complete relative and full URIs and preserves query parameters.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Merge Risk: ⚪ Minimal · up to c8c37

The container credential changes are mergeable after normal checks.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding AWS EKS Pod Identity support to IamAwsProvider.
Linked Issues check ✅ Passed Issue #1717 requires credential retrieval through the EKS Pod Identity Agent. The reviewed IamAwsProvider reads AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE with precedence, removes trailing file whites…
Out of Scope Changes check ✅ Passed The reviewed change is limited to api/src/main/java/io/minio/credentials/IamAwsProvider.java. The host allowlist, authorization-token handling, URI parsing, HTTPS handling, and error conversion dire…
  • Fix all pre-merge checks with AI

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit reads each line,
The patch grows clear beneath the moon,
Small changes hop in place,
Tests guard the garden path,
Reviews bloom before the dawn.

Comment @coderabbitai help to get the list of available commands.

@shtripat

Copy link
Copy Markdown

None of this is covered by a test — checkContainerHost's allow-list (loopback / ECS-EKS link-local / HTTPS-bypass), the token-file-over-env precedence in containerAuthorizationToken, and the relative-URI path fix all only get exercised the next time someone hits this in prod. It's fully testable offline today: EnvironmentProvider.getProperty checks System.getProperty before the env var, and an OkHttpClient interceptor passed through the existing customHttpClient constructor param can short-circuit the real network call, so even the 169.254.170.2/.23 cases run without anything listening there.

Here's a full test file covering all four fixes — 8 of its 9 cases fail against the pre-fix code and pass on this branch:

/*
 * MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2026 MinIO, Inc.
 *
 * Licensed 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
 *
 *     https://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 io.minio.credentials;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.ProviderException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

/**
 * Covers the container-credentials paths of {@link IamAwsProvider} added for EKS Pod Identity: the
 * ECS/EKS link-local + loopback + HTTPS-bypass host check, authorization-token-file precedence, and
 * the relative-URI path building. Each test drives the class only through its public API ({@link
 * IamAwsProvider#fetch} and the constructor's {@code customHttpClient} parameter): an OkHttp
 * interceptor short-circuits the actual network call so the real link-local/loopback addresses are
 * exercised without needing anything listening on them.
 */
public class IamAwsProviderTest {
  private static final String SUCCESS_BODY =
      "{\"AccessKeyID\":\"ak\",\"SecretAccessKey\":\"sk\",\"Token\":\"tok\",\"Code\":\"Success\"}";

  private static final String[] PROPERTY_NAMES = {
    "AWS_CONTAINER_CREDENTIALS_FULL_URI",
    "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI",
    "AWS_CONTAINER_AUTHORIZATION_TOKEN",
    "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE",
    "AWS_WEB_IDENTITY_TOKEN_FILE",
  };

  @Rule public TemporaryFolder tmp = new TemporaryFolder();

  private final Map<String, String> saved = new HashMap<>();

  @After
  public void restoreProperties() {
    for (String name : PROPERTY_NAMES) {
      set(name, saved.remove(name));
    }
  }

  private void set(String name, String value) {
    if (value == null) {
      System.clearProperty(name);
    } else {
      System.setProperty(name, value);
    }
  }

  private void withProperty(String name, String value) {
    saved.putIfAbsent(name, System.getProperty(name));
    set(name, value);
  }

  /** Returns a client that never touches the network; it records the request and replies. */
  private OkHttpClient capturingClient(AtomicReference<Request> captured, String responseBody) {
    Interceptor interceptor =
        chain -> {
          captured.set(chain.request());
          return new Response.Builder()
              .request(chain.request())
              .protocol(Protocol.HTTP_1_1)
              .code(200)
              .message("OK")
              .body(ResponseBody.create(responseBody, MediaType.parse("application/json")))
              .build();
        };
    return new OkHttpClient.Builder().addInterceptor(interceptor).build();
  }

  @Test
  public void fullUriAllowsEcsLinkLocalAddressOverHttp() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://169.254.170.2/v2/credentials/abc");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    Credentials creds = provider.fetch();

    Assert.assertEquals("ak", creds.accessKey());
    Assert.assertEquals("http://169.254.170.2/v2/credentials/abc", captured.get().url().toString());
  }

  @Test
  public void fullUriAllowsEksPodIdentityLinkLocalAddressOverHttp() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://169.254.170.23/v2/credentials/abc");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    Credentials creds = provider.fetch();

    Assert.assertEquals("ak", creds.accessKey());
  }

  @Test
  public void fullUriAllowsLoopbackOverHttp() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://127.0.0.1:12345/creds");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    Credentials creds = provider.fetch();

    Assert.assertEquals("ak", creds.accessKey());
  }

  @Test
  public void fullUriRejectsPublicHostOverHttp() {
    // 203.0.113.10 is a documentation-only address (RFC 5737 TEST-NET-3): never routable, so this
    // stays offline and deterministic while standing in for an arbitrary attacker-chosen host.
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://203.0.113.10/creds");
    IamAwsProvider provider =
        new IamAwsProvider(null, capturingClient(new AtomicReference<>(), SUCCESS_BODY));

    ProviderException e = Assert.assertThrows(ProviderException.class, provider::fetch);

    Assert.assertTrue(e.getMessage().contains("neither loopback"));
  }

  @Test
  public void fullUriAllowsArbitraryHostOverHttps() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "https://arbitrary.example.invalid/creds");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    Credentials creds = provider.fetch();

    Assert.assertEquals("ak", creds.accessKey());
  }

  @Test
  public void fullUriMalformedValueThrowsProviderExceptionNotNpe() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "not a valid uri ###");
    IamAwsProvider provider =
        new IamAwsProvider(null, capturingClient(new AtomicReference<>(), SUCCESS_BODY));

    ProviderException e = Assert.assertThrows(ProviderException.class, provider::fetch);

    Assert.assertTrue(e.getMessage().contains("AWS_CONTAINER_CREDENTIALS_FULL_URI"));
  }

  @Test
  public void relativeUriBuildsSinglePathSeparator() {
    withProperty("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/v2/credentials/abc-def");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    provider.fetch();

    Assert.assertEquals(
        "http://169.254.170.2/v2/credentials/abc-def", captured.get().url().toString());
  }

  @Test
  public void authorizationTokenFileTakesPrecedenceOverEnvVar() throws Exception {
    Path tokenFile = tmp.newFile("token").toPath();
    Files.write(tokenFile, "file-token\n".getBytes(StandardCharsets.UTF_8));
    withProperty("AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE", tokenFile.toString());
    withProperty("AWS_CONTAINER_AUTHORIZATION_TOKEN", "env-token");
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://169.254.170.2/v2/credentials/abc");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    provider.fetch();

    Assert.assertEquals("file-token", captured.get().header("Authorization"));
  }

  @Test
  public void authorizationTokenFallsBackToEnvVarWhenFileUnset() {
    withProperty("AWS_CONTAINER_AUTHORIZATION_TOKEN", "env-token");
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://169.254.170.2/v2/credentials/abc");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    provider.fetch();

    Assert.assertEquals("env-token", captured.get().header("Authorization"));
  }
}

@balamurugana

Copy link
Copy Markdown
Member Author

None of this is covered by a test — checkContainerHost's allow-list (loopback / ECS-EKS link-local / HTTPS-bypass), the token-file-over-env precedence in containerAuthorizationToken, and the relative-URI path fix all only get exercised the next time someone hits this in prod. It's fully testable offline today: EnvironmentProvider.getProperty checks System.getProperty before the env var, and an OkHttpClient interceptor passed through the existing customHttpClient constructor param can short-circuit the real network call, so even the 169.254.170.2/.23 cases run without anything listening there.

Here's a full test file covering all four fixes — 8 of its 9 cases fail against the pre-fix code and pass on this branch:

/*
 * MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2026 MinIO, Inc.
 *
 * Licensed 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
 *
 *     https://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 io.minio.credentials;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.ProviderException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

/**
 * Covers the container-credentials paths of {@link IamAwsProvider} added for EKS Pod Identity: the
 * ECS/EKS link-local + loopback + HTTPS-bypass host check, authorization-token-file precedence, and
 * the relative-URI path building. Each test drives the class only through its public API ({@link
 * IamAwsProvider#fetch} and the constructor's {@code customHttpClient} parameter): an OkHttp
 * interceptor short-circuits the actual network call so the real link-local/loopback addresses are
 * exercised without needing anything listening on them.
 */
public class IamAwsProviderTest {
  private static final String SUCCESS_BODY =
      "{\"AccessKeyID\":\"ak\",\"SecretAccessKey\":\"sk\",\"Token\":\"tok\",\"Code\":\"Success\"}";

  private static final String[] PROPERTY_NAMES = {
    "AWS_CONTAINER_CREDENTIALS_FULL_URI",
    "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI",
    "AWS_CONTAINER_AUTHORIZATION_TOKEN",
    "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE",
    "AWS_WEB_IDENTITY_TOKEN_FILE",
  };

  @Rule public TemporaryFolder tmp = new TemporaryFolder();

  private final Map<String, String> saved = new HashMap<>();

  @After
  public void restoreProperties() {
    for (String name : PROPERTY_NAMES) {
      set(name, saved.remove(name));
    }
  }

  private void set(String name, String value) {
    if (value == null) {
      System.clearProperty(name);
    } else {
      System.setProperty(name, value);
    }
  }

  private void withProperty(String name, String value) {
    saved.putIfAbsent(name, System.getProperty(name));
    set(name, value);
  }

  /** Returns a client that never touches the network; it records the request and replies. */
  private OkHttpClient capturingClient(AtomicReference<Request> captured, String responseBody) {
    Interceptor interceptor =
        chain -> {
          captured.set(chain.request());
          return new Response.Builder()
              .request(chain.request())
              .protocol(Protocol.HTTP_1_1)
              .code(200)
              .message("OK")
              .body(ResponseBody.create(responseBody, MediaType.parse("application/json")))
              .build();
        };
    return new OkHttpClient.Builder().addInterceptor(interceptor).build();
  }

  @Test
  public void fullUriAllowsEcsLinkLocalAddressOverHttp() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://169.254.170.2/v2/credentials/abc");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    Credentials creds = provider.fetch();

    Assert.assertEquals("ak", creds.accessKey());
    Assert.assertEquals("http://169.254.170.2/v2/credentials/abc", captured.get().url().toString());
  }

  @Test
  public void fullUriAllowsEksPodIdentityLinkLocalAddressOverHttp() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://169.254.170.23/v2/credentials/abc");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    Credentials creds = provider.fetch();

    Assert.assertEquals("ak", creds.accessKey());
  }

  @Test
  public void fullUriAllowsLoopbackOverHttp() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://127.0.0.1:12345/creds");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    Credentials creds = provider.fetch();

    Assert.assertEquals("ak", creds.accessKey());
  }

  @Test
  public void fullUriRejectsPublicHostOverHttp() {
    // 203.0.113.10 is a documentation-only address (RFC 5737 TEST-NET-3): never routable, so this
    // stays offline and deterministic while standing in for an arbitrary attacker-chosen host.
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://203.0.113.10/creds");
    IamAwsProvider provider =
        new IamAwsProvider(null, capturingClient(new AtomicReference<>(), SUCCESS_BODY));

    ProviderException e = Assert.assertThrows(ProviderException.class, provider::fetch);

    Assert.assertTrue(e.getMessage().contains("neither loopback"));
  }

  @Test
  public void fullUriAllowsArbitraryHostOverHttps() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "https://arbitrary.example.invalid/creds");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    Credentials creds = provider.fetch();

    Assert.assertEquals("ak", creds.accessKey());
  }

  @Test
  public void fullUriMalformedValueThrowsProviderExceptionNotNpe() {
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "not a valid uri ###");
    IamAwsProvider provider =
        new IamAwsProvider(null, capturingClient(new AtomicReference<>(), SUCCESS_BODY));

    ProviderException e = Assert.assertThrows(ProviderException.class, provider::fetch);

    Assert.assertTrue(e.getMessage().contains("AWS_CONTAINER_CREDENTIALS_FULL_URI"));
  }

  @Test
  public void relativeUriBuildsSinglePathSeparator() {
    withProperty("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/v2/credentials/abc-def");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    provider.fetch();

    Assert.assertEquals(
        "http://169.254.170.2/v2/credentials/abc-def", captured.get().url().toString());
  }

  @Test
  public void authorizationTokenFileTakesPrecedenceOverEnvVar() throws Exception {
    Path tokenFile = tmp.newFile("token").toPath();
    Files.write(tokenFile, "file-token\n".getBytes(StandardCharsets.UTF_8));
    withProperty("AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE", tokenFile.toString());
    withProperty("AWS_CONTAINER_AUTHORIZATION_TOKEN", "env-token");
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://169.254.170.2/v2/credentials/abc");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    provider.fetch();

    Assert.assertEquals("file-token", captured.get().header("Authorization"));
  }

  @Test
  public void authorizationTokenFallsBackToEnvVarWhenFileUnset() {
    withProperty("AWS_CONTAINER_AUTHORIZATION_TOKEN", "env-token");
    withProperty("AWS_CONTAINER_CREDENTIALS_FULL_URI", "http://169.254.170.2/v2/credentials/abc");
    AtomicReference<Request> captured = new AtomicReference<>();
    IamAwsProvider provider = new IamAwsProvider(null, capturingClient(captured, SUCCESS_BODY));

    provider.fetch();

    Assert.assertEquals("env-token", captured.get().header("Authorization"));
  }
}

These tests do not give values in real world. As it works only inside AWS environment, it is hard to guarantee by unit tests.

@balamurugana
balamurugana merged commit 212ebf8 into minio:master Sep 16, 2026
13 checks passed
@balamurugana
balamurugana deleted the fix-issue-1717 branch September 16, 2026 08:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support AWS EKS Pod Identity (AssumeRoleForPodIdentity)

2 participants