mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-09-04 06:15:07 +09:00
fix: honor configured STS endpoint for "ambient" credentials
Ambient credential resolution built a bare STS client, so a web-identity token found by the SDK default chain (e.g. AWS_WEB_IDENTITY_TOKEN_FILE on a self-hosted runner) was exchanged with public STS instead of any operator-configured sts-endpoint. Resolution now passes the configured region, endpoint, and proxy handler to the default provider chain.
This commit is contained in:
Generated
+1
@@ -11,6 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^3.0.1",
|
"@actions/core": "^3.0.1",
|
||||||
"@aws-sdk/client-sts": "^3.1116.0",
|
"@aws-sdk/client-sts": "^3.1116.0",
|
||||||
|
"@aws-sdk/credential-provider-node": "^3.972.63",
|
||||||
"@smithy/node-http-handler": "^4.11.3",
|
"@smithy/node-http-handler": "^4.11.3",
|
||||||
"proxy-agent": "^8.0.2"
|
"proxy-agent": "^8.0.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^3.0.1",
|
"@actions/core": "^3.0.1",
|
||||||
"@aws-sdk/client-sts": "^3.1116.0",
|
"@aws-sdk/client-sts": "^3.1116.0",
|
||||||
|
"@aws-sdk/credential-provider-node": "^3.972.63",
|
||||||
"@smithy/node-http-handler": "^4.11.3",
|
"@smithy/node-http-handler": "^4.11.3",
|
||||||
"proxy-agent": "^8.0.2"
|
"proxy-agent": "^8.0.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { info } from '@actions/core';
|
import { info } from '@actions/core';
|
||||||
import { STSClient } from '@aws-sdk/client-sts';
|
import { STSClient } from '@aws-sdk/client-sts';
|
||||||
|
import { defaultProvider } from '@aws-sdk/credential-provider-node';
|
||||||
import type { AwsCredentialIdentity } from '@aws-sdk/types';
|
import type { AwsCredentialIdentity } from '@aws-sdk/types';
|
||||||
import { NodeHttpHandler } from '@smithy/node-http-handler';
|
import { NodeHttpHandler } from '@smithy/node-http-handler';
|
||||||
import { ProxyAgent } from 'proxy-agent';
|
import { ProxyAgent } from 'proxy-agent';
|
||||||
@@ -105,9 +106,15 @@ export class CredentialsClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async loadCredentials() {
|
private async loadCredentials() {
|
||||||
const config = {} as { requestHandler?: NodeHttpHandler };
|
// Previously we constructed a new client, but that picks up the default provider chain including the endpoint.
|
||||||
if (this.requestHandler !== undefined) config.requestHandler = this.requestHandler;
|
// Explicitly calling the default provider chain allows us to pass in the endpoint and region as well as the
|
||||||
const client = new STSClient(config);
|
// proxy config.
|
||||||
return client.config.credentials();
|
return defaultProvider({
|
||||||
|
clientConfig: {
|
||||||
|
...(this.region !== undefined && { region: this.region }),
|
||||||
|
...(this.stsEndpoint !== undefined && { endpoint: this.stsEndpoint }),
|
||||||
|
...(this.requestHandler !== undefined && { requestHandler: this.requestHandler }),
|
||||||
|
},
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
|
vi.mock('@aws-sdk/credential-provider-node', () => ({
|
||||||
|
defaultProvider: vi.fn(() => async () => ({ accessKeyId: 'AKIA', secretAccessKey: 'secret' })),
|
||||||
|
}));
|
||||||
|
|
||||||
|
import { defaultProvider } from '@aws-sdk/credential-provider-node';
|
||||||
|
import { CredentialsClient } from '../src/CredentialsClient';
|
||||||
|
|
||||||
|
describe('CredentialsClient', {}, () => {
|
||||||
|
it('pins ambient credential resolution to the configured region and STS endpoint', {}, async () => {
|
||||||
|
const client = new CredentialsClient({
|
||||||
|
region: 'eu-west-1',
|
||||||
|
stsEndpoint: 'https://sts.example.com',
|
||||||
|
roleChaining: false,
|
||||||
|
});
|
||||||
|
// biome-ignore lint/suspicious/noExplicitAny: any required to call private method
|
||||||
|
await (client as any).loadCredentials();
|
||||||
|
expect(defaultProvider).toHaveBeenCalledWith({
|
||||||
|
clientConfig: expect.objectContaining({ region: 'eu-west-1', endpoint: 'https://sts.example.com' }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('omits unset client config values from ambient credential resolution', {}, async () => {
|
||||||
|
const client = new CredentialsClient({ region: 'eu-west-1', roleChaining: false });
|
||||||
|
// biome-ignore lint/suspicious/noExplicitAny: any required to call private method
|
||||||
|
await (client as any).loadCredentials();
|
||||||
|
expect(defaultProvider).toHaveBeenLastCalledWith({ clientConfig: { region: 'eu-west-1' } });
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user