Skip to content
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 @@ -37,6 +37,10 @@
* <p>The command string is captured at assembly time and does not change after construction.
* Each call to {@code resolveIdentity()} re-executes the process to obtain fresh credentials,
* so expiring credentials returned by the process are naturally refreshed without caching.
*
* <p>This provider registers terminally: once a profile declares {@code credential_process}, the chain commits
* to it, and a process failure is returned as an error rather than falling through to a lower-priority provider
* (per the Extensible Credentials SEP).
*/
public final class CredentialProcessHandler implements ChainIdentityProvider {

Expand Down Expand Up @@ -76,7 +80,7 @@ public void setup(Class<? extends Identity> identityType, ChainSetup setup) {
}
for (AwsConfigCredentialSource source : profile.credentialSources()) {
if (source instanceof AwsConfigCredentialSource.CredentialProcess(String commandLine)) {
setup.addResolver(new Resolver(commandLine));
setup.addTerminalResolver(new Resolver(commandLine));
return;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.java.aws.credentials.chain;

import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import software.amazon.smithy.java.aws.auth.api.identity.AwsCredentialsIdentity;
import software.amazon.smithy.java.aws.config.AwsProfileFile;
import software.amazon.smithy.java.aws.credentials.chain.config.CredentialProcessHandler;

class CredentialProcessTerminalTest {
@Test
void claimsTerminalWhenProfileDeclaresCredentialProcess(@TempDir Path tmp) throws IOException {
Path config = tmp.resolve("config");
Files.writeString(config, "[default]\ncredential_process = /usr/local/bin/awscreds\n");
var file = AwsProfileFile.builder().configFile(config).credentialsFile(null).build();

var setup = ChainSetup.builder().build();
setup.setProfileFile(file);
setup.setProfile(file.activeProfile(k -> null));

var handler = new CredentialProcessHandler();
setup.setCurrentProvider(handler);
handler.setup(AwsCredentialsIdentity.class, setup);

assertTrue(setup.isTerminal(),
"A profile declaring credential_process must claim the chain terminally so a process failure "
+ "stops resolution instead of falling through to a lower-priority provider.");
}
}
Loading