diff --git a/action.yml b/action.yml index fba8ae1..318c99d 100644 --- a/action.yml +++ b/action.yml @@ -96,7 +96,7 @@ inputs: description: An option comma-delimited list of expected AWS account IDs. The action will fail if we receive credentials for the wrong account. force-skip-oidc: required: false - description: When enabled, this option will skip using GitHub OIDC provider even if the id-token permission is set. This is sometimes useful when using IAM instance credentials, or when running on a self-hosted runner with container-sourced credentials. + description: When enabled, this option will skip using GitHub OIDC provider even if the id-token permission is set. This is sometimes useful when using IAM instance credentials. action-timeout-s: required: false description: A global timeout in seconds for the action. When the timeout is reached, the action immediately exits. The default is to run without a timeout. diff --git a/src/index.ts b/src/index.ts index 00b91ef..2153a32 100644 --- a/src/index.ts +++ b/src/index.ts @@ -77,22 +77,12 @@ export async function run() { }, globalTimeout * 1000); } - // Container-sourced credentials are exposed by the AWS SDK default chain via these env vars. They count as a valid - // non-OIDC source for the force-skip-oidc guard. - const hasContainerCredentials = !!( - process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI || process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI - ); - - if (forceSkipOidc && roleToAssume && !AccessKeyId && !webIdentityTokenFile && !hasContainerCredentials) { + if (forceSkipOidc && roleToAssume && !AccessKeyId && !webIdentityTokenFile) { throw new Error( - "If 'force-skip-oidc' is true and 'role-to-assume' is set, 'aws-access-key-id', 'web-identity-token-file', or container credentials must be available", + "If 'force-skip-oidc' is true and 'role-to-assume' is set, 'aws-access-key-id' or 'web-identity-token-file' must be set", ); } - if (forceSkipOidc && hasContainerCredentials && !AccessKeyId && !webIdentityTokenFile) { - core.info('Using container credentials from AWS_CONTAINER_CREDENTIALS_* environment variables'); - } - if (specialCharacterWorkaround) { // 😳 disableRetry = false; diff --git a/test/index.test.ts b/test/index.test.ts index 8ebe526..93f6abe 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -743,70 +743,7 @@ describe('Configure AWS Credentials', {}, () => { await run(); expect(core.setFailed).toHaveBeenCalledWith( - "If 'force-skip-oidc' is true and 'role-to-assume' is set, 'aws-access-key-id', 'web-identity-token-file', or container credentials must be available", - ); - }); - - it('uses container credentials with force-skip-oidc and role-to-assume (CodeBuild/ECS runner, #1546)', async () => { - vi.mocked(core.getInput).mockImplementation( - mocks.getInput({ - 'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE', - 'aws-region': 'fake-region-1', - 'force-skip-oidc': 'true', - }), - ); - vi.mocked(core.getIDToken).mockResolvedValue('testoidctoken'); - mockedSTSClient.on(AssumeRoleCommand).resolves(mocks.outputs.STS_CREDENTIALS); - mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY }); - // Simulate the container-metadata creds the SDK would pull from 169.254.170.2. - // biome-ignore lint/suspicious/noExplicitAny: any required to mock private method - vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({ - accessKeyId: 'CONTAINERAWSACCESSKEYID', - }); - process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'fake-token'; - process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI = '/v2/credentials/abc-123'; - - await run(); - expect(core.getIDToken).not.toHaveBeenCalled(); - expect(core.info).toHaveBeenCalledWith( - 'Using container credentials from AWS_CONTAINER_CREDENTIALS_* environment variables', - ); - expect(core.info).toHaveBeenCalledWith('Assuming role with user credentials'); - expect(core.setFailed).not.toHaveBeenCalled(); - }); - - it('uses container credentials via AWS_CONTAINER_CREDENTIALS_FULL_URI', async () => { - vi.mocked(core.getInput).mockImplementation( - mocks.getInput({ - 'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE', - 'aws-region': 'fake-region-1', - 'force-skip-oidc': 'true', - }), - ); - mockedSTSClient.on(AssumeRoleCommand).resolves(mocks.outputs.STS_CREDENTIALS); - mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY }); - // biome-ignore lint/suspicious/noExplicitAny: any required to mock private method - vi.spyOn(CredentialsClient.prototype as any, 'loadCredentials').mockResolvedValue({ - accessKeyId: 'CONTAINERAWSACCESSKEYID', - }); - process.env.AWS_CONTAINER_CREDENTIALS_FULL_URI = 'http://169.254.170.23/credentials'; - - await run(); - expect(core.setFailed).not.toHaveBeenCalled(); - }); - - it('still errors when container env vars are absent and no other creds are provided', async () => { - vi.mocked(core.getInput).mockImplementation( - mocks.getInput({ - 'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE', - 'aws-region': 'fake-region-1', - 'force-skip-oidc': 'true', - }), - ); - // Neither AWS_CONTAINER_CREDENTIALS_RELATIVE_URI nor _FULL_URI is set (mocks.envs has neither). - await run(); - expect(core.setFailed).toHaveBeenCalledWith( - expect.stringContaining("'aws-access-key-id', 'web-identity-token-file', or container credentials"), + "If 'force-skip-oidc' is true and 'role-to-assume' is set, 'aws-access-key-id' or 'web-identity-token-file' must be set", ); });