mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-03-12 18:07:10 -04:00
V3 (#791)
* feat!: v3 release Squashed commit of the following: commit9df144b3aeMerge:19d3f3a131c7b6Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Aug 23 14:41:33 2023 -0700 Merge remote-tracking branch 'origin' into vNext commit131c7b6fd1Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 22 03:12:24 2023 +0000 chore: Bump jest from 29.6.2 to 29.6.3 (#786) Bumps [jest](https://github.com/jestjs/jest/tree/HEAD/packages/jest) from 29.6.2 to 29.6.3. - [Release notes](https://github.com/jestjs/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jestjs/jest/commits/v29.6.3/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit6334b403ebAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 22 03:11:45 2023 +0000 chore: Bump aws-sdk from 2.1436.0 to 2.1441.0 (#787) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1436.0 to 2.1441.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1436.0...v2.1441.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit19d3f3a169Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 18 20:13:39 2023 -0700 chore: update readme and changelog commit4403e8d882Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 18 17:12:47 2023 -0700 chore: update workflows commit0f1923f1a1Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 18 17:01:59 2023 -0700 chore: update .github with current commit60a9bf1676Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 18 17:00:14 2023 -0700 chore: update .github with current commitd3464b25f8Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 18 16:58:01 2023 -0700 chore: add examples to vNext branch commit7cd050ca4dAuthor: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 18 16:54:12 2023 -0700 chore: update readme commit0e32a13775Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 18 16:19:17 2023 -0700 chore: update readme commit2625b45d56Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 18 15:12:36 2023 -0700 chore: update readme commit19eb4df27eAuthor: peterwoodworth <woodwoop@amazon.com> Date: Thu Aug 17 17:22:20 2023 -0700 chore: update readme commit71ff793a0fAuthor: peterwoodworth <woodwoop@amazon.com> Date: Thu Aug 17 17:18:42 2023 -0700 chore: update readme commita272f95336Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Aug 16 17:05:42 2023 -0700 chore: update readme commit360ea313a7Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 15 03:33:37 2023 +0000 chore: Bump aws-sdk from 2.1431.0 to 2.1436.0 (#783) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1431.0 to 2.1436.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1431.0...v2.1436.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commitde93b00c9fAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 15 03:32:58 2023 +0000 chore: Bump eslint from 8.46.0 to 8.47.0 (#784) Bumps [eslint](https://github.com/eslint/eslint) from 8.46.0 to 8.47.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.46.0...v8.47.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit4dd1aeed85Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 11 16:41:44 2023 -0700 chore: remove unused dependency, fixing vulnerability commit7f4507af3cAuthor: peterwoodworth <woodwoop@amazon.com> Date: Fri Aug 11 16:24:09 2023 -0700 fix: maxRetry hit infinite loop with negative input commit746d33e7c1Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 8 03:23:17 2023 +0000 chore: Bump aws-sdk from 2.1426.0 to 2.1431.0 (#782) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1426.0 to 2.1431.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1426.0...v2.1431.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit706fc9ae3dAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 1 03:41:00 2023 +0000 chore: Bump eslint from 8.45.0 to 8.46.0 (#780) Bumps [eslint](https://github.com/eslint/eslint) from 8.45.0 to 8.46.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.45.0...v8.46.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit9918371ad5Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 1 03:39:16 2023 +0000 chore: Bump aws-sdk from 2.1421.0 to 2.1426.0 (#781) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1421.0 to 2.1426.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1421.0...v2.1426.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit345462ab9eAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Aug 1 03:38:28 2023 +0000 chore: Bump jest from 29.6.1 to 29.6.2 (#779) Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) from 29.6.1 to 29.6.2. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/commits/v29.6.2/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit80a7a6c2a2Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jul 25 03:22:02 2023 +0000 chore: Bump aws-sdk from 2.1416.0 to 2.1421.0 (#778) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1416.0 to 2.1421.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1416.0...v2.1421.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit385d7e1d64Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jul 18 03:25:33 2023 +0000 chore: Bump aws-sdk from 2.1413.0 to 2.1416.0 (#774) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1413.0 to 2.1416.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1413.0...v2.1416.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit48560b5d49Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jul 18 03:24:46 2023 +0000 chore: Bump eslint from 8.44.0 to 8.45.0 (#773) Bumps [eslint](https://github.com/eslint/eslint) from 8.44.0 to 8.45.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.44.0...v8.45.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit35d8f9588bAuthor: Shailja Khurana <117320115+khushail@users.noreply.github.com> Date: Fri Jul 14 15:14:02 2023 -0700 added workflow for handling answerable discussions (#772) commit86df881b31Author: Tom Keller <1083460+kellertk@users.noreply.github.com> Date: Wed Jul 12 14:51:43 2023 -0700 chore: add link to CF template in README (#771) commita621db3279Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jul 11 03:16:22 2023 +0000 chore: Bump jest from 29.5.0 to 29.6.1 (#768) Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) from 29.5.0 to 29.6.1. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/commits/v29.6.1/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit90858a2e70Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jul 11 03:15:36 2023 +0000 chore: Bump aws-sdk from 2.1410.0 to 2.1413.0 (#767) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1410.0 to 2.1413.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1410.0...v2.1413.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit228a9916eeAuthor: Tom Keller <1083460+kellertk@users.noreply.github.com> Date: Fri Jul 7 16:49:10 2023 -0700 Update README.md for OIDC changes (#764) commit65c2143642Author: peterwoodworth <woodwoop@amazon.com> Date: Thu Jul 6 15:19:05 2023 -0700 chore: add final tests, add outputs to action.yml commit7b893ba14bAuthor: peterwoodworth <woodwoop@amazon.com> Date: Wed Jul 5 18:55:04 2023 -0700 feat: getIDToken retry, feat: special character in key retry commit3c981da079Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jul 4 03:30:19 2023 +0000 chore: Bump eslint from 8.43.0 to 8.44.0 (#761) Bumps [eslint](https://github.com/eslint/eslint) from 8.43.0 to 8.44.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.43.0...v8.44.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit222080786bAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jul 4 03:29:03 2023 +0000 chore: Bump aws-sdk from 2.1405.0 to 2.1410.0 (#760) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1405.0 to 2.1410.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1405.0...v2.1410.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commitaa2675f083Author: peterwoodworth <woodwoop@amazon.com> Date: Mon Jul 3 16:13:19 2023 -0700 implement last changes for vNext commit256d740e71Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Jun 30 16:20:47 2023 -0700 chore: remove unnecessary step in unit test job commitcd5cd29d7fAuthor: peterwoodworth <woodwoop@amazon.com> Date: Fri Jun 30 16:17:47 2023 -0700 chore: declare eol in gitattributes commit7b90497500Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Jun 30 16:11:12 2023 -0700 chore: disable auto crlf in unit tests commitfb67439785Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Jun 30 15:48:15 2023 -0700 fix boolean input commit2b32a8f2c6Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Jun 30 15:40:41 2023 -0700 fix webIdentityTokenFile option, rearrange validation logic commit7526948ef9Author: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Thu Jun 29 17:29:11 2023 -0700 chore: vnext unit tests (#758) * fix: unit tests * get unit tests running commit0270d0bcecAuthor: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Tue Jun 27 14:22:02 2023 -0700 chore: update readme with new thumbprint (#755) commit4b8efb08dbAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jun 27 03:58:21 2023 +0000 chore: Bump aws-sdk from 2.1400.0 to 2.1405.0 (#754) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1400.0 to 2.1405.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1400.0...v2.1405.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commitd26f2d03f8Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Jun 21 16:45:34 2023 -0700 feat: role-chaining commit20f59875feAuthor: peterwoodworth <woodwoop@amazon.com> Date: Wed Jun 21 15:13:42 2023 -0700 feat: optional policy inputs when assuming role commit10024331f6Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Jun 21 15:08:37 2023 -0700 feat: optional policy inputs when assuming role commit2cee35f9a9Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Jun 21 14:51:50 2023 -0700 feat: optional policy inputs when assuming role commit8aa25a5cb6Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Jun 21 14:50:04 2023 -0700 feat: optional policy inputs when assuming role commite849bae717Author: peterwoodworth <woodwoop@amazon.com> Date: Tue Jun 20 18:02:34 2023 -0700 chore: remove windows self-hosted runner commit8a5ae330ddAuthor: peterwoodworth <woodwoop@amazon.com> Date: Tue Jun 20 16:10:30 2023 -0700 chore: expand integ tests commit819a6d1c74Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jun 20 03:58:58 2023 +0000 chore: Bump eslint from 8.42.0 to 8.43.0 (#750) Bumps [eslint](https://github.com/eslint/eslint) from 8.42.0 to 8.43.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.42.0...v8.43.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commite57babb541Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jun 20 03:58:19 2023 +0000 chore: Bump aws-sdk from 2.1396.0 to 2.1400.0 (#749) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1396.0 to 2.1400.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1396.0...v2.1400.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commitc613996f9aAuthor: peterwoodworth <woodwoop@amazon.com> Date: Mon Jun 19 18:38:44 2023 -0700 chore: attempting to get to minimal integ test success commitc13a9c8ef3Author: peterwoodworth <woodwoop@amazon.com> Date: Mon Jun 19 18:36:40 2023 -0700 chore: attempting to get to minimal integ test success commitb98e10c776Author: peterwoodworth <woodwoop@amazon.com> Date: Mon Jun 19 18:25:03 2023 -0700 chore: set failing configuration on integ workflow matrix commit6d193465aeAuthor: peterwoodworth <woodwoop@amazon.com> Date: Mon Jun 19 16:32:19 2023 -0700 chore: remove push workflow trigger commita8f18666dbAuthor: peterwoodworth <woodwoop@amazon.com> Date: Mon Jun 19 16:29:33 2023 -0700 chore: fix workflow file indentation commit7dec5a88ceAuthor: peterwoodworth <woodwoop@amazon.com> Date: Mon Jun 19 16:28:05 2023 -0700 chore: update workflow to be able to trigger commit0a8178a52aAuthor: peterwoodworth <woodwoop@amazon.com> Date: Mon Jun 19 16:21:45 2023 -0700 chore: update workflow to be able to trigger commit506b27277dAuthor: peterwoodworth <woodwoop@amazon.com> Date: Mon Jun 19 16:17:53 2023 -0700 chore: update workflow to be able to trigger commit5fd3084fc3Author: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Wed Jun 14 15:02:32 2023 -0700 chore: update changelog for release (#745) commitd00f6c6f41Author: Dimitar <dimitarshr@gmail.com> Date: Wed Jun 14 22:43:04 2023 +0100 Allow inline session policies for assuming role (#739) * Allow to pass inline session policy as a parameter Update the action file Regenerate the dist/ content Add test * Fix typos * Fix stylistic error * Move the inline policy logic to allow assumeRole to use it as well; Update and add tests * Add an option for managed policies * Regenerate the dist/ files * Use multiline input for managed policies * Update readme * Update readme --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commitae734070a0Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Jun 13 04:55:26 2023 +0000 chore: Update dist commit3d528c5f7dAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jun 13 04:54:37 2023 +0000 chore: Bump aws-sdk from 2.1391.0 to 2.1396.0 (#744) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1391.0 to 2.1396.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1391.0...v2.1396.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commite7aae61719Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Jun 6 03:59:43 2023 +0000 chore: Update dist commit979ee1f6f4Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jun 6 03:59:04 2023 +0000 chore: Bump aws-sdk from 2.1386.0 to 2.1391.0 (#742) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1386.0 to 2.1391.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1386.0...v2.1391.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit184acc09eaAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jun 6 03:58:21 2023 +0000 chore: Bump eslint from 8.41.0 to 8.42.0 (#741) Bumps [eslint](https://github.com/eslint/eslint) from 8.41.0 to 8.42.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.41.0...v8.42.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit375a690dc0Author: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Wed May 31 14:43:39 2023 -0700 chore: update changelog for v2.1.0 (#738) * chore: update changelog for v2.1.0 * chore: update changelog for v2.1.0 --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit8337ca3433Author: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Wed May 31 14:38:06 2023 -0700 update time to ancient (#729) Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit5727f247b6Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue May 30 03:59:04 2023 +0000 chore: Update dist commitde3676366fAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue May 30 03:58:14 2023 +0000 chore: Bump aws-sdk from 2.1382.0 to 2.1386.0 (#736) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1382.0 to 2.1386.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1382.0...v2.1386.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit81fba9ea6aAuthor: escudero89 <532828+escudero89@users.noreply.github.com> Date: Fri May 26 00:10:40 2023 +0200 Update README.md with v2 instead of v1 (#733) commit8815b6557cAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue May 23 03:59:25 2023 +0000 chore: Bump eslint from 8.40.0 to 8.41.0 (#732) Bumps [eslint](https://github.com/eslint/eslint) from 8.40.0 to 8.41.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.40.0...v8.41.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit3d77523f10Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue May 23 03:58:44 2023 +0000 chore: Update dist commit4eb7afece4Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue May 23 03:58:06 2023 +0000 chore: Bump aws-sdk from 2.1378.0 to 2.1382.0 (#731) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1378.0 to 2.1382.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1378.0...v2.1382.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commitd713a182c5Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue May 16 03:58:29 2023 +0000 chore: Update dist commit1910078421Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue May 16 03:57:45 2023 +0000 chore: Bump aws-sdk from 2.1374.0 to 2.1378.0 (#726) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1374.0 to 2.1378.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1374.0...v2.1378.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit580afbba80Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue May 9 03:59:53 2023 +0000 chore: Update dist commit1daf2a1967Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue May 9 03:59:14 2023 +0000 chore: Bump aws-sdk from 2.1369.0 to 2.1374.0 (#723) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1369.0 to 2.1374.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1369.0...v2.1374.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit76ad093bd5Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue May 9 03:57:57 2023 +0000 chore: Bump eslint from 8.39.0 to 8.40.0 (#722) Bumps [eslint](https://github.com/eslint/eslint) from 8.39.0 to 8.40.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.39.0...v8.40.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit6fbd316fd1Author: Milo Hyson <siggimoo@users.noreply.github.com> Date: Fri May 5 18:27:52 2023 -0700 Add role-chaining support (#688) * Add role-chaining support * fix version in readme * minor readme adjustment --------- Co-authored-by: Milo Hyson <mhyson@tunein.com> Co-authored-by: peterwoodworth <woodwoop@amazon.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit19f3a6d67fAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue May 2 03:59:57 2023 +0000 chore: Bump axios from 1.3.6 to 1.4.0 (#720) Bumps [axios](https://github.com/axios/axios) from 1.3.6 to 1.4.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.3.6...v1.4.0) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit96aac45bfcAuthor: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue May 2 03:58:25 2023 +0000 chore: Update dist commit5e6a264592Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue May 2 03:57:46 2023 +0000 chore: Bump aws-sdk from 2.1364.0 to 2.1369.0 (#719) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1364.0 to 2.1369.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1364.0...v2.1369.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit82ea2d2853Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Apr 25 04:01:50 2023 +0000 chore: Bump axios from 1.3.5 to 1.3.6 (#716) Bumps [axios](https://github.com/axios/axios) from 1.3.5 to 1.3.6. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.3.5...v1.3.6) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commite0213bba7aAuthor: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Apr 25 03:59:31 2023 +0000 chore: Update dist commit2beda2fb7cAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Apr 25 03:58:42 2023 +0000 chore: Bump aws-sdk from 2.1360.0 to 2.1364.0 (#715) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1360.0 to 2.1364.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1360.0...v2.1364.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit0afc5d47c7Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Apr 25 03:57:35 2023 +0000 chore: Bump eslint from 8.38.0 to 8.39.0 (#714) Bumps [eslint](https://github.com/eslint/eslint) from 8.38.0 to 8.39.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.38.0...v8.39.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit31bd3ae2dbAuthor: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Apr 18 03:59:23 2023 +0000 chore: Update dist commit46648cb772Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Apr 18 03:58:27 2023 +0000 chore: Bump aws-sdk from 2.1354.0 to 2.1360.0 (#713) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1354.0 to 2.1360.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1354.0...v2.1360.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit60a5c129d0Author: Jonathan Lang <jonathan.lang@tngtech.com> Date: Wed Apr 12 00:46:13 2023 +0200 Fix Typo in README.md (#707) commitf576cc9d9bAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Apr 11 04:00:40 2023 +0000 chore: Bump axios from 1.3.4 to 1.3.5 (#712) Bumps [axios](https://github.com/axios/axios) from 1.3.4 to 1.3.5. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.3.4...v1.3.5) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit9c17403327Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Apr 11 03:59:38 2023 +0000 chore: Bump eslint from 8.35.0 to 8.38.0 (#711) Bumps [eslint](https://github.com/eslint/eslint) from 8.35.0 to 8.38.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.35.0...v8.38.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit9c1a10e79cAuthor: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Apr 11 03:58:34 2023 +0000 chore: Update dist commit9192d9ecb4Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Apr 11 03:57:48 2023 +0000 chore: Bump aws-sdk from 2.1329.0 to 2.1354.0 (#710) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1329.0 to 2.1354.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1329.0...v2.1354.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit26227bfa7dAuthor: peterwoodworth <woodwoop@amazon.com> Date: Wed Mar 22 16:52:04 2023 -0700 chore: adjust cleanup build target commit0d90ddd1f2Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Mar 22 16:51:12 2023 -0700 chore: adjust cleanup build again commitfc80f28dbaAuthor: peterwoodworth <woodwoop@amazon.com> Date: Wed Mar 22 16:37:58 2023 -0700 chore: adjust cleanup build and some imports commit3088522ce8Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Mar 22 16:32:37 2023 -0700 chore: build and set cleanup file commit0181111f1dAuthor: peterwoodworth <woodwoop@amazon.com> Date: Wed Mar 22 15:12:07 2023 -0700 chore: build action commitb723544115Author: peterwoodworth <woodwoop@amazon.com> Date: Wed Mar 22 15:08:39 2023 -0700 fix: branch name is not sanitized, slight refactor commit0e613a0980Author: Adrian Środoń <adriansrodon@tuta.io> Date: Mon Mar 20 23:24:34 2023 +0100 docs: add note about case sensivity to CloudFormation template (#696) * docs: add note about case sensivity to CloudFormation template * Move case-sensivity notes to CloudFormation template commit12d07d4800Author: Tom Keller <kellertk@amazon.com> Date: Fri Mar 17 17:46:57 2023 -0700 feat: update tests commitf6fdf0cdbdAuthor: peterwoodworth <woodwoop@amazon.com> Date: Wed Mar 15 14:12:01 2023 -0700 feat: aws region is optional, use global sts endpoint when not set commitcb1361ade3Author: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Mon Mar 13 14:50:02 2023 -0700 docs: clarify safety of version migration in readme (#692) commitf9f25e69f5Author: peterwoodworth <woodwoop@amazon.com> Date: Fri Mar 10 14:35:59 2023 -0800 refactor, add new major version features and proxy commit83f0e97b2fMerge:7fc5f08f86a0c3Author: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Tue Mar 7 17:36:19 2023 -0800 Merge pull request #687 from fabienfoerster/patch-2 Update README examples to use v2 commitf86a0c30a5Author: Fabien Foerster <f.foerster@bevolta.com> Date: Tue Mar 7 21:29:17 2023 +0100 Update README examples to use v2 commit7fc5f080e5Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Mar 7 01:02:37 2023 +0000 chore: Update dist commitffc08eae73Author: Tom Keller <kellertk@amazon.com> Date: Mon Mar 6 17:01:09 2023 -0800 Rename master to main commite1e17a757eAuthor: Tom Keller <1083460+kellertk@users.noreply.github.com> Date: Mon Mar 6 16:35:37 2023 -0800 Version 2 release (#685) * Update README for v2 * Remove codeql analysis * Version bump checkout action * Tweak closed issue message * Changes for v2 release * Adjust action name * Update CHANGELOG * Update action to use node 16 * Update versions * Typo commitbab55d3830Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Feb 28 04:09:09 2023 +0000 chore: Bump axios from 1.3.3 to 1.3.4 (#679) Bumps [axios](https://github.com/axios/axios) from 1.3.3 to 1.3.4. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.3.3...v1.3.4) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit07b737a14fAuthor: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Feb 28 04:00:33 2023 +0000 chore: Update dist commit26e4efa71fAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Feb 28 03:59:47 2023 +0000 chore: Bump aws-sdk from 2.1320.0 to 2.1324.0 (#677) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1320.0 to 2.1324.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1320.0...v2.1324.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit7e0ecf0346Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Feb 28 03:58:55 2023 +0000 chore: Bump eslint from 8.34.0 to 8.35.0 (#675) Bumps [eslint](https://github.com/eslint/eslint) from 8.34.0 to 8.35.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.34.0...v8.35.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit567d4149d6Merge:32eb1b485ec61bAuthor: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Tue Feb 21 18:49:30 2023 -0800 Merge pull request #563 from russau/docs/readme-role-update Minor: include a role condition test for AUD in sample CFN template commit32eb1b4a66Author: Jackson Welsh <me@jacksonwel.sh> Date: Tue Feb 21 20:36:17 2023 -0600 feat: document mask-aws-account-id input (#606) Closes aws-actions#304 Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit6ca2577643Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Wed Feb 22 02:34:29 2023 +0000 chore: Update dist commitf1de076135Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed Feb 22 02:33:40 2023 +0000 chore: Bump aws-sdk from 2.1273.0 to 2.1320.0 (#666) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1273.0 to 2.1320.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1273.0...v2.1320.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit077fd1fc8fAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Feb 21 04:00:04 2023 +0000 chore: Bump jest from 29.4.2 to 29.4.3 (#663) Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) from 29.4.2 to 29.4.3. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/commits/v29.4.3/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit1416c559c0Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Feb 14 04:08:31 2023 +0000 chore: Bump eslint from 8.33.0 to 8.34.0 (#653) Bumps [eslint](https://github.com/eslint/eslint) from 8.33.0 to 8.34.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.33.0...v8.34.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commitc3f9f9cde3Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Feb 14 04:02:34 2023 +0000 chore: Bump jest from 29.4.1 to 29.4.2 (#655) Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) from 29.4.1 to 29.4.2. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/commits/v29.4.2/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit1a61b71d4cAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Feb 14 04:00:54 2023 +0000 chore: Bump axios from 1.3.2 to 1.3.3 (#651) Bumps [axios](https://github.com/axios/axios) from 1.3.2 to 1.3.3. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.3.2...v1.3.3) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit07d5781915Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Feb 7 03:03:40 2023 +0000 chore: Bump axios from 1.2.6 to 1.3.2 (#648) Bumps [axios](https://github.com/axios/axios) from 1.2.6 to 1.3.2. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.2.6...v1.3.2) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit5ed46d9d6aAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 31 03:10:42 2023 +0000 chore: Bump eslint from 8.32.0 to 8.33.0 (#645) Bumps [eslint](https://github.com/eslint/eslint) from 8.32.0 to 8.33.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.32.0...v8.33.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit0d34112acbAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 31 03:06:27 2023 +0000 chore: Bump jest from 29.3.1 to 29.4.1 (#643) Bumps [jest](https://github.com/facebook/jest/tree/HEAD/packages/jest) from 29.3.1 to 29.4.1. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/facebook/jest/commits/v29.4.1/packages/jest) --- updated-dependencies: - dependency-name: jest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commitfa45146389Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 31 03:05:11 2023 +0000 chore: Bump @vercel/ncc from 0.36.0 to 0.36.1 (#640) Bumps [@vercel/ncc](https://github.com/vercel/ncc) from 0.36.0 to 0.36.1. - [Release notes](https://github.com/vercel/ncc/releases) - [Commits](https://github.com/vercel/ncc/compare/0.36.0...0.36.1) --- updated-dependencies: - dependency-name: "@vercel/ncc" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commita075dc0410Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 31 03:03:44 2023 +0000 chore: Bump axios from 1.2.3 to 1.2.6 (#639) Bumps [axios](https://github.com/axios/axios) from 1.2.3 to 1.2.6. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.2.3...v1.2.6) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit3e21ee4ae7Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 24 03:04:28 2023 +0000 chore: Bump axios from 1.2.2 to 1.2.3 (#630) Bumps [axios](https://github.com/axios/axios) from 1.2.2 to 1.2.3. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/1.2.2...v1.2.3) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit491cd39cf6Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 17 03:05:35 2023 +0000 chore: Bump eslint from 8.31.0 to 8.32.0 (#625) Bumps [eslint](https://github.com/eslint/eslint) from 8.31.0 to 8.32.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.31.0...v8.32.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit3654529dc6Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 3 03:06:41 2023 +0000 chore: Bump json5 from 2.2.1 to 2.2.3 (#620) Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3. - [Release notes](https://github.com/json5/json5/releases) - [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md) - [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3) --- updated-dependencies: - dependency-name: json5 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commitaa5a031041Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 3 03:04:46 2023 +0000 chore: Bump eslint from 8.30.0 to 8.31.0 (#619) Bumps [eslint](https://github.com/eslint/eslint) from 8.30.0 to 8.31.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.30.0...v8.31.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit55443b3d5bAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Jan 3 03:03:28 2023 +0000 chore: Bump axios from 1.2.1 to 1.2.2 (#616) Bumps [axios](https://github.com/axios/axios) from 1.2.1 to 1.2.2. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.2.1...1.2.2) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit48f0cb7848Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Dec 20 03:04:13 2022 +0000 chore: Bump eslint from 8.29.0 to 8.30.0 (#610) Bumps [eslint](https://github.com/eslint/eslint) from 8.29.0 to 8.30.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.29.0...v8.30.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit90d1b38cb5Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Dec 13 03:05:43 2022 +0000 chore: Update dist commit422c797285Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Dec 13 03:04:51 2022 +0000 chore: Bump aws-sdk from 2.1268.0 to 2.1273.0 (#603) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1268.0 to 2.1273.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1268.0...v2.1273.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit4b942d82b0Author: GitHub Actions <github-aws-sdk-osds-automation@amazon.com> Date: Tue Dec 6 03:10:45 2022 +0000 chore: Update dist commit7437ed192eAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Dec 6 03:09:51 2022 +0000 chore: Bump aws-sdk from 2.1262.0 to 2.1268.0 (#596) Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.1262.0 to 2.1268.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js/compare/v2.1262.0...v2.1268.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commited4ba44f95Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Dec 6 03:08:24 2022 +0000 chore: Bump @vercel/ncc from 0.34.0 to 0.36.0 (#594) Bumps [@vercel/ncc](https://github.com/vercel/ncc) from 0.34.0 to 0.36.0. - [Release notes](https://github.com/vercel/ncc/releases) - [Commits](https://github.com/vercel/ncc/compare/0.34.0...0.36.0) --- updated-dependencies: - dependency-name: "@vercel/ncc" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> commit10dc6d923aAuthor: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Dec 6 03:05:08 2022 +0000 chore: Bump axios from 1.2.0 to 1.2.1 (#590) Bumps [axios](https://github.… * chore: tweak readme for v3
This commit is contained in:
19
.editorconfig
Normal file
19
.editorconfig
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# EditorConfig is awesome: https://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
2
.eslintignore
Normal file
2
.eslintignore
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
build
|
||||||
|
dist
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"commonjs": true,
|
|
||||||
"es6": true,
|
|
||||||
"node": true,
|
|
||||||
"jest": true
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended",
|
|
||||||
"globals": {
|
|
||||||
"Atomics": "readonly",
|
|
||||||
"SharedArrayBuffer": "readonly"
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2018
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
168
.eslintrc.yml
Normal file
168
.eslintrc.yml
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
env:
|
||||||
|
jest: true
|
||||||
|
node: true
|
||||||
|
root: true
|
||||||
|
plugins:
|
||||||
|
- import
|
||||||
|
- prettier
|
||||||
|
parserOptions:
|
||||||
|
ecmaVersion: 2021
|
||||||
|
sourceType: module
|
||||||
|
extends:
|
||||||
|
- plugin:prettier/recommended
|
||||||
|
- prettier
|
||||||
|
rules:
|
||||||
|
prettier/prettier: [error]
|
||||||
|
import/no-extraneous-dependencies:
|
||||||
|
- error
|
||||||
|
- devDependencies:
|
||||||
|
- "**/test/**"
|
||||||
|
- "**/build-tools/**"
|
||||||
|
optionalDependencies: false
|
||||||
|
peerDependencies: true
|
||||||
|
import/no-unresolved: [error]
|
||||||
|
import/order:
|
||||||
|
- warn
|
||||||
|
- groups:
|
||||||
|
- builtin
|
||||||
|
- external
|
||||||
|
alphabetize:
|
||||||
|
order: asc
|
||||||
|
caseInsensitive: true
|
||||||
|
array-callback-return: [warn]
|
||||||
|
no-await-in-loop: [warn]
|
||||||
|
no-constant-binary-expression: [error]
|
||||||
|
no-constructor-return: [error]
|
||||||
|
no-duplicate-imports: [error]
|
||||||
|
no-self-compare: [warn]
|
||||||
|
no-template-curly-in-string: [error]
|
||||||
|
no-unmodified-loop-condition: [error]
|
||||||
|
no-unreachable-loop: [error]
|
||||||
|
no-unused-private-class-members: [error]
|
||||||
|
no-use-before-define: [error]
|
||||||
|
require-atomic-updates: [error]
|
||||||
|
block-scoped-var: [warn]
|
||||||
|
camelcase: [warn]
|
||||||
|
class-methods-use-this: [error]
|
||||||
|
consistent-return: [warn]
|
||||||
|
consistent-this: [warn]
|
||||||
|
default-case-last: [warn]
|
||||||
|
default-param-last: [warn]
|
||||||
|
dot-notation: [error]
|
||||||
|
eqeqeq: [error]
|
||||||
|
guard-for-in: [warn]
|
||||||
|
logical-assignment-operators:
|
||||||
|
- error
|
||||||
|
- always
|
||||||
|
- enforceForIfStatements: false
|
||||||
|
no-array-constructor: [error]
|
||||||
|
no-bitwise: [error]
|
||||||
|
no-console: [warn]
|
||||||
|
no-empty-function: [warn]
|
||||||
|
no-eval: [error]
|
||||||
|
no-extra-bind: [error]
|
||||||
|
no-labels: [error]
|
||||||
|
no-implicit-globals: [error]
|
||||||
|
no-invalid-this: [error]
|
||||||
|
key-spacing: [error]
|
||||||
|
no-multiple-empty-lines: [error]
|
||||||
|
no-return-await: [warn]
|
||||||
|
no-trailing-spaces: [error]
|
||||||
|
no-lonely-if: [error]
|
||||||
|
no-nested-ternary: [warn]
|
||||||
|
no-mixed-operators: [warn]
|
||||||
|
no-proto: [error]
|
||||||
|
no-sequences: [error]
|
||||||
|
no-throw-literal: [error]
|
||||||
|
no-useless-call: [error]
|
||||||
|
no-useless-concat: [warn]
|
||||||
|
no-var: [error]
|
||||||
|
one-var-declaration-per-line: [error]
|
||||||
|
prefer-const: [warn]
|
||||||
|
prefer-arrow-callback: [warn]
|
||||||
|
prefer-regex-literals: [warn]
|
||||||
|
prefer-promise-reject-errors: [warn]
|
||||||
|
prefer-spread: [warn]
|
||||||
|
prefer-template: [warn]
|
||||||
|
require-await: [error]
|
||||||
|
overrides:
|
||||||
|
- files:
|
||||||
|
- '**/*.ts'
|
||||||
|
parser: '@typescript-eslint/parser'
|
||||||
|
parserOptions:
|
||||||
|
ecmaVersion: 2021
|
||||||
|
sourceType: module
|
||||||
|
project: ./tsconfig.json
|
||||||
|
extends:
|
||||||
|
- plugin:@typescript-eslint/recommended
|
||||||
|
- plugin:@typescript-eslint/recommended-requiring-type-checking
|
||||||
|
- plugin:import/typescript
|
||||||
|
rules:
|
||||||
|
'@typescript-eslint/array-type':
|
||||||
|
- warn
|
||||||
|
- default: array-simple
|
||||||
|
'@typescript-eslint/ban-tslint-comment': [error]
|
||||||
|
'@typescript-eslint/consistent-indexed-object-style': [warn]
|
||||||
|
'@typescript-eslint/consistent-type-assertions': [warn]
|
||||||
|
'@typescript-eslint/prefer-includes': [warn]
|
||||||
|
dot-notation: [off]
|
||||||
|
'@typescript-eslint/dot-notation': [error]
|
||||||
|
'@typescript-eslint/no-explicit-any': [off]
|
||||||
|
'@typescript-eslint/consistent-type-exports': [warn]
|
||||||
|
'@typescript-eslint/consistent-type-imports': [warn]
|
||||||
|
'@typescript-eslint/no-base-to-string': [error]
|
||||||
|
'@typescript-eslint/no-confusing-non-null-assertion': [warn]
|
||||||
|
'@typescript-eslint/no-invalid-void-type': [error]
|
||||||
|
'@typescript-eslint/no-meaningless-void-operator': [warn]
|
||||||
|
'@typescript-eslint/no-redundant-type-constituents': [warn]
|
||||||
|
'@typescript-eslint/no-unnecessary-boolean-literal-compare': [warn]
|
||||||
|
'@typescript-eslint/no-unnecessary-condition': [warn]
|
||||||
|
'@typescript-eslint/no-unnecessary-qualifier': [warn]
|
||||||
|
'@typescript-eslint/no-unnecessary-type-arguments': [warn]
|
||||||
|
'@typescript-eslint/non-nullable-type-assertion-style': [warn]
|
||||||
|
'@typescript-eslint/prefer-for-of': [error]
|
||||||
|
'@typescript-eslint/prefer-literal-enum-member': [warn]
|
||||||
|
'@typescript-eslint/prefer-optional-chain': [warn]
|
||||||
|
'@typescript-eslint/prefer-readonly': [warn]
|
||||||
|
'@typescript-eslint/prefer-regexp-exec': [warn]
|
||||||
|
'@typescript-eslint/prefer-string-starts-ends-with': [warn]
|
||||||
|
'@typescript-eslint/prefer-ts-expect-error': [error]
|
||||||
|
'@typescript-eslint/promise-function-async': [warn]
|
||||||
|
'@typescript-eslint/require-array-sort-compare': [error]
|
||||||
|
default-param-last: [off]
|
||||||
|
'@typescript-eslint/default-param-last': [warn]
|
||||||
|
no-array-constructor: [off]
|
||||||
|
'@typescript-eslint/no-array-constructor': [error]
|
||||||
|
no-dupe-class-members: [off]
|
||||||
|
'@typescript-eslint/no-dupe-class-members': [warn]
|
||||||
|
no-invalid-this: [off]
|
||||||
|
'@typescript-eslint/no-invalid-this': [warn]
|
||||||
|
no-unused-vars: [off]
|
||||||
|
'@typescript-eslint/no-unused-vars':
|
||||||
|
- error
|
||||||
|
- varsIgnorePattern: '^_'
|
||||||
|
argsIgnorePattern: '^_'
|
||||||
|
caughtErrorsIgnorePattern: '^_'
|
||||||
|
'@typescript-eslint/no-non-null-assertion': [off]
|
||||||
|
'@typescript-eslint/no-require-imports':
|
||||||
|
- error
|
||||||
|
no-return-await: [off]
|
||||||
|
'@typescript-eslint/return-await': [error]
|
||||||
|
no-shadow: [off]
|
||||||
|
'@typescript-eslint/no-shadow': [error]
|
||||||
|
'@typescript-eslint/no-floating-promises': [error]
|
||||||
|
"@typescript-eslint/member-ordering":
|
||||||
|
- error
|
||||||
|
- default:
|
||||||
|
- public-static-field
|
||||||
|
- public-static-method
|
||||||
|
- protected-static-field
|
||||||
|
- protected-static-method
|
||||||
|
- private-static-field
|
||||||
|
- private-static-method
|
||||||
|
- field
|
||||||
|
- constructor
|
||||||
|
- method
|
||||||
|
no-use-before-define: [off]
|
||||||
|
'@typescript-eslint/no-use-before-define': [error]
|
||||||
|
no-duplicate-imports: [off]
|
||||||
7
.gitattributes
vendored
Normal file
7
.gitattributes
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/dist/** linguist-generated
|
||||||
|
/package-lock.json linguist-generated
|
||||||
|
*.json text eol=lf
|
||||||
|
*.js text eol=lf
|
||||||
|
*.jsx text eol=lf
|
||||||
|
*.ts text eol=lf
|
||||||
|
*.tsx text eol=lf
|
||||||
16
.github/workflows/check.yml
vendored
16
.github/workflows/check.yml
vendored
@@ -1,16 +0,0 @@
|
|||||||
on:
|
|
||||||
[pull_request]
|
|
||||||
|
|
||||||
name: Check
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
name: Run Unit Tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Run tests
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npm test
|
|
||||||
51
.github/workflows/close-stale-issues.yml
vendored
51
.github/workflows/close-stale-issues.yml
vendored
@@ -1,51 +0,0 @@
|
|||||||
name: "Close Stale Issues"
|
|
||||||
|
|
||||||
# Controls when the action will run.
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 */4 * * *"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cleanup:
|
|
||||||
permissions:
|
|
||||||
issues: write
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Stale issue job
|
|
||||||
steps:
|
|
||||||
- uses: aws-actions/stale-issue-cleanup@v5
|
|
||||||
with:
|
|
||||||
# Setting messages to an empty string will cause the automation to skip
|
|
||||||
# that category
|
|
||||||
ancient-issue-message: This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.
|
|
||||||
stale-issue-message: This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.
|
|
||||||
stale-pr-message: This PR has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.
|
|
||||||
|
|
||||||
# These labels are required
|
|
||||||
stale-issue-label: closing-soon
|
|
||||||
exempt-issue-labels: no-autoclose
|
|
||||||
stale-pr-label: closing-soon
|
|
||||||
exempt-pr-labels: no-autoclose
|
|
||||||
response-requested-label: response-requested
|
|
||||||
|
|
||||||
# Don't set closed-for-staleness label to skip closing very old issues
|
|
||||||
# regardless of label
|
|
||||||
closed-for-staleness-label: closed-for-staleness
|
|
||||||
|
|
||||||
# Issue timing
|
|
||||||
days-before-stale: 5
|
|
||||||
days-before-close: 2
|
|
||||||
days-before-ancient: 36500
|
|
||||||
|
|
||||||
# If you don't want to mark a issue as being ancient based on a
|
|
||||||
# threshold of "upvotes", you can set this here. An "upvote" is
|
|
||||||
# the total number of +1, heart, hooray, and rocket reactions
|
|
||||||
# on an issue.
|
|
||||||
minimum-upvotes-to-exempt: 5
|
|
||||||
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
loglevel: DEBUG
|
|
||||||
# Set dry-run to true to not perform label or close actions.
|
|
||||||
dry-run: false
|
|
||||||
5
.github/workflows/closed-issue-message.yml
vendored
5
.github/workflows/closed-issue-message.yml
vendored
@@ -13,6 +13,7 @@ jobs:
|
|||||||
# These inputs are both required
|
# These inputs are both required
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
message: |
|
message: |
|
||||||
Comments on closed issues are hard for our team to see.
|
** Note **
|
||||||
|
Comments on closed issues are hard for our team to see.
|
||||||
If you need more assistance, please either tag a team member or open a new issue that references this one.
|
If you need more assistance, please either tag a team member or open a new issue that references this one.
|
||||||
If you wish to keep having a conversation with other community members under this issue feel free to do so.
|
If you wish to keep having a conversation with other community members under this issue feel free to do so.
|
||||||
|
|||||||
@@ -15,4 +15,4 @@ jobs:
|
|||||||
- name: Stale discussions action
|
- name: Stale discussions action
|
||||||
uses: aws-github-ops/handle-stale-discussions@v1
|
uses: aws-github-ops/handle-stale-discussions@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
|||||||
4
.github/workflows/package.yml
vendored
4
.github/workflows/package.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Update dist files on
|
name: Update dist files on main branch
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
npm test
|
npm test
|
||||||
npm run package
|
npm run package
|
||||||
- name: Configure AWS credentials
|
- name: Configure AWS credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
with:
|
with:
|
||||||
aws-region: us-west-2
|
aws-region: us-west-2
|
||||||
role-to-assume: ${{ secrets.SECRETS_AWS_ROLE_TO_ASSUME }}
|
role-to-assume: ${{ secrets.SECRETS_AWS_ROLE_TO_ASSUME }}
|
||||||
|
|||||||
27
.github/workflows/pull-request-lint.yml
vendored
Normal file
27
.github/workflows/pull-request-lint.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
name: pull-request-lint
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
types:
|
||||||
|
- labeled
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
- reopened
|
||||||
|
- ready_for_review
|
||||||
|
- edited
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
name: Validate PR title
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
steps:
|
||||||
|
- uses: amannn/action-semantic-pull-request@v4.5.0
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
types: |-
|
||||||
|
feat
|
||||||
|
fix
|
||||||
|
chore
|
||||||
|
requireScope: false
|
||||||
68
.github/workflows/tests-integ.yml
vendored
Normal file
68
.github/workflows/tests-integ.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
name: Run tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
integ-oidc:
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [[self-hosted, linux-fargate], windows-latest, ubuntu-latest, macos-latest]
|
||||||
|
node: [14, 16, 18]
|
||||||
|
name: Run OIDC integ tests
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- name: "Checkout repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Integ test for OIDC
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
aws-region: us-west-2
|
||||||
|
role-to-assume: ${{ secrets.SECRETS_OIDC_AWS_ROLE_TO_ASSUME }}
|
||||||
|
role-duration-seconds: 900
|
||||||
|
role-session-name: IntegOidcAssumeRole
|
||||||
|
role-external-id: ${{ secrets.SECRETS_OIDC_AWS_ROLE_EXTERNAL_ID }}
|
||||||
|
integ-access-keys:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [[self-hosted, linux-fargate], windows-latest, ubuntu-latest, macos-latest]
|
||||||
|
node: [14, 16, 18]
|
||||||
|
name: Run access key integ tests
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- name: "Checkout repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Integ test for access keys
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
aws-region: us-west-2
|
||||||
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
role-to-assume: ${{ secrets.SECRETS_AWS_ROLE_TO_ASSUME }}
|
||||||
|
role-session-name: IntegAccessKeysAssumeRole
|
||||||
|
role-external-id: ${{ secrets.SECRETS_AWS_ROLE_EXTERNAL_ID }}
|
||||||
|
integ-iam-user:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [[self-hosted, linux-fargate], windows-latest, ubuntu-latest, macos-latest]
|
||||||
|
node: [14, 16, 18]
|
||||||
|
name: Run IAM User integ tests
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- name: "Checkout repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Integ test for IAM user
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
aws-region: us-west-2
|
||||||
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
41
.github/workflows/tests-unit.yml
vendored
Normal file
41
.github/workflows/tests-unit.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
on:
|
||||||
|
[pull_request]
|
||||||
|
|
||||||
|
name: Run unit tests
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
unit-test:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||||
|
node: [14, 16, 18]
|
||||||
|
name: Run unit tests
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: 5
|
||||||
|
steps:
|
||||||
|
- name: "Checkout repository"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: "Setup node"
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
- name: "Install dependencies"
|
||||||
|
uses: bahmutov/npm-install@v1
|
||||||
|
- name: "Run tests"
|
||||||
|
run: npm run test --if-present
|
||||||
|
lint:
|
||||||
|
name: Ensure code standards
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
steps:
|
||||||
|
- name: "Checkout repostiory"
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: "Setup node"
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
- name: "Install dependencies"
|
||||||
|
uses: bahmutov/npm-install@v1
|
||||||
|
- name: "Lint code"
|
||||||
|
run: npm run lint --if-present
|
||||||
70
.gitignore
vendored
70
.gitignore
vendored
@@ -1,66 +1,6 @@
|
|||||||
node_modules/
|
node_modules
|
||||||
|
|
||||||
# Editors
|
|
||||||
.vscode
|
|
||||||
.idea
|
|
||||||
|
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
coverage
|
||||||
|
.DS_Store
|
||||||
# nyc test coverage
|
Thumbs.db
|
||||||
.nyc_output
|
build
|
||||||
|
test-reports
|
||||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Other Dependency directories
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# TypeScript v1 declaration files
|
|
||||||
typings/
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variables file
|
|
||||||
.env
|
|
||||||
|
|
||||||
# next.js build output
|
|
||||||
.next
|
|
||||||
|
|||||||
8
.prettierrc.json
Normal file
8
.prettierrc.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 120,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"overrides": []
|
||||||
|
}
|
||||||
19
CHANGELOG.md
19
CHANGELOG.md
@@ -2,6 +2,25 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
|
## [3.0.0](https://github.com/aws-actions/configure-aws-credentials/compare/v2.2.0...v3.0.0) (2023-08-21)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
* Can configure `max-retries` and `disable-retry` to modify retry functionality when the assume role call fails
|
||||||
|
* Set returned credentials as step outputs with `output-credentials`
|
||||||
|
* Clear AWS related environment variables at the start of the action with `unset-current-credentials`
|
||||||
|
* Unique role identifier is now printed in the workflow logs
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
* Can't use credentials if they contain a special character
|
||||||
|
* Retry functionality added when generating the JWT fails
|
||||||
|
* Can now use `webIdentityTokenFile` option
|
||||||
|
* Branch name validation too strict
|
||||||
|
* JS SDK v2 deprecation warning in workflow logs
|
||||||
|
|
||||||
|
### Changes to existing functionality
|
||||||
|
* Default session duration is now 1 hour in all cases (from 6 hours in some cases)
|
||||||
|
* Account ID will not be masked by default in logs
|
||||||
|
|
||||||
## [2.2.0](https://github.com/aws-actions/configure-aws-credentials/compare/v2.1.0...v2.2.0) (2023-05-31)
|
## [2.2.0](https://github.com/aws-actions/configure-aws-credentials/compare/v2.1.0...v2.2.0) (2023-05-31)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
4
LICENSE
4
LICENSE
@@ -1,6 +1,4 @@
|
|||||||
MIT License
|
Copyright (c) 2019-2022 Amazon.com, Inc. or its affiliates
|
||||||
|
|
||||||
Copyright 2019 Amazon.com, Inc. or its affiliates.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
460
README.md
460
README.md
@@ -5,43 +5,76 @@ and exports environment variables for your other Actions to use. Environment
|
|||||||
variable exports are detected by both the AWS SDKs and the AWS CLI for AWS API
|
variable exports are detected by both the AWS SDKs and the AWS CLI for AWS API
|
||||||
calls.
|
calls.
|
||||||
|
|
||||||
### Recent updates
|
---
|
||||||
|
|
||||||
**GitHub OIDC Changes**
|
### News
|
||||||
|
|
||||||
In #[357](https://github.com/aws-actions/configure-aws-credentials/issues/357), we
|
We have recently released `v3` of Configure AWS Credentials! With this new
|
||||||
observed that GitHub recently started offering one of several intermediate OIDC
|
release we have migrated the code to TypeScript, and have also migrated away
|
||||||
endpoint thumbprints. Because IAM requires statically configured endpoint
|
from using `v2` of the JavaScript AWS SDK. This should eliminate the warning you
|
||||||
thumbprints, AWS customers that had only one thumbprint configured could see
|
have seen in your workflow logs about `v2` deprecation.
|
||||||
intermittent authentication failures. **As of July 6, 2023, AWS has made a change to
|
|
||||||
IAM that will no longer require any particular certificate thumbprint for
|
|
||||||
tokens.actions.githubusercontent.com**, which is the GitHub OIDC endpoint. Instead,
|
|
||||||
AWS secures communication with GitHub OIDC using our library of trusted CAs rather
|
|
||||||
than using a certificate thumbprint to verify the server certificate. The IAM APIs
|
|
||||||
still require that a thumbprint is configured, but those thumbprints will be ignored
|
|
||||||
when authenticating tokens.actions.githubusercontent.com.
|
|
||||||
|
|
||||||
GitHub Enterprise Server customers use a different endpoint so they are not affected by
|
In addition to the refactored codebase, we have also introduced some changes to
|
||||||
this change.
|
existing functionality, added some new features, and fixed some bugs. These
|
||||||
|
changes should be backwards compatible with your existing workflows.
|
||||||
|
|
||||||
*Original message:*
|
**Notable changes to existing functionality**
|
||||||
There are now [two possible intermediary certificates](https://github.blog/changelog/2023-06-27-github-actions-update-on-oidc-integration-with-aws/) for the Actions SSL certificate. Previously, the certificate with the thumbprint `6938fd4d98bab03faadb97b34396831e3780aea1` was guaranteed to return. Now, the certificate with the thumbprint `1c58a3a8518e8759bf075b76b750d4f2df264fcd` can also be returned, so you will need to [update your identity provider](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html) with this additional new thumbprint.
|
|
||||||
|
- By default, the assumed role credentials will only be valid for one hour in
|
||||||
|
_all_ use cases. This is changed from 6 hours in `v2`. You can adjust this value
|
||||||
|
with the `role-duration-seconds` input.
|
||||||
|
- By default, your account ID will not be masked in workflow logs. This was
|
||||||
|
changed from being masked by default in the previous version. AWS does consider
|
||||||
|
account IDs as sensitive information, so this change reflects that stance. You
|
||||||
|
can rever to the old default and mask your account ID in workflow logs by
|
||||||
|
setting the `mask-aws-account-id` input to `true`.
|
||||||
|
|
||||||
|
**New features**
|
||||||
|
|
||||||
|
- You can now configure retry settings in case your STS call fails. By default,
|
||||||
|
we retry with exponential backoff twelve times. You can disable this behavior
|
||||||
|
altogether by setting the `disable-retry` input to `true`, or you can configure
|
||||||
|
the number of times the action will retry with the `retry-max-attempts` input.
|
||||||
|
- You can now set the returned credentials as action step outputs. To do this,
|
||||||
|
you can set the `output-credentials` prop to `true`.
|
||||||
|
- There's now an option to clear the AWS-related environment variables at the
|
||||||
|
start of the action. Clearing these variables is often a workaround for
|
||||||
|
problems, so enabling this can be helpful if existing credentials or environment
|
||||||
|
variables are interfering with the action. You can enable this by setting the
|
||||||
|
`unset-current-credentials` input to `true`.
|
||||||
|
|
||||||
|
**Bug fixes**
|
||||||
|
|
||||||
|
You can find a list of bugs that have been fixed in v3 in the
|
||||||
|
[changelog](./changelog.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Table of Contents
|
### Table of Contents
|
||||||
<!-- toc -->
|
<!-- toc -->
|
||||||
- [Usage](#usage)
|
- [Overview](#overview)
|
||||||
- [Credentials](#credentials)
|
- [Security recommendations](#security-recommendations)
|
||||||
- [Assuming a Role](#assuming-a-role)
|
- [Using this action](#using-this-action)
|
||||||
+ [Session tagging](#session-tagging)
|
+ [Credential Lifetime](#credential-lifetime)
|
||||||
|
+ [External ID](#external-id)
|
||||||
|
+ [Session tagging](#session-tagging-and-name)
|
||||||
+ [Sample IAM Role Permissions](#sample-iam-role-cloudformation-template)
|
+ [Sample IAM Role Permissions](#sample-iam-role-cloudformation-template)
|
||||||
|
+ [Misc](#misc)
|
||||||
|
- [OIDC](#OIDC)
|
||||||
|
+ [Audience](#audience)
|
||||||
|
+ [Sample IAM OIDC CloudFormation Template](#sample-iam-oidc-cloudformation-template)
|
||||||
|
+ [Claims and scoping permissions](#claims-and-scoping-permissions)
|
||||||
|
+ [Further info](#further-info)
|
||||||
- [Self-Hosted Runners](#self-hosted-runners)
|
- [Self-Hosted Runners](#self-hosted-runners)
|
||||||
+ [Proxy Configuration](#proxy-configuration)
|
+ [Proxy Configuration](#proxy-configuration)
|
||||||
|
+ [Use with the AWS CLI](#use-with-the-aws-cli)
|
||||||
|
- [Examples](#examples)
|
||||||
- [License Summary](#license-summary)
|
- [License Summary](#license-summary)
|
||||||
- [Security Disclosures](#security-disclosures)
|
- [Security Disclosures](#security-disclosures)
|
||||||
<!-- tocstop -->
|
<!-- tocstop -->
|
||||||
|
|
||||||
## Usage
|
## Overview
|
||||||
We support four methods for fetching credentials from AWS, but we recommend that
|
We support five methods for fetching credentials from AWS, but we recommend that
|
||||||
you use GitHub's OIDC provider in conjunction with a configured AWS IAM
|
you use GitHub's OIDC provider in conjunction with a configured AWS IAM
|
||||||
Identity Provider endpoint.
|
Identity Provider endpoint.
|
||||||
|
|
||||||
@@ -49,14 +82,14 @@ To do that, you would add the following step to your workflow:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
with:
|
with:
|
||||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
```
|
```
|
||||||
This will cause the action to perform an `AssumeRoleWithWebIdentity` call and
|
This will cause the action to perform an [`AssumeRoleWithWebIdentity`](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html) call and
|
||||||
return temporary security credentials for use by other actions. In order for
|
return temporary security credentials for use by other steps in your workflow. In order for
|
||||||
this to work, you'll need to preconfigure the IAM IdP in your AWS account
|
this to work, you'll need to preconfigure the IAM Identity Provider in your AWS account
|
||||||
(see [Assuming a Role](#assuming-a-role) for details).
|
(see [Assuming a Role](#assuming-a-role) for details).
|
||||||
|
|
||||||
You can use this action with the AWS CLI available in
|
You can use this action with the AWS CLI available in
|
||||||
@@ -78,7 +111,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Configure AWS credentials from Test account
|
- name: Configure AWS credentials from Test account
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
with:
|
with:
|
||||||
role-to-assume: arn:aws:iam::111111111111:role/my-github-actions-role-test
|
role-to-assume: arn:aws:iam::111111111111:role/my-github-actions-role-test
|
||||||
aws-region: us-east-1
|
aws-region: us-east-1
|
||||||
@@ -86,7 +119,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
aws s3 sync . s3://my-s3-test-website-bucket
|
aws s3 sync . s3://my-s3-test-website-bucket
|
||||||
- name: Configure AWS credentials from Production account
|
- name: Configure AWS credentials from Production account
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
with:
|
with:
|
||||||
role-to-assume: arn:aws:iam::222222222222:role/my-github-actions-role-prod
|
role-to-assume: arn:aws:iam::222222222222:role/my-github-actions-role-prod
|
||||||
aws-region: us-west-2
|
aws-region: us-west-2
|
||||||
@@ -98,7 +131,13 @@ jobs:
|
|||||||
See [action.yml](action.yml) for the full documentation for this action's inputs
|
See [action.yml](action.yml) for the full documentation for this action's inputs
|
||||||
and outputs.
|
and outputs.
|
||||||
|
|
||||||
## Credentials
|
### Note about GHES
|
||||||
|
|
||||||
|
Some of this documentation may be inaccurate if you are using GHES (GitHub Enterprise Servers), please take note to review the GitHub documentation when relevant.
|
||||||
|
|
||||||
|
For example, the URL that the OIDC JWT is issued from is different than the usual `tokens.actions.githubusercontent.com`, and will be unique to your enterprise server. As a result, you will need to configure this differently when you create the Identity Provider.
|
||||||
|
|
||||||
|
## Security recommendations
|
||||||
|
|
||||||
We recommend following
|
We recommend following
|
||||||
[Amazon IAM best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
|
[Amazon IAM best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
|
||||||
@@ -109,15 +148,18 @@ for the AWS credentials used in GitHub Actions workflows, including:
|
|||||||
GitHub Actions workflows.
|
GitHub Actions workflows.
|
||||||
* [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log) of the credentials used in GitHub Actions workflows.
|
* [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log) of the credentials used in GitHub Actions workflows.
|
||||||
|
|
||||||
## Assuming a Role
|
## Using this action
|
||||||
There are four different supported ways to retrieve credentials. We recommend
|
There are five different supported ways to retrieve credentials:
|
||||||
using [GitHub's OIDC provider](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)
|
|
||||||
to get short-lived credentials needed for your actions. Specifying
|
|
||||||
`role-to-assume` **without** providing an `aws-access-key-id` or a
|
|
||||||
`web-identity-token-file`, or setting `role-chaining`, will signal to the action that you wish to use the
|
|
||||||
OIDC provider. If `role-chaining` is `true`, existing credentials in the environment will be used to assume `role-to-assume`.
|
|
||||||
|
|
||||||
The following table describes which identity is used based on which values are supplied to the Action:
|
- Using GitHub's OIDC provider (`AssumeRoleWithWebIdentity`)
|
||||||
|
- Proceeding as an IAM user (No STS call is made)
|
||||||
|
- Using access keys as action input (`AssumeRole`)
|
||||||
|
- Using a WebIdentity Token File (`AssumeRoleWithWebIdentity`)
|
||||||
|
- Using existing credentials in your runner (`AssumeRole`)
|
||||||
|
|
||||||
|
We recommend using [GitHub's OIDC provider](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services) to get short-lived AWS credentials needed for your actions. See [OIDC](#OIDC) for more information on how to setup your AWS account to assume a role with OIDC.
|
||||||
|
|
||||||
|
The following table describes which method is used based on which values are supplied to the Action:
|
||||||
|
|
||||||
| **Identity Used** | `aws-access-key-id` | `role-to-assume` | `web-identity-token-file` | `role-chaining` |
|
| **Identity Used** | `aws-access-key-id` | `role-to-assume` | `web-identity-token-file` | `role-chaining` |
|
||||||
| --------------------------------------------------------------- | ------------------- | ---------------- | ------------------------- | - |
|
| --------------------------------------------------------------- | ------------------- | ---------------- | ------------------------- | - |
|
||||||
@@ -128,97 +170,135 @@ The following table describes which identity is used based on which values are s
|
|||||||
| Assume Role using existing credentials | | ✔ | | ✔ |
|
| Assume Role using existing credentials | | ✔ | | ✔ |
|
||||||
|
|
||||||
### Credential Lifetime
|
### Credential Lifetime
|
||||||
The default session duration is **1 hour** when using the OIDC provider to
|
The default session duration is **1 hour**.
|
||||||
directly assume an IAM Role or when an `aws-session-token` is directly provided.
|
|
||||||
The default session duration is **6 hours** when using an IAM User to assume an
|
|
||||||
IAM Role (by providing an `aws-access-key-id`, `aws-secret-access-key`, and a
|
|
||||||
`role-to-assume`) .
|
|
||||||
|
|
||||||
If you would like to adjust this you can pass a duration to `role-duration-seconds`, but the duration cannot exceed the maximum that was defined when the IAM Role was created.
|
If you would like to adjust this you can pass a duration to `role-duration-seconds`, but the duration cannot exceed the maximum that was defined when the IAM Role was created.
|
||||||
The default session name is GitHubActions, and you can modify it by specifying the desired name in `role-session-name`.
|
|
||||||
The default audience is `sts.amazonaws.com` which you can replace by specifying the desired audience name in `audience`.
|
|
||||||
|
|
||||||
### Examples
|
### External ID
|
||||||
|
If your role requires an external ID to assume, you can provide the external ID with the `role-external-id` input
|
||||||
|
|
||||||
#### AssumeRoleWithWebIdentity (recommended)
|
### Session tagging and name
|
||||||
|
The default session name is "GitHubActions", and you can modify it by specifying the desired name in `role-session-name`.
|
||||||
|
The session will be tagged with the following tags: (`GITHUB_` environment variable definitions can be
|
||||||
|
[found here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables))
|
||||||
|
|
||||||
|
| Key | Value |
|
||||||
|
| ---------- | ----------------- |
|
||||||
|
| GitHub | "Actions" |
|
||||||
|
| Repository | GITHUB_REPOSITORY |
|
||||||
|
| Workflow | GITHUB_WORKFLOW |
|
||||||
|
| Action | GITHUB_ACTION |
|
||||||
|
| Actor | GITHUB_ACTOR |
|
||||||
|
| Branch | GITHUB_REF |
|
||||||
|
| Commit | GITHUB_SHA |
|
||||||
|
|
||||||
|
_Note: all tag values must conform to
|
||||||
|
[the requirements](https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html).
|
||||||
|
Particularly, `GITHUB_WORKFLOW` will be truncated if it's too long. If
|
||||||
|
`GITHUB_ACTOR` or `GITHUB_WORKFLOW` contain invalid characters, the characters
|
||||||
|
will be replaced with an '*'._
|
||||||
|
|
||||||
|
The action will use session tagging by default during role assumption, unless you are assuming a role with a WebIdentity.
|
||||||
|
For WebIdentity role assumption, the session tags have to be included
|
||||||
|
in the encoded WebIdentity token. This means that Tags can only be supplied by
|
||||||
|
the OIDC provider, and they cannot set during the AssumeRoleWithWebIdentity API call
|
||||||
|
within the Action. See [issue 419](https://github.com/aws-actions/configure-aws-credentials/issues/419) for more info
|
||||||
|
|
||||||
|
You can skip this session tagging by providing
|
||||||
|
`role-skip-session-tagging` as true in the action's inputs:
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
role-skip-session-tagging: true
|
||||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
|
||||||
role-session-name: MySessionName
|
|
||||||
```
|
```
|
||||||
In this example, the Action will load the OIDC token from the GitHub-provided environment variable and use it to assume the role `arn:aws:iam::123456789100:role/my-github-actions-role` with the session name `MySessionName`.
|
|
||||||
|
|
||||||
#### AssumeRole with static IAM credentials in repository secrets
|
### Session policies
|
||||||
|
|
||||||
|
#### Inline session policies
|
||||||
|
An IAM policy in stringified JSON format that you want to use as an inline session policy.
|
||||||
|
Depending on preferences, the JSON could be written on a single line like this:
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
inline-session-policy: '{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:List*","Resource":"*"}]}'
|
||||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
|
||||||
role-session-name: MySessionName
|
|
||||||
- name: Configure other AWS Credentials
|
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
|
||||||
aws-region: us-east-2
|
|
||||||
role-to-assume: arn:aws:iam::987654321000:role/my-second-role
|
|
||||||
role-session-name: MySessionName
|
|
||||||
role-chaining: true
|
|
||||||
```
|
```
|
||||||
In this two-step example, the first step will use OIDC to assume the role `arn:aws:iam::123456789100:role/my-github-actions-role` just as in the prior example. Following that, a second step will use this role to assume a different role, `arn:aws:iam::987654321000:role/my-second-role`.
|
Or we can have a nicely formatted JSON as well:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
with:
|
||||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
inline-session-policy: >-
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
{
|
||||||
aws-region: us-east-2
|
"Version": "2012-10-17",
|
||||||
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
|
"Statement": [
|
||||||
role-external-id: ${{ secrets.AWS_ROLE_EXTERNAL_ID }}
|
{
|
||||||
role-duration-seconds: 1200
|
"Sid":"Stmt1",
|
||||||
role-session-name: MySessionName
|
"Effect":"Allow",
|
||||||
|
"Action":"s3:List*",
|
||||||
|
"Resource":"*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
```
|
```
|
||||||
In this example, the secret `AWS_ROLE_TO_ASSUME` contains a string like `arn:aws:iam::123456789100:role/my-github-actions-role`. To assume a role in the same account as the static credentials, you can simply specify the role name, like `role-to-assume: my-github-actions-role`.
|
|
||||||
|
|
||||||
#### AssumeRoleWithWebIdentity using a custom audience
|
#### Managed session policies
|
||||||
|
The Amazon Resource Names (ARNs) of the IAM managed policies that you want to use as managed session policies.
|
||||||
|
The policies must exist in the same account as the role. You can pass a single managed policy like this:
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials for Beta Customers
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
with:
|
||||||
audience: beta-customers
|
managed-session-policies: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
||||||
|
```
|
||||||
|
And we can pass multiple managed policies likes this:
|
||||||
|
```yaml
|
||||||
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
|
with:
|
||||||
|
managed-session-policies: |
|
||||||
|
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
||||||
|
arn:aws:iam::aws:policy/AmazonS3OutpostsReadOnlyAccess
|
||||||
|
```
|
||||||
|
|
||||||
|
### Misc
|
||||||
|
|
||||||
|
#### Adjust the retry mechanism
|
||||||
|
You can now configure retry settings for when the STS call fails. By default, we retry with exponential backoff `12` times. You can disable this behavior altogether by setting the `disable-retry` input to `true`, or you can configure the number of times it retries with the `retry-max-attempts` input.
|
||||||
|
|
||||||
|
#### Mask account ID
|
||||||
|
Your account ID is not masked by default in workflow logs since it's not considered sensitive information. However, you can set the `mask-aws-account-id` input to `true` to mask your account ID in workflow logs if desired.
|
||||||
|
|
||||||
|
#### Unset current credentials
|
||||||
|
Sometimes, existing credentials in your runner can get in the way of the intended outcome, and the recommended solution is to include another step in your workflow which unsets the environment variables set by this action. Now if you set the `unset-current-credentials` input to `true`, the workaround is made eaiser
|
||||||
|
|
||||||
|
## OIDC
|
||||||
|
|
||||||
|
We recommend using [GitHub's OIDC provider](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services) to get short-lived AWS credentials needed for your actions. When using OIDC, this action will create a JWT unique to the workflow run, and it will use this JWT to assume the role. For this action to create the JWT, it is required for your workflow to have the `id-token: write` permission:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
|
contents: read
|
||||||
|
```
|
||||||
|
|
||||||
|
### Audience
|
||||||
|
|
||||||
|
When the JWT is created, an audience needs to be specified. By default, the audience is `sts.amazon.com` and this will work for most cases. Changing the default audience may be necessary when using non-default AWS partitions. You can specify the audience through the `audience` input:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS Credentials for China region audience
|
||||||
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
|
with:
|
||||||
|
audience: sts.amazonaws.com.cn
|
||||||
aws-region: us-east-3
|
aws-region: us-east-3
|
||||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||||
role-session-name: MySessionName
|
|
||||||
```
|
```
|
||||||
In this example, the audience has been changed from the default to use a different audience name `beta-customers`. This can help ensure that the role can only affect those AWS accounts whose GitHub OIDC providers have explicitly opted in to the `beta-customers` label.
|
|
||||||
|
|
||||||
Changing the default audience may be necessary when using non-default [AWS partitions](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html).
|
### Sample IAM OIDC CloudFormation Template
|
||||||
|
To use GitHub's OIDC provider, you must first set up federation
|
||||||
#### AssumeRoleWithWebIdentity and disable secure Action outputs
|
|
||||||
```yaml
|
|
||||||
- name: Configure AWS Credentials
|
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
|
||||||
aws-region: us-east-2
|
|
||||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
|
||||||
role-session-name: MySessionName
|
|
||||||
mask-aws-account-id: false
|
|
||||||
```
|
|
||||||
In this example, account ID masking has been disabled. By default, the AWS
|
|
||||||
account ID will be obscured in the action's output. This may be helpful when
|
|
||||||
debugging action failures.
|
|
||||||
|
|
||||||
## Sample IAM OIDC CloudFormation Template
|
|
||||||
If you choose to use GitHub's OIDC provider, you must first set up federation
|
|
||||||
with the provider in as an IAM IdP. The GitHub OIDC provider only needs to be
|
with the provider in as an IAM IdP. The GitHub OIDC provider only needs to be
|
||||||
created once per account (i.e. multiple IAM Roles that can be assumed by the
|
created once per account (i.e. multiple IAM Roles that can be assumed by the
|
||||||
GitHub's OIDC can share a single OIDC Provider).
|
GitHub's OIDC can share a single OIDC Provider).
|
||||||
|
|
||||||
Note that the thumbprint has been set to all F's because the thumbprint is not
|
Note that the thumbprint has been set to all F's because the thumbprint is not
|
||||||
used when authenticating tokens.actions.githubusercontent.com. Instead, IAM
|
used when authenticating `tokens.actions.githubusercontent.com`. Instead, IAM
|
||||||
uses its library of trusted CAs to authenticate. However, this value is still
|
uses its library of trusted CAs to authenticate. However, this value is still
|
||||||
required by the API.
|
required by the API.
|
||||||
|
|
||||||
@@ -282,16 +362,14 @@ Outputs:
|
|||||||
Value: !GetAtt Role.Arn
|
Value: !GetAtt Role.Arn
|
||||||
```
|
```
|
||||||
|
|
||||||
To align with the Amazon IAM best practice of
|
### Claims and scoping permissions
|
||||||
[granting least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege), the assume role policy document should contain a
|
To align with the Amazon IAM best practice of [granting least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege), the assume role policy document should contain a [`Condition`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html) that specifies a subject (`sub`) allowed to assume the role. [GitHub also recommends](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#defining-trust-conditions-on-cloud-roles-using-oidc-claims) filtering for the correct audience (`aud`). See [AWS IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif) on which claims you can filter for in your trust policies.
|
||||||
[`Condition`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html) that specifies a subject allowed to assume the role. Without a subject
|
|
||||||
condition, any GitHub user or repository could potentially assume the role. The
|
Without a subject (`sub`) condition, any GitHub user or repository could potentially assume the role. The subject can be scoped to a GitHub organization and repository as shown in the CloudFormation template. However, scoping it down to your org and repo may cause the role assumption to fail in some cases. See [Example subject claims](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims) for specific details on what the subject value will be depending on your workflow. You can also [customize your subject claim](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#customizing-the-token-claims) if you want full control over the information you can filter for in your trust policy. If you aren't sure what your subject (`sub`) key is, you can add the [`actions-oidc-debugger`](https://github.com/github/actions-oidc-debugger) action to your workflow to see the value of the subject (`sub`) key, as well as other claims.
|
||||||
subject can be scoped to a GitHub organization and repository as shown in the
|
|
||||||
CloudFormation template. Additional claim conditions can be added for higher
|
Additional claim conditions can be added for higher specificity as explained in the [GitHub documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). Due to implementation details, not every OIDC claim is presently supported by IAM.
|
||||||
specificity as explained in the
|
|
||||||
[GitHub documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect).
|
### Further info
|
||||||
Due to implementation details, not every OIDC claim is presently supported by
|
|
||||||
IAM.
|
|
||||||
|
|
||||||
For further information on OIDC and GitHub Actions, please see:
|
For further information on OIDC and GitHub Actions, please see:
|
||||||
|
|
||||||
@@ -301,82 +379,6 @@ For further information on OIDC and GitHub Actions, please see:
|
|||||||
* [GitHub docs: Configuring OpenID Connect in Amazon Web Services](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)
|
* [GitHub docs: Configuring OpenID Connect in Amazon Web Services](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)
|
||||||
* [GitHub changelog: GitHub Actions: Secure cloud deployments with OpenID Connect](https://github.blog/changelog/2021-10-27-github-actions-secure-cloud-deployments-with-openid-connect/)
|
* [GitHub changelog: GitHub Actions: Secure cloud deployments with OpenID Connect](https://github.blog/changelog/2021-10-27-github-actions-secure-cloud-deployments-with-openid-connect/)
|
||||||
|
|
||||||
### Session tagging
|
|
||||||
The session will have the name "GitHubActions" and be tagged with the following
|
|
||||||
tags: (`GITHUB_` environment variable definitions can be
|
|
||||||
[found here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables))
|
|
||||||
|
|
||||||
| Key | Value |
|
|
||||||
| ---------- | ----------------- |
|
|
||||||
| GitHub | "Actions" |
|
|
||||||
| Repository | GITHUB_REPOSITORY |
|
|
||||||
| Workflow | GITHUB_WORKFLOW |
|
|
||||||
| Action | GITHUB_ACTION |
|
|
||||||
| Actor | GITHUB_ACTOR |
|
|
||||||
| Branch | GITHUB_REF |
|
|
||||||
| Commit | GITHUB_SHA |
|
|
||||||
|
|
||||||
_Note: all tag values must conform to
|
|
||||||
[the requirements](https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html).
|
|
||||||
Particularly, `GITHUB_WORKFLOW` will be truncated if it's too long. If
|
|
||||||
`GITHUB_ACTOR` or `GITHUB_WORKFLOW` contain invalid characters, the characters
|
|
||||||
will be replaced with an '*'._
|
|
||||||
|
|
||||||
The action will use session tagging by default during role assumption.
|
|
||||||
Note that for WebIdentity role assumption, the session tags have to be included
|
|
||||||
in the encoded WebIdentity token. This means that Tags can only be supplied by
|
|
||||||
the OIDC provider and not set during the AssumeRoleWithWebIdentity API call
|
|
||||||
within the Action. You can skip this session tagging by providing
|
|
||||||
`role-skip-session-tagging` as true in the action's inputs:
|
|
||||||
```yaml
|
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
|
||||||
role-skip-session-tagging: true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Inline session policy
|
|
||||||
An IAM policy in stringified JSON format that you want to use as an inline session policy.
|
|
||||||
Depending on preferences, the JSON could be written on a single line like this:
|
|
||||||
```yaml
|
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
|
||||||
inline-session-policy: '{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:List*","Resource":"*"}]}'
|
|
||||||
```
|
|
||||||
Or we can have a nicely formatted JSON as well:
|
|
||||||
```yaml
|
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
|
||||||
inline-session-policy: >-
|
|
||||||
{
|
|
||||||
"Version": "2012-10-17",
|
|
||||||
"Statement": [
|
|
||||||
{
|
|
||||||
"Sid":"Stmt1",
|
|
||||||
"Effect":"Allow",
|
|
||||||
"Action":"s3:List*",
|
|
||||||
"Resource":"*"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Managed session policies
|
|
||||||
The Amazon Resource Names (ARNs) of the IAM managed policies that you want to use as managed session policies.
|
|
||||||
The policies must exist in the same account as the role. You can pass a single managed policy like this:
|
|
||||||
```yaml
|
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
|
||||||
managed-session-policies: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
|
||||||
```
|
|
||||||
And we can pass multiple managed policies likes this:
|
|
||||||
```yaml
|
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
|
||||||
with:
|
|
||||||
managed-session-policies: |
|
|
||||||
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
|
||||||
arn:aws:iam::aws:policy/AmazonS3OutpostsReadOnlyAccess
|
|
||||||
```
|
|
||||||
|
|
||||||
## Self-Hosted Runners
|
## Self-Hosted Runners
|
||||||
|
|
||||||
If you run your GitHub Actions in a
|
If you run your GitHub Actions in a
|
||||||
@@ -388,13 +390,13 @@ authenticate on your runner, this Action will as well.
|
|||||||
|
|
||||||
If no access key credentials are given in the action inputs, this action will
|
If no access key credentials are given in the action inputs, this action will
|
||||||
use credentials from the runner environment using the
|
use credentials from the runner environment using the
|
||||||
[default methods for the AWS SDK for Javascript](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html).
|
[default methods for the AWS SDK for Javascript](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html).
|
||||||
|
|
||||||
You can use this action to simply configure the region and account ID in the
|
You can use this action to simply configure the region and account ID in the
|
||||||
environment, and then use the runner's credentials for all AWS API calls made by
|
environment, and then use the runner's credentials for all AWS API calls made by
|
||||||
your Actions workflow:
|
your Actions workflow:
|
||||||
```yaml
|
```yaml
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
```
|
```
|
||||||
@@ -404,7 +406,7 @@ APIs called by your Actions workflow.
|
|||||||
Or, you can use this action to assume a role, and then use the role credentials
|
Or, you can use this action to assume a role, and then use the role credentials
|
||||||
for all AWS API calls made by your Actions workflow:
|
for all AWS API calls made by your Actions workflow:
|
||||||
```yaml
|
```yaml
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
role-to-assume: my-github-actions-role
|
role-to-assume: my-github-actions-role
|
||||||
@@ -427,7 +429,7 @@ environment.
|
|||||||
|
|
||||||
Manually configured proxy:
|
Manually configured proxy:
|
||||||
```yaml
|
```yaml
|
||||||
uses: aws-actions/configure-aws-credentials@v2
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
role-to-assume: my-github-actions-role
|
role-to-assume: my-github-actions-role
|
||||||
@@ -451,6 +453,78 @@ to executing `aws` commands need to have the AWS CLI
|
|||||||
if it's not already present.
|
if it's not already present.
|
||||||
Most [GitHub hosted runner environments](https://github.com/actions/virtual-environments)
|
Most [GitHub hosted runner environments](https://github.com/actions/virtual-environments)
|
||||||
should include the AWS CLI by default.
|
should include the AWS CLI by default.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### AssumeRoleWithWebIdentity (recommended)
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS Credentials
|
||||||
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
|
with:
|
||||||
|
aws-region: us-east-2
|
||||||
|
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||||
|
role-session-name: MySessionName
|
||||||
|
```
|
||||||
|
In this example, the Action will load the OIDC token from the GitHub-provided environment variable and use it to assume the role `arn:aws:iam::123456789100:role/my-github-actions-role` with the session name `MySessionName`.
|
||||||
|
|
||||||
|
### AssumeRole with role previously assumed by action in same workflow
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS Credentials
|
||||||
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
|
with:
|
||||||
|
aws-region: us-east-2
|
||||||
|
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||||
|
role-session-name: MySessionName
|
||||||
|
- name: Configure other AWS Credentials
|
||||||
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
|
with:
|
||||||
|
aws-region: us-east-2
|
||||||
|
role-to-assume: arn:aws:iam::987654321000:role/my-second-role
|
||||||
|
role-session-name: MySessionName
|
||||||
|
role-chaining: true
|
||||||
|
```
|
||||||
|
In this two-step example, the first step will use OIDC to assume the role `arn:aws:iam::123456789100:role/my-github-actions-role` just as in the prior example. Following that, a second step will use this role to assume a different role, `arn:aws:iam::987654321000:role/my-second-role`.
|
||||||
|
|
||||||
|
### AssumeRole with static IAM credentials in repository secrets
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS Credentials
|
||||||
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
|
with:
|
||||||
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
aws-region: us-east-2
|
||||||
|
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
|
||||||
|
role-external-id: ${{ secrets.AWS_ROLE_EXTERNAL_ID }}
|
||||||
|
role-duration-seconds: 1200
|
||||||
|
role-session-name: MySessionName
|
||||||
|
```
|
||||||
|
In this example, the secret `AWS_ROLE_TO_ASSUME` contains a string like `arn:aws:iam::123456789100:role/my-github-actions-role`. To assume a role in the same account as the static credentials, you can simply specify the role name, like `role-to-assume: my-github-actions-role`.
|
||||||
|
|
||||||
|
### Retrieving credentials from step output, AssumeRole with temporary credentials
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS Credentials 1
|
||||||
|
id: creds
|
||||||
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
|
with:
|
||||||
|
aws-region: us-east-2
|
||||||
|
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||||
|
output-credentials: true
|
||||||
|
- name: get caller identity 1
|
||||||
|
run: |
|
||||||
|
aws sts get-caller-identity
|
||||||
|
- name: Configure AWS Credentials 2
|
||||||
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
|
with:
|
||||||
|
aws-region: us-east-2
|
||||||
|
aws-access-key-id: ${{ steps.creds.outputs.aws-access-key-id }}
|
||||||
|
aws-secret-access-key: ${{ steps.creds.outputs.aws-secret-access-key }}
|
||||||
|
aws-session-token: ${{ steps.creds.outputs.aws-session-token }}
|
||||||
|
role-to-assume: arn:aws:iam::123456789100:role/my-other-github-actions-role
|
||||||
|
- name: get caller identity2
|
||||||
|
run: |
|
||||||
|
aws sts get-caller-identity
|
||||||
|
```
|
||||||
|
This example shows that you can reference the fetched credentials as outputs if `output-credentials` is set to true. This example also shows that you can use the `aws-session-token` input in a situation where session tokens are fetched and passed to this action.
|
||||||
|
|
||||||
## License Summary
|
## License Summary
|
||||||
This code is made available under the MIT license.
|
This code is made available under the MIT license.
|
||||||
|
|||||||
11666
THIRD-PARTY
11666
THIRD-PARTY
File diff suppressed because it is too large
Load Diff
119
action.yml
119
action.yml
@@ -1,76 +1,81 @@
|
|||||||
name: 'Configure AWS Credentials For GitHub Actions'
|
|
||||||
description: 'Configure AWS credential and region environment variables for use with the AWS CLI and AWS SDKs'
|
name: '"Configure AWS Credentials" Action for GitHub Actions'
|
||||||
|
description: Configures AWS credentials for use in subsequent steps in a GitHub Action workflow
|
||||||
|
runs:
|
||||||
|
using: node16
|
||||||
|
main: dist/index.js
|
||||||
|
post: dist/cleanup/index.js
|
||||||
branding:
|
branding:
|
||||||
icon: 'cloud'
|
color: orange
|
||||||
color: 'orange'
|
icon: cloud
|
||||||
inputs:
|
inputs:
|
||||||
audience:
|
aws-region:
|
||||||
default: 'sts.amazonaws.com'
|
description: AWS Region, e.g. us-east-2
|
||||||
description: 'The audience to use for the OIDC provider'
|
required: true
|
||||||
|
role-to-assume:
|
||||||
|
description: The Amazon Resource Name (ARN) of the role to assume. Use the provided credentials to assume an IAM role and configure the Actions environment with the assumed role credentials rather than with the provided credentials.
|
||||||
required: false
|
required: false
|
||||||
aws-access-key-id:
|
aws-access-key-id:
|
||||||
description: >-
|
description: AWS Access Key ID. Provide this key if you want to assume a role using access keys rather than a web identity token.
|
||||||
AWS Access Key ID. This input is required if running in the GitHub hosted environment.
|
|
||||||
It is optional if running in a self-hosted environment that already has AWS credentials,
|
|
||||||
for example on an EC2 instance.
|
|
||||||
required: false
|
required: false
|
||||||
aws-secret-access-key:
|
aws-secret-access-key:
|
||||||
description: >-
|
description: AWS Secret Access Key. Required if aws-access-key-id is provided.
|
||||||
AWS Secret Access Key. This input is required if running in the GitHub hosted environment.
|
|
||||||
It is optional if running in a self-hosted environment that already has AWS credentials,
|
|
||||||
for example on an EC2 instance.
|
|
||||||
required: false
|
required: false
|
||||||
aws-session-token:
|
aws-session-token:
|
||||||
description: 'AWS Session Token'
|
description: AWS Session Token.
|
||||||
required: false
|
|
||||||
aws-region:
|
|
||||||
description: 'AWS Region, e.g. us-east-2'
|
|
||||||
required: true
|
|
||||||
mask-aws-account-id:
|
|
||||||
description: >-
|
|
||||||
Whether to set the AWS account ID for these credentials as a secret value,
|
|
||||||
so that it is masked in logs. Valid values are 'true' and 'false'.
|
|
||||||
Defaults to true
|
|
||||||
required: false
|
|
||||||
role-to-assume:
|
|
||||||
description: >-
|
|
||||||
Use the provided credentials to assume an IAM role and configure the Actions
|
|
||||||
environment with the assumed role credentials rather than with the provided
|
|
||||||
credentials
|
|
||||||
required: false
|
required: false
|
||||||
web-identity-token-file:
|
web-identity-token-file:
|
||||||
description: >-
|
description: Use the web identity token file from the provided file system path in order to assume an IAM role using a web identity, e.g. from within an Amazon EKS worker node.
|
||||||
Use the web identity token file from the provided file system path in order to
|
|
||||||
assume an IAM role using a web identity. E.g., from within an Amazon EKS worker node
|
|
||||||
required: false
|
|
||||||
role-duration-seconds:
|
|
||||||
description: "Role duration in seconds (default: 6 hours, 1 hour for OIDC/specified aws-session-token)"
|
|
||||||
required: false
|
|
||||||
role-session-name:
|
|
||||||
description: 'Role session name (default: GitHubActions)'
|
|
||||||
required: false
|
|
||||||
role-external-id:
|
|
||||||
description: 'The external ID of the role to assume'
|
|
||||||
required: false
|
|
||||||
role-skip-session-tagging:
|
|
||||||
description: 'Skip session tagging during role assumption'
|
|
||||||
required: false
|
|
||||||
http-proxy:
|
|
||||||
description: 'Proxy to use for the AWS SDK agent'
|
|
||||||
required: false
|
required: false
|
||||||
role-chaining:
|
role-chaining:
|
||||||
description: 'Use existing credentials from the environment to assume a new role'
|
description: Use existing credentials from the environment to assume a new role, rather than providing credentials as input.
|
||||||
|
required: false
|
||||||
|
audience:
|
||||||
|
description: The audience to use for the OIDC provider
|
||||||
|
required: false
|
||||||
|
default: sts.amazonaws.com
|
||||||
|
http-proxy:
|
||||||
|
description: Proxy to use for the AWS SDK agent
|
||||||
|
required: false
|
||||||
|
mask-aws-account-id:
|
||||||
|
description: Whether to mask the AWS account ID for these credentials as a secret value. By default the account ID will not be masked
|
||||||
|
required: false
|
||||||
|
role-duration-seconds:
|
||||||
|
description: Role duration in seconds. Default is one hour.
|
||||||
|
required: false
|
||||||
|
role-external-id:
|
||||||
|
description: The external ID of the role to assume.
|
||||||
|
required: false
|
||||||
|
role-session-name:
|
||||||
|
description: "Role session name (default: GitHubActions)"
|
||||||
|
required: false
|
||||||
|
role-skip-session-tagging:
|
||||||
|
description: Skip session tagging during role assumption
|
||||||
required: false
|
required: false
|
||||||
inline-session-policy:
|
inline-session-policy:
|
||||||
description: 'Inline session policy'
|
description: Define an inline session policy to use when assuming a role
|
||||||
required: false
|
required: false
|
||||||
managed-session-policies:
|
managed-session-policies:
|
||||||
description: 'List of managed session policies'
|
description: Define a list of managed session policies to use when assuming a role
|
||||||
|
required: false
|
||||||
|
output-credentials:
|
||||||
|
description: Whether to set credentials as step output
|
||||||
|
required: false
|
||||||
|
unset-current-credentials:
|
||||||
|
description: Whether to unset the existing credentials in your runner. May be useful if you run this action multiple times in the same job
|
||||||
|
required: false
|
||||||
|
disable-retry:
|
||||||
|
description: Whether to disable the retry and backoff mechanism when the assume role call fails. By default the retry mechanism is enabled
|
||||||
|
required: false
|
||||||
|
retry-max-attempts:
|
||||||
|
description: The maximum number of attempts it will attempt to retry the assume role call. By default it will retry 12 times
|
||||||
required: false
|
required: false
|
||||||
outputs:
|
outputs:
|
||||||
aws-account-id:
|
aws-account-id:
|
||||||
description: 'The AWS account ID for the provided credentials'
|
description: The AWS account ID for the provided credentials
|
||||||
runs:
|
aws-access-key-id:
|
||||||
using: 'node16'
|
description: The AWS access key ID for the provided credentials
|
||||||
main: 'dist/index.js'
|
aws-secret-access-key:
|
||||||
post: 'dist/cleanup/index.js'
|
description: The AWS secret access key for the provided credentials
|
||||||
|
aws-session-token:
|
||||||
|
description: The AWS session token for the provided credentials
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
const core = require('@actions/core');
|
|
||||||
const cleanup = require('./cleanup.js');
|
|
||||||
|
|
||||||
jest.mock('@actions/core');
|
|
||||||
|
|
||||||
const FAKE_ACCESS_KEY_ID = 'MY-AWS-ACCESS-KEY-ID';
|
|
||||||
const FAKE_SECRET_ACCESS_KEY = 'MY-AWS-SECRET-ACCESS-KEY';
|
|
||||||
const FAKE_SESSION_TOKEN = 'MY-AWS-SESSION-TOKEN';
|
|
||||||
const FAKE_REGION = 'fake-region-1';
|
|
||||||
const ACTION_ENVIRONMENT_VARIABLES = {
|
|
||||||
AWS_ACCESS_KEY_ID: FAKE_ACCESS_KEY_ID,
|
|
||||||
AWS_SECRET_ACCESS_KEY: FAKE_SECRET_ACCESS_KEY,
|
|
||||||
AWS_SESSION_TOKEN: FAKE_SESSION_TOKEN,
|
|
||||||
AWS_DEFAULT_REGION: FAKE_REGION,
|
|
||||||
AWS_REGION: FAKE_REGION,
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Configure AWS Credentials', () => {
|
|
||||||
const OLD_ENV = process.env;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jest.resetModules();
|
|
||||||
process.env = {...OLD_ENV, ...ACTION_ENVIRONMENT_VARIABLES};
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
process.env = OLD_ENV;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('replaces AWS credential and region env vars with empty strings', async () => {
|
|
||||||
await cleanup();
|
|
||||||
expect(core.setFailed).toHaveBeenCalledTimes(0);
|
|
||||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', '');
|
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', '');
|
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', '');
|
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', '');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('error is caught and fails the action', async () => {
|
|
||||||
core.exportVariable.mockReset();
|
|
||||||
core.exportVariable.mockImplementation(() => {
|
|
||||||
throw new Error();
|
|
||||||
});
|
|
||||||
|
|
||||||
await cleanup();
|
|
||||||
|
|
||||||
expect(core.setFailed).toBeCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
18401
dist/cleanup/index.js
generated
vendored
18401
dist/cleanup/index.js
generated
vendored
File diff suppressed because it is too large
Load Diff
14
dist/cleanup/src/CredentialsClient.d.ts
generated
vendored
Normal file
14
dist/cleanup/src/CredentialsClient.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { STSClient } from '@aws-sdk/client-sts';
|
||||||
|
export interface CredentialsClientProps {
|
||||||
|
region?: string;
|
||||||
|
proxyServer?: string;
|
||||||
|
}
|
||||||
|
export declare class CredentialsClient {
|
||||||
|
region?: string;
|
||||||
|
private _stsClient?;
|
||||||
|
private readonly requestHandler?;
|
||||||
|
constructor(props: CredentialsClientProps);
|
||||||
|
get stsClient(): STSClient;
|
||||||
|
validateCredentials(expectedAccessKeyId?: string, roleChaining?: boolean): Promise<void>;
|
||||||
|
private loadCredentials;
|
||||||
|
}
|
||||||
15
dist/cleanup/src/assumeRole.d.ts
generated
vendored
Normal file
15
dist/cleanup/src/assumeRole.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import type { CredentialsClient } from './CredentialsClient';
|
||||||
|
export interface assumeRoleParams {
|
||||||
|
credentialsClient: CredentialsClient;
|
||||||
|
roleToAssume: string;
|
||||||
|
roleDuration: number;
|
||||||
|
roleSessionName: string;
|
||||||
|
roleSkipSessionTagging?: boolean;
|
||||||
|
sourceAccountId?: string;
|
||||||
|
roleExternalId?: string;
|
||||||
|
webIdentityTokenFile?: string;
|
||||||
|
webIdentityToken?: string;
|
||||||
|
inlineSessionPolicy?: string;
|
||||||
|
managedSessionPolicies?: any[];
|
||||||
|
}
|
||||||
|
export declare function assumeRole(params: assumeRoleParams): Promise<import("@aws-sdk/client-sts").AssumeRoleCommandOutput>;
|
||||||
11
dist/cleanup/src/cleanup/index.d.ts
generated
vendored
Normal file
11
dist/cleanup/src/cleanup/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* When the GitHub Actions job is done, clean up any environment variables that
|
||||||
|
* may have been set by the configure-aws-credentials steps in the job.
|
||||||
|
*
|
||||||
|
* Environment variables are not intended to be shared across different jobs in
|
||||||
|
* the same GitHub Actions workflow: GitHub Actions documentation states that
|
||||||
|
* each job runs in a fresh instance. However, doing our own cleanup will
|
||||||
|
* give us additional assurance that these environment variables are not shared
|
||||||
|
* with any other jobs.
|
||||||
|
*/
|
||||||
|
export declare function cleanup(): void;
|
||||||
16
dist/cleanup/src/helpers.d.ts
generated
vendored
Normal file
16
dist/cleanup/src/helpers.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { Credentials } from '@aws-sdk/client-sts';
|
||||||
|
import type { CredentialsClient } from './CredentialsClient';
|
||||||
|
export declare function exportCredentials(creds?: Partial<Credentials>, outputCredentials?: boolean): void;
|
||||||
|
export declare function unsetCredentials(): void;
|
||||||
|
export declare function exportRegion(region: string): void;
|
||||||
|
export declare function exportAccountId(credentialsClient: CredentialsClient, maskAccountId?: boolean): Promise<string>;
|
||||||
|
export declare function sanitizeGitHubVariables(name: string): string;
|
||||||
|
export declare function defaultSleep(ms: number): Promise<unknown>;
|
||||||
|
declare let sleep: typeof defaultSleep;
|
||||||
|
export declare function withsleep(s: typeof sleep): void;
|
||||||
|
export declare function reset(): void;
|
||||||
|
export declare function verifyKeys(creds: Partial<Credentials> | undefined): void;
|
||||||
|
export declare function retryAndBackoff<T>(fn: () => Promise<T>, isRetryable: boolean, maxRetries?: number, retries?: number, base?: number): Promise<T>;
|
||||||
|
export declare function errorMessage(error: unknown): string;
|
||||||
|
export declare function isDefined<T>(i: T | undefined | null): i is T;
|
||||||
|
export {};
|
||||||
1
dist/cleanup/src/index.d.ts
generated
vendored
Normal file
1
dist/cleanup/src/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export declare function run(): Promise<void>;
|
||||||
1
dist/cleanup/test/cleanup.test.d.ts
generated
vendored
Normal file
1
dist/cleanup/test/cleanup.test.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {};
|
||||||
1
dist/cleanup/test/helpers.test.d.ts
generated
vendored
Normal file
1
dist/cleanup/test/helpers.test.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {};
|
||||||
1
dist/cleanup/test/index.test.d.ts
generated
vendored
Normal file
1
dist/cleanup/test/index.test.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {};
|
||||||
64949
dist/index.js
generated
vendored
64949
dist/index.js
generated
vendored
File diff suppressed because one or more lines are too long
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v1-node16
|
uses: aws-actions/configure-aws-credentials@v3
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-1
|
aws-region: us-east-1
|
||||||
## the following creates an ARN based on the values entered into github secrets
|
## the following creates an ARN based on the values entered into github secrets
|
||||||
|
|||||||
429
index.js
429
index.js
@@ -1,429 +0,0 @@
|
|||||||
const core = require('@actions/core');
|
|
||||||
const aws = require('aws-sdk');
|
|
||||||
const assert = require('assert');
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const proxy = require('https-proxy-agent');
|
|
||||||
|
|
||||||
// Use 1hr as role duration when using session token or OIDC
|
|
||||||
// Otherwise, use the max duration of GitHub action (6hr)
|
|
||||||
const MAX_ACTION_RUNTIME = 6 * 3600;
|
|
||||||
const SESSION_ROLE_DURATION = 3600;
|
|
||||||
const DEFAULT_ROLE_DURATION_FOR_OIDC_ROLES = 3600;
|
|
||||||
const USER_AGENT = 'configure-aws-credentials-for-github-actions';
|
|
||||||
const MAX_TAG_VALUE_LENGTH = 256;
|
|
||||||
const SANITIZATION_CHARACTER = '_';
|
|
||||||
const ROLE_SESSION_NAME = 'GitHubActions';
|
|
||||||
const REGION_REGEX = /^[a-z0-9-]+$/g;
|
|
||||||
|
|
||||||
async function assumeRole(params) {
|
|
||||||
// Assume a role to get short-lived credentials using longer-lived credentials.
|
|
||||||
const isDefined = i => !!i;
|
|
||||||
|
|
||||||
const {
|
|
||||||
sourceAccountId,
|
|
||||||
roleToAssume,
|
|
||||||
roleExternalId,
|
|
||||||
roleDurationSeconds,
|
|
||||||
roleSessionName,
|
|
||||||
region,
|
|
||||||
roleSkipSessionTagging,
|
|
||||||
webIdentityTokenFile,
|
|
||||||
webIdentityToken,
|
|
||||||
inlineSessionPolicy,
|
|
||||||
managedSessionPolicies
|
|
||||||
} = params;
|
|
||||||
assert(
|
|
||||||
[roleToAssume, roleDurationSeconds, roleSessionName, region].every(isDefined),
|
|
||||||
"Missing required input when assuming a Role."
|
|
||||||
);
|
|
||||||
|
|
||||||
const {GITHUB_REPOSITORY, GITHUB_WORKFLOW, GITHUB_ACTION, GITHUB_ACTOR, GITHUB_SHA} = process.env;
|
|
||||||
assert(
|
|
||||||
[GITHUB_REPOSITORY, GITHUB_WORKFLOW, GITHUB_ACTION, GITHUB_ACTOR, GITHUB_SHA].every(isDefined),
|
|
||||||
'Missing required environment value. Are you running in GitHub Actions?'
|
|
||||||
);
|
|
||||||
|
|
||||||
const sts = getStsClient(region);
|
|
||||||
|
|
||||||
let roleArn = roleToAssume;
|
|
||||||
if (!roleArn.startsWith('arn:aws')) {
|
|
||||||
// Supports only 'aws' partition. Customers in other partitions ('aws-cn') will need to provide full ARN
|
|
||||||
assert(
|
|
||||||
isDefined(sourceAccountId),
|
|
||||||
"Source Account ID is needed if the Role Name is provided and not the Role Arn."
|
|
||||||
);
|
|
||||||
roleArn = `arn:aws:iam::${sourceAccountId}:role/${roleArn}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const tagArray = [
|
|
||||||
{Key: 'GitHub', Value: 'Actions'},
|
|
||||||
{Key: 'Repository', Value: GITHUB_REPOSITORY},
|
|
||||||
{Key: 'Workflow', Value: sanitizeGithubWorkflowName(GITHUB_WORKFLOW)},
|
|
||||||
{Key: 'Action', Value: GITHUB_ACTION},
|
|
||||||
{Key: 'Actor', Value: sanitizeGithubActor(GITHUB_ACTOR)},
|
|
||||||
{Key: 'Commit', Value: GITHUB_SHA},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isDefined(process.env.GITHUB_REF)) {
|
|
||||||
tagArray.push({Key: 'Branch', Value: process.env.GITHUB_REF});
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleSessionTags = roleSkipSessionTagging ? undefined : tagArray;
|
|
||||||
|
|
||||||
if(roleSessionTags == undefined){
|
|
||||||
core.debug("Role session tagging has been skipped.")
|
|
||||||
} else {
|
|
||||||
core.debug(roleSessionTags.length + " role session tags are being used.")
|
|
||||||
}
|
|
||||||
|
|
||||||
const assumeRoleRequest = {
|
|
||||||
RoleArn: roleArn,
|
|
||||||
RoleSessionName: roleSessionName,
|
|
||||||
DurationSeconds: roleDurationSeconds,
|
|
||||||
Tags: roleSessionTags
|
|
||||||
};
|
|
||||||
|
|
||||||
if (roleExternalId) {
|
|
||||||
assumeRoleRequest.ExternalId = roleExternalId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDefined(inlineSessionPolicy)) {
|
|
||||||
assumeRoleRequest.Policy = inlineSessionPolicy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (managedSessionPolicies && managedSessionPolicies.length) {
|
|
||||||
const policyArns = []
|
|
||||||
for (const managedSessionPolicy of managedSessionPolicies) {
|
|
||||||
policyArns.push({arn: managedSessionPolicy})
|
|
||||||
}
|
|
||||||
assumeRoleRequest.PolicyArns = policyArns;
|
|
||||||
}
|
|
||||||
|
|
||||||
let assumeFunction = sts.assumeRole.bind(sts);
|
|
||||||
|
|
||||||
// These are customizations needed for the GH OIDC Provider
|
|
||||||
if(isDefined(webIdentityToken)) {
|
|
||||||
delete assumeRoleRequest.Tags;
|
|
||||||
|
|
||||||
assumeRoleRequest.WebIdentityToken = webIdentityToken;
|
|
||||||
assumeFunction = sts.assumeRoleWithWebIdentity.bind(sts);
|
|
||||||
} else if(isDefined(webIdentityTokenFile)) {
|
|
||||||
core.debug("webIdentityTokenFile provided. Will call sts:AssumeRoleWithWebIdentity and take session tags from token contents.");
|
|
||||||
delete assumeRoleRequest.Tags;
|
|
||||||
|
|
||||||
const webIdentityTokenFilePath = path.isAbsolute(webIdentityTokenFile) ?
|
|
||||||
webIdentityTokenFile :
|
|
||||||
path.join(process.env.GITHUB_WORKSPACE, webIdentityTokenFile);
|
|
||||||
|
|
||||||
if (!fs.existsSync(webIdentityTokenFilePath)) {
|
|
||||||
throw new Error(`Web identity token file does not exist: ${webIdentityTokenFilePath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
assumeRoleRequest.WebIdentityToken = await fs.promises.readFile(webIdentityTokenFilePath, 'utf8');
|
|
||||||
assumeFunction = sts.assumeRoleWithWebIdentity.bind(sts);
|
|
||||||
} catch(error) {
|
|
||||||
throw new Error(`Web identity token file could not be read: ${error.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return assumeFunction(assumeRoleRequest)
|
|
||||||
.promise()
|
|
||||||
.then(function (data) {
|
|
||||||
return {
|
|
||||||
accessKeyId: data.Credentials.AccessKeyId,
|
|
||||||
secretAccessKey: data.Credentials.SecretAccessKey,
|
|
||||||
sessionToken: data.Credentials.SessionToken,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function sanitizeGithubActor(actor) {
|
|
||||||
// In some circumstances the actor may contain square brackets. For example, if they're a bot ('[bot]')
|
|
||||||
// Square brackets are not allowed in AWS session tags
|
|
||||||
return actor.replace(/\[|\]/g, SANITIZATION_CHARACTER)
|
|
||||||
}
|
|
||||||
|
|
||||||
function sanitizeGithubWorkflowName(name) {
|
|
||||||
// Workflow names can be almost any valid UTF-8 string, but tags are more restrictive.
|
|
||||||
// This replaces anything not conforming to the tag restrictions by inverting the regular expression.
|
|
||||||
// See the AWS documentation for constraint specifics https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html.
|
|
||||||
const nameWithoutSpecialCharacters = name.replace(/[^\p{L}\p{Z}\p{N}_:/=+.-@-]/gu, SANITIZATION_CHARACTER);
|
|
||||||
const nameTruncated = nameWithoutSpecialCharacters.slice(0, MAX_TAG_VALUE_LENGTH)
|
|
||||||
return nameTruncated
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportCredentials(params){
|
|
||||||
// Configure the AWS CLI and AWS SDKs using environment variables and set them as secrets.
|
|
||||||
// Setting the credentials as secrets masks them in Github Actions logs
|
|
||||||
const {accessKeyId, secretAccessKey, sessionToken} = params;
|
|
||||||
|
|
||||||
// AWS_ACCESS_KEY_ID:
|
|
||||||
// Specifies an AWS access key associated with an IAM user or role
|
|
||||||
core.setSecret(accessKeyId);
|
|
||||||
core.exportVariable('AWS_ACCESS_KEY_ID', accessKeyId);
|
|
||||||
|
|
||||||
// AWS_SECRET_ACCESS_KEY:
|
|
||||||
// Specifies the secret key associated with the access key. This is essentially the "password" for the access key.
|
|
||||||
core.setSecret(secretAccessKey);
|
|
||||||
core.exportVariable('AWS_SECRET_ACCESS_KEY', secretAccessKey);
|
|
||||||
|
|
||||||
// AWS_SESSION_TOKEN:
|
|
||||||
// Specifies the session token value that is required if you are using temporary security credentials.
|
|
||||||
if (sessionToken) {
|
|
||||||
core.setSecret(sessionToken);
|
|
||||||
core.exportVariable('AWS_SESSION_TOKEN', sessionToken);
|
|
||||||
} else if (process.env.AWS_SESSION_TOKEN) {
|
|
||||||
// clear session token from previous credentials action
|
|
||||||
core.exportVariable('AWS_SESSION_TOKEN', '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportRegion(region) {
|
|
||||||
// AWS_DEFAULT_REGION and AWS_REGION:
|
|
||||||
// Specifies the AWS Region to send requests to
|
|
||||||
core.exportVariable('AWS_DEFAULT_REGION', region);
|
|
||||||
core.exportVariable('AWS_REGION', region);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function exportAccountId(maskAccountId, region) {
|
|
||||||
// Get the AWS account ID
|
|
||||||
const sts = getStsClient(region);
|
|
||||||
const identity = await sts.getCallerIdentity().promise();
|
|
||||||
const accountId = identity.Account;
|
|
||||||
if (!maskAccountId || maskAccountId.toLowerCase() == 'true') {
|
|
||||||
core.setSecret(accountId);
|
|
||||||
}
|
|
||||||
core.setOutput('aws-account-id', accountId);
|
|
||||||
return accountId;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadCredentials() {
|
|
||||||
// Force the SDK to re-resolve credentials with the default provider chain.
|
|
||||||
//
|
|
||||||
// This action typically sets credentials in the environment via environment variables.
|
|
||||||
// The SDK never refreshes those env-var-based credentials after initial load.
|
|
||||||
// In case there were already env-var creds set in the actions environment when this action
|
|
||||||
// loaded, this action needs to refresh the SDK creds after overwriting those environment variables.
|
|
||||||
//
|
|
||||||
// The credentials object needs to be entirely recreated (instead of simply refreshed),
|
|
||||||
// because the credential object type could change when this action writes env var creds.
|
|
||||||
// For example, the first load could return EC2 instance metadata credentials
|
|
||||||
// in a self-hosted runner, and the second load could return environment credentials
|
|
||||||
// from an assume-role call in this action.
|
|
||||||
aws.config.credentials = null;
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
aws.config.getCredentials((err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
resolve(aws.config.credentials);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function validateCredentials(expectedAccessKeyId, roleChaining) {
|
|
||||||
let credentials;
|
|
||||||
try {
|
|
||||||
credentials = await loadCredentials();
|
|
||||||
|
|
||||||
if (!credentials.accessKeyId) {
|
|
||||||
throw new Error('Access key ID empty after loading credentials');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
throw new Error(`Credentials could not be loaded, please check your action inputs: ${error.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roleChaining) {
|
|
||||||
const actualAccessKeyId = credentials.accessKeyId;
|
|
||||||
|
|
||||||
if (expectedAccessKeyId && expectedAccessKeyId != actualAccessKeyId) {
|
|
||||||
throw new Error('Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getStsClient(region) {
|
|
||||||
return new aws.STS({
|
|
||||||
region,
|
|
||||||
stsRegionalEndpoints: 'regional',
|
|
||||||
customUserAgent: USER_AGENT
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let defaultSleep = function (ms) {
|
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
||||||
};
|
|
||||||
let sleep = defaultSleep;
|
|
||||||
|
|
||||||
// retryAndBackoff retries with exponential backoff the promise if the error isRetryable upto maxRetries time.
|
|
||||||
const retryAndBackoff = async (fn, isRetryable, retries = 0, maxRetries = 12, base = 50) => {
|
|
||||||
try {
|
|
||||||
return await fn();
|
|
||||||
} catch (err) {
|
|
||||||
if (!isRetryable) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
// It's retryable, so sleep and retry.
|
|
||||||
await sleep(Math.random() * (Math.pow(2, retries) * base) );
|
|
||||||
retries += 1;
|
|
||||||
if (retries === maxRetries) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return await retryAndBackoff(fn, isRetryable, retries, maxRetries, base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function configureProxy(proxyServer) {
|
|
||||||
const proxyFromEnv = process.env.HTTP_PROXY || process.env.http_proxy;
|
|
||||||
|
|
||||||
if (proxyFromEnv || proxyServer) {
|
|
||||||
let proxyToSet = null;
|
|
||||||
|
|
||||||
if (proxyServer){
|
|
||||||
console.log(`Setting proxy from actions input: ${proxyServer}`);
|
|
||||||
proxyToSet = proxyServer;
|
|
||||||
} else {
|
|
||||||
console.log(`Setting proxy from environment: ${proxyFromEnv}`);
|
|
||||||
proxyToSet = proxyFromEnv;
|
|
||||||
}
|
|
||||||
|
|
||||||
aws.config.update({
|
|
||||||
httpOptions: { agent: proxy(proxyToSet) }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function run() {
|
|
||||||
try {
|
|
||||||
// Get inputs
|
|
||||||
const accessKeyId = core.getInput('aws-access-key-id', { required: false });
|
|
||||||
const audience = core.getInput('audience', { required: false });
|
|
||||||
const secretAccessKey = core.getInput('aws-secret-access-key', { required: false });
|
|
||||||
const region = core.getInput('aws-region', { required: true });
|
|
||||||
const sessionToken = core.getInput('aws-session-token', { required: false });
|
|
||||||
const maskAccountId = core.getInput('mask-aws-account-id', { required: false });
|
|
||||||
const roleToAssume = core.getInput('role-to-assume', {required: false});
|
|
||||||
const roleExternalId = core.getInput('role-external-id', { required: false });
|
|
||||||
const roleChainingInput = core.getInput('role-chaining', { required: false }) || 'false';
|
|
||||||
const roleChaining = roleChainingInput.toLowerCase() === 'true';
|
|
||||||
let roleDurationSeconds = core.getInput('role-duration-seconds', {required: false})
|
|
||||||
|| (sessionToken && SESSION_ROLE_DURATION)
|
|
||||||
|| (roleChaining && SESSION_ROLE_DURATION)
|
|
||||||
|| MAX_ACTION_RUNTIME;
|
|
||||||
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
|
|
||||||
const roleSkipSessionTaggingInput = core.getInput('role-skip-session-tagging', { required: false }) || 'false';
|
|
||||||
const roleSkipSessionTagging = roleSkipSessionTaggingInput.toLowerCase() === 'true';
|
|
||||||
const webIdentityTokenFile = core.getInput('web-identity-token-file', { required: false });
|
|
||||||
const proxyServer = core.getInput('http-proxy', { required: false });
|
|
||||||
const inlineSessionPolicy = core.getInput('inline-session-policy', { required: false });
|
|
||||||
const managedSessionPolicies = core.getMultilineInput('managed-session-policies', { required: false })
|
|
||||||
|
|
||||||
if (!region.match(REGION_REGEX)) {
|
|
||||||
throw new Error(`Region is not valid: ${region}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
exportRegion(region);
|
|
||||||
|
|
||||||
// This wraps the logic for deciding if we should rely on the GH OIDC provider since we may need to reference
|
|
||||||
// the decision in a few different places. Consolidating it here makes the logic clearer elsewhere.
|
|
||||||
const useGitHubOIDCProvider = () => {
|
|
||||||
// The assumption here is that self-hosted runners won't be populating the `ACTIONS_ID_TOKEN_REQUEST_TOKEN`
|
|
||||||
// environment variable, and they won't be providing a web identity token file or access key either.
|
|
||||||
// V2 of the action might relax this a bit and create an explicit precedence for these so that customers
|
|
||||||
// can provide as much info as they want, and we will follow the established credential loading precedence.
|
|
||||||
|
|
||||||
return roleToAssume && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN && !accessKeyId && !webIdentityTokenFile && !roleChaining
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always export the source credentials and account ID.
|
|
||||||
// The STS client for calling AssumeRole pulls creds from the environment.
|
|
||||||
// Plus, in the assume role case, if the AssumeRole call fails, we want
|
|
||||||
// the source credentials and account ID to already be masked as secrets
|
|
||||||
// in any error messages.
|
|
||||||
if (accessKeyId) {
|
|
||||||
if (!secretAccessKey) {
|
|
||||||
throw new Error("'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided");
|
|
||||||
}
|
|
||||||
|
|
||||||
exportCredentials({accessKeyId, secretAccessKey, sessionToken});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configures proxy
|
|
||||||
configureProxy(proxyServer);
|
|
||||||
|
|
||||||
// Attempt to load credentials from the GitHub OIDC provider.
|
|
||||||
// If a user provides an IAM Role Arn and DOESN'T provide an Access Key Id
|
|
||||||
// The only way to assume the role is via GitHub's OIDC provider.
|
|
||||||
let sourceAccountId;
|
|
||||||
let webIdentityToken;
|
|
||||||
if(useGitHubOIDCProvider()) {
|
|
||||||
webIdentityToken = await core.getIDToken(audience);
|
|
||||||
roleDurationSeconds = core.getInput('role-duration-seconds', {required: false}) || DEFAULT_ROLE_DURATION_FOR_OIDC_ROLES;
|
|
||||||
// We don't validate the credentials here because we don't have them yet when using OIDC.
|
|
||||||
} else {
|
|
||||||
// Regardless of whether any source credentials were provided as inputs,
|
|
||||||
// validate that the SDK can actually pick up credentials. This validates
|
|
||||||
// cases where this action is on a self-hosted runner that doesn't have credentials
|
|
||||||
// configured correctly, and cases where the user intended to provide input
|
|
||||||
// credentials but the secrets inputs resolved to empty strings.
|
|
||||||
await validateCredentials(accessKeyId, roleChaining);
|
|
||||||
|
|
||||||
sourceAccountId = await exportAccountId(maskAccountId, region);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get role credentials if configured to do so
|
|
||||||
if (roleToAssume) {
|
|
||||||
const roleCredentials = await retryAndBackoff(
|
|
||||||
async () => { return await assumeRole({
|
|
||||||
sourceAccountId,
|
|
||||||
region,
|
|
||||||
roleToAssume,
|
|
||||||
roleExternalId,
|
|
||||||
roleDurationSeconds,
|
|
||||||
roleSessionName,
|
|
||||||
roleSkipSessionTagging,
|
|
||||||
webIdentityTokenFile,
|
|
||||||
webIdentityToken,
|
|
||||||
inlineSessionPolicy,
|
|
||||||
managedSessionPolicies
|
|
||||||
}) }, true);
|
|
||||||
exportCredentials(roleCredentials);
|
|
||||||
// We need to validate the credentials in 2 of our use-cases
|
|
||||||
// First: self-hosted runners. If the GITHUB_ACTIONS environment variable
|
|
||||||
// is set to `true` then we are NOT in a self-hosted runner.
|
|
||||||
// Second: Customer provided credentials manually (IAM User keys stored in GH Secrets)
|
|
||||||
if (!process.env.GITHUB_ACTIONS || accessKeyId) {
|
|
||||||
await validateCredentials(roleCredentials.accessKeyId);
|
|
||||||
}
|
|
||||||
await exportAccountId(maskAccountId, region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
core.setFailed(error.message);
|
|
||||||
|
|
||||||
const showStackTrace = process.env.SHOW_STACK_TRACE;
|
|
||||||
|
|
||||||
if (showStackTrace === 'true') {
|
|
||||||
throw(error)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.withSleep = function (s) {
|
|
||||||
sleep = s;
|
|
||||||
};
|
|
||||||
exports.reset = function () {
|
|
||||||
sleep = defaultSleep;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.run = run
|
|
||||||
|
|
||||||
/* istanbul ignore next */
|
|
||||||
if (require.main === module) {
|
|
||||||
run();
|
|
||||||
}
|
|
||||||
1021
index.test.js
1021
index.test.js
File diff suppressed because it is too large
Load Diff
31
jest.config.cjs
Normal file
31
jest.config.cjs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/** @type {import('jest').Config} */
|
||||||
|
const config = {
|
||||||
|
verbose: true,
|
||||||
|
transform: {
|
||||||
|
'^.+\\.m?[tj]sx?$': ['ts-jest'],
|
||||||
|
},
|
||||||
|
testMatch: [
|
||||||
|
'<rootDir>/src/**/__tests__/**/*.ts?(x)',
|
||||||
|
'<rootDir>/(test|src)/**/*(*.)@(spec|test).ts?(x)',
|
||||||
|
'<rootDir>/test/**/*.(test|spec).(js|jsx|ts|tsx)',
|
||||||
|
],
|
||||||
|
clearMocks: true,
|
||||||
|
collectCoverage: true,
|
||||||
|
coverageReporters: ['json', 'lcov', 'clover', 'cobertura', 'text'],
|
||||||
|
coverageDirectory: 'coverage',
|
||||||
|
coveragePathIgnorePatterns: ['/node_modules/'],
|
||||||
|
testPathIgnorePatterns: ['/node_modules/'],
|
||||||
|
watchPathIgnorePatterns: ['/node_modules/'],
|
||||||
|
reporters: [
|
||||||
|
'default',
|
||||||
|
[
|
||||||
|
'jest-junit',
|
||||||
|
{
|
||||||
|
outputDirectory: 'test-reports',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
preset: 'ts-jest/presets/default-legacy',
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = config;
|
||||||
15391
package-lock.json
generated
15391
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
80
package.json
80
package.json
@@ -1,38 +1,64 @@
|
|||||||
{
|
{
|
||||||
"name": "aws-actions-configure-aws-credentials",
|
"name": "configure-aws-credentials",
|
||||||
"version": "2.0.0",
|
"description": "A GitHub Action to configure AWS credentials",
|
||||||
"description": "Configure AWS Credentials",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint **.js",
|
"build": "tsc --project tsconfig.build.json",
|
||||||
"package": "ncc build index.js -o dist && ncc build cleanup.js -o dist/cleanup",
|
"lint": "eslint .",
|
||||||
"test": "npm run lint && jest --coverage --verbose"
|
"package": "npm run build && ncc build --license THIRD-PARTY -o dist && ncc build src/cleanup/index.ts -o dist/cleanup && copyup -E dist/THIRD-PARTY . && del-cli dist/THIRD-PARTY",
|
||||||
|
"test": "npm run lint && jest --verbose"
|
||||||
},
|
},
|
||||||
"repository": {
|
"author": {
|
||||||
"type": "git",
|
"name": "Amazon.com, Inc. or its affiliates",
|
||||||
"url": "git+https://github.com/aws-actions/configure-aws-credentials.git"
|
"url": "https://aws.amazon.com",
|
||||||
|
"organization": true
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@aws-sdk/credential-provider-env": "^3.186.0",
|
||||||
|
"@aws-sdk/property-provider": "^3.188.0",
|
||||||
|
"@jest/globals": "^29.1.2",
|
||||||
|
"@types/jest": "^29.1.2",
|
||||||
|
"@types/node": "^14",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5",
|
||||||
|
"@typescript-eslint/parser": "^5",
|
||||||
|
"@vercel/ncc": "^0.34.0",
|
||||||
|
"aws-sdk-client-mock": "^2.0.0",
|
||||||
|
"copyfiles": "^2.4.1",
|
||||||
|
"del-cli": "^5.0.0",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
"eslint-import-resolver-node": "^0.3.6",
|
||||||
|
"eslint-import-resolver-typescript": "^3.5.1",
|
||||||
|
"eslint-plugin-import": "^2.26.0",
|
||||||
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
|
"jest": "^29.1.2",
|
||||||
|
"jest-junit": "^13",
|
||||||
|
"json-schema": "^0.4.0",
|
||||||
|
"prettier": "^2.7.1",
|
||||||
|
"standard-version": "^9",
|
||||||
|
"ts-jest": "^29.0.3",
|
||||||
|
"typescript": "^4.8.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/core": "^1.10.0",
|
||||||
|
"@aws-sdk/client-sts": "^3",
|
||||||
|
"@aws-sdk/node-http-handler": "^3",
|
||||||
|
"https-proxy-agent": "^5.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"AWS",
|
"aws",
|
||||||
"GitHub",
|
"github",
|
||||||
"Actions",
|
"github-action"
|
||||||
"JavaScript"
|
|
||||||
],
|
],
|
||||||
"author": "AWS",
|
"engines": {
|
||||||
|
"node": ">= 14.0.0"
|
||||||
|
},
|
||||||
|
"main": "build/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"homepage": "https://github.com/aws-actions/configure-aws-credentials",
|
||||||
|
"version": "0.0.0",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/aws-actions/configure-aws-credentials/issues"
|
"url": "https://github.com/aws-actions/configure-aws-credentials/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/aws-actions/configure-aws-credentials#readme",
|
"types": "build/index.d.ts",
|
||||||
"dependencies": {
|
"private": true
|
||||||
"@actions/core": "^1.10.0",
|
|
||||||
"aws-sdk": "^2.1441.0",
|
|
||||||
"axios": "^1.4.0",
|
|
||||||
"https-proxy-agent": "^5.0.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@vercel/ncc": "^0.36.1",
|
|
||||||
"eslint": "^8.47.0",
|
|
||||||
"jest": "^29.6.3"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
70
src/CredentialsClient.ts
Normal file
70
src/CredentialsClient.ts
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import { info } from '@actions/core';
|
||||||
|
import { STSClient } from '@aws-sdk/client-sts';
|
||||||
|
import { NodeHttpHandler } from '@aws-sdk/node-http-handler';
|
||||||
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
||||||
|
import { errorMessage } from './helpers';
|
||||||
|
|
||||||
|
const USER_AGENT = 'configure-aws-credentials-for-github-actions';
|
||||||
|
|
||||||
|
export interface CredentialsClientProps {
|
||||||
|
region?: string;
|
||||||
|
proxyServer?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CredentialsClient {
|
||||||
|
public region?: string;
|
||||||
|
private _stsClient?: STSClient;
|
||||||
|
private readonly requestHandler?: NodeHttpHandler;
|
||||||
|
|
||||||
|
constructor(props: CredentialsClientProps) {
|
||||||
|
this.region = props.region;
|
||||||
|
if (props.proxyServer) {
|
||||||
|
info('Configuring proxy handler for STS client');
|
||||||
|
const handler = new HttpsProxyAgent(props.proxyServer);
|
||||||
|
this.requestHandler = new NodeHttpHandler({
|
||||||
|
httpAgent: handler,
|
||||||
|
httpsAgent: handler,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get stsClient(): STSClient {
|
||||||
|
if (!this._stsClient) {
|
||||||
|
this._stsClient = new STSClient({
|
||||||
|
region: this.region,
|
||||||
|
customUserAgent: USER_AGENT,
|
||||||
|
requestHandler: this.requestHandler ? this.requestHandler : undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this._stsClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async validateCredentials(expectedAccessKeyId?: string, roleChaining?: boolean) {
|
||||||
|
let credentials;
|
||||||
|
try {
|
||||||
|
credentials = await this.loadCredentials();
|
||||||
|
if (!credentials.accessKeyId) {
|
||||||
|
throw new Error('Access key ID empty after loading credentials');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Credentials could not be loaded, please check your action inputs: ${errorMessage(error)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!roleChaining) {
|
||||||
|
const actualAccessKeyId = credentials.accessKeyId;
|
||||||
|
|
||||||
|
if (expectedAccessKeyId && expectedAccessKeyId !== actualAccessKeyId) {
|
||||||
|
throw new Error(
|
||||||
|
'Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async loadCredentials() {
|
||||||
|
const client = new STSClient({
|
||||||
|
requestHandler: this.requestHandler ? this.requestHandler : undefined,
|
||||||
|
});
|
||||||
|
return client.config.credentials();
|
||||||
|
}
|
||||||
|
}
|
||||||
169
src/assumeRole.ts
Normal file
169
src/assumeRole.ts
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
import assert from 'assert';
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import * as core from '@actions/core';
|
||||||
|
import type { AssumeRoleCommandInput, STSClient, Tag } from '@aws-sdk/client-sts';
|
||||||
|
import { AssumeRoleCommand, AssumeRoleWithWebIdentityCommand } from '@aws-sdk/client-sts';
|
||||||
|
import type { CredentialsClient } from './CredentialsClient';
|
||||||
|
import { errorMessage, isDefined, sanitizeGitHubVariables, verifyKeys } from './helpers';
|
||||||
|
|
||||||
|
async function assumeRoleWithOIDC(params: AssumeRoleCommandInput, client: STSClient, webIdentityToken: string) {
|
||||||
|
delete params.Tags;
|
||||||
|
core.info('Assuming role with OIDC');
|
||||||
|
try {
|
||||||
|
const creds = await client.send(
|
||||||
|
new AssumeRoleWithWebIdentityCommand({
|
||||||
|
...params,
|
||||||
|
WebIdentityToken: webIdentityToken,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
verifyKeys(creds.Credentials);
|
||||||
|
return creds;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Could not assume role with OIDC: ${errorMessage(error)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function assumeRoleWithWebIdentityTokenFile(
|
||||||
|
params: AssumeRoleCommandInput,
|
||||||
|
client: STSClient,
|
||||||
|
webIdentityTokenFile: string,
|
||||||
|
workspace: string
|
||||||
|
) {
|
||||||
|
core.debug(
|
||||||
|
'webIdentityTokenFile provided. Will call sts:AssumeRoleWithWebIdentity and take session tags from token contents.'
|
||||||
|
);
|
||||||
|
const webIdentityTokenFilePath = path.isAbsolute(webIdentityTokenFile)
|
||||||
|
? webIdentityTokenFile
|
||||||
|
: path.join(workspace, webIdentityTokenFile);
|
||||||
|
if (!fs.existsSync(webIdentityTokenFilePath)) {
|
||||||
|
throw new Error(`Web identity token file does not exist: ${webIdentityTokenFilePath}`);
|
||||||
|
}
|
||||||
|
core.info('Assuming role with web identity token file');
|
||||||
|
try {
|
||||||
|
const webIdentityToken = fs.readFileSync(webIdentityTokenFilePath, 'utf8');
|
||||||
|
delete params.Tags;
|
||||||
|
const creds = await client.send(
|
||||||
|
new AssumeRoleWithWebIdentityCommand({
|
||||||
|
...params,
|
||||||
|
WebIdentityToken: webIdentityToken,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
verifyKeys(creds.Credentials);
|
||||||
|
return creds;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Could not assume role with web identity token file: ${errorMessage(error)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function assumeRoleWithCredentials(params: AssumeRoleCommandInput, client: STSClient) {
|
||||||
|
core.info('Assuming role with user credentials');
|
||||||
|
try {
|
||||||
|
const creds = await client.send(new AssumeRoleCommand({ ...params }));
|
||||||
|
verifyKeys(creds.Credentials);
|
||||||
|
return creds;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Could not assume role with user credentials: ${errorMessage(error)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface assumeRoleParams {
|
||||||
|
credentialsClient: CredentialsClient;
|
||||||
|
roleToAssume: string;
|
||||||
|
roleDuration: number;
|
||||||
|
roleSessionName: string;
|
||||||
|
roleSkipSessionTagging?: boolean;
|
||||||
|
sourceAccountId?: string;
|
||||||
|
roleExternalId?: string;
|
||||||
|
webIdentityTokenFile?: string;
|
||||||
|
webIdentityToken?: string;
|
||||||
|
inlineSessionPolicy?: string;
|
||||||
|
managedSessionPolicies?: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function assumeRole(params: assumeRoleParams) {
|
||||||
|
const {
|
||||||
|
credentialsClient,
|
||||||
|
sourceAccountId,
|
||||||
|
roleToAssume,
|
||||||
|
roleExternalId,
|
||||||
|
roleDuration,
|
||||||
|
roleSessionName,
|
||||||
|
roleSkipSessionTagging,
|
||||||
|
webIdentityTokenFile,
|
||||||
|
webIdentityToken,
|
||||||
|
inlineSessionPolicy,
|
||||||
|
managedSessionPolicies,
|
||||||
|
} = { ...params };
|
||||||
|
|
||||||
|
// Load GitHub environment variables
|
||||||
|
const { GITHUB_REPOSITORY, GITHUB_WORKFLOW, GITHUB_ACTION, GITHUB_ACTOR, GITHUB_SHA, GITHUB_WORKSPACE } = process.env;
|
||||||
|
if (!GITHUB_REPOSITORY || !GITHUB_WORKFLOW || !GITHUB_ACTION || !GITHUB_ACTOR || !GITHUB_SHA || !GITHUB_WORKSPACE) {
|
||||||
|
throw new Error('Missing required environment variables. Are you running in GitHub Actions?');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load role session tags
|
||||||
|
const tagArray: Tag[] = [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: sanitizeGitHubVariables(GITHUB_WORKFLOW) },
|
||||||
|
{ Key: 'Action', Value: GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: sanitizeGitHubVariables(GITHUB_ACTOR) },
|
||||||
|
{ Key: 'Commit', Value: GITHUB_SHA },
|
||||||
|
];
|
||||||
|
if (process.env['GITHUB_REF']) {
|
||||||
|
tagArray.push({ Key: 'Branch', Value: sanitizeGitHubVariables(process.env['GITHUB_REF']) });
|
||||||
|
}
|
||||||
|
const tags = roleSkipSessionTagging ? undefined : tagArray;
|
||||||
|
if (!tags) {
|
||||||
|
core.debug('Role session tagging has been skipped.');
|
||||||
|
} else {
|
||||||
|
core.debug(`${tags.length} role session tags are being used.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate role ARN from name and account ID (currently only supports `aws` partition)
|
||||||
|
let roleArn = roleToAssume;
|
||||||
|
if (!roleArn.startsWith('arn:aws')) {
|
||||||
|
assert(
|
||||||
|
isDefined(sourceAccountId),
|
||||||
|
'Source Account ID is needed if the Role Name is provided and not the Role Arn.'
|
||||||
|
);
|
||||||
|
roleArn = `arn:aws:iam::${sourceAccountId}:role/${roleArn}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ready common parameters to assume role
|
||||||
|
const commonAssumeRoleParams: AssumeRoleCommandInput = {
|
||||||
|
RoleArn: roleArn,
|
||||||
|
RoleSessionName: roleSessionName,
|
||||||
|
DurationSeconds: roleDuration,
|
||||||
|
Tags: tags ? tags : undefined,
|
||||||
|
ExternalId: roleExternalId ? roleExternalId : undefined,
|
||||||
|
Policy: inlineSessionPolicy ? inlineSessionPolicy : undefined,
|
||||||
|
PolicyArns: managedSessionPolicies?.length ? managedSessionPolicies : undefined,
|
||||||
|
};
|
||||||
|
const keys = Object.keys(commonAssumeRoleParams) as Array<keyof typeof commonAssumeRoleParams>;
|
||||||
|
keys.forEach((k) => commonAssumeRoleParams[k] === undefined && delete commonAssumeRoleParams[k]);
|
||||||
|
|
||||||
|
// Instantiate STS client
|
||||||
|
const stsClient = credentialsClient.stsClient;
|
||||||
|
|
||||||
|
// Assume role using one of three methods
|
||||||
|
switch (true) {
|
||||||
|
case !!webIdentityToken: {
|
||||||
|
return assumeRoleWithOIDC(commonAssumeRoleParams, stsClient, webIdentityToken!);
|
||||||
|
}
|
||||||
|
|
||||||
|
case !!webIdentityTokenFile: {
|
||||||
|
return assumeRoleWithWebIdentityTokenFile(
|
||||||
|
commonAssumeRoleParams,
|
||||||
|
stsClient,
|
||||||
|
webIdentityTokenFile!,
|
||||||
|
GITHUB_WORKSPACE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
return assumeRoleWithCredentials(commonAssumeRoleParams, stsClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
const core = require('@actions/core');
|
import * as core from '@actions/core';
|
||||||
|
import { errorMessage } from '../helpers';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the GitHub Actions job is done, clean up any environment variables that
|
* When the GitHub Actions job is done, clean up any environment variables that
|
||||||
@@ -11,7 +12,7 @@ const core = require('@actions/core');
|
|||||||
* with any other jobs.
|
* with any other jobs.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async function cleanup() {
|
export function cleanup() {
|
||||||
try {
|
try {
|
||||||
// The GitHub Actions toolkit does not have an option to completely unset
|
// The GitHub Actions toolkit does not have an option to completely unset
|
||||||
// environment variables, so we overwrite the current value with an empty
|
// environment variables, so we overwrite the current value with an empty
|
||||||
@@ -22,15 +23,15 @@ async function cleanup() {
|
|||||||
core.exportVariable('AWS_SESSION_TOKEN', '');
|
core.exportVariable('AWS_SESSION_TOKEN', '');
|
||||||
core.exportVariable('AWS_DEFAULT_REGION', '');
|
core.exportVariable('AWS_DEFAULT_REGION', '');
|
||||||
core.exportVariable('AWS_REGION', '');
|
core.exportVariable('AWS_REGION', '');
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
core.setFailed(errorMessage(error));
|
||||||
core.setFailed(error.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* c8 ignore start */
|
||||||
module.exports = cleanup;
|
|
||||||
|
|
||||||
/* istanbul ignore next */
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
cleanup();
|
try {
|
||||||
|
cleanup();
|
||||||
|
} catch (error) {
|
||||||
|
core.setFailed(errorMessage(error));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
142
src/helpers.ts
Normal file
142
src/helpers.ts
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import type { Credentials } from '@aws-sdk/client-sts';
|
||||||
|
import { GetCallerIdentityCommand } from '@aws-sdk/client-sts';
|
||||||
|
import type { CredentialsClient } from './CredentialsClient';
|
||||||
|
|
||||||
|
const MAX_TAG_VALUE_LENGTH = 256;
|
||||||
|
const SANITIZATION_CHARACTER = '_';
|
||||||
|
const SPECIAL_CHARS_REGEX = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]+/;
|
||||||
|
|
||||||
|
// Configure the AWS CLI and AWS SDKs using environment variables and set them as secrets.
|
||||||
|
// Setting the credentials as secrets masks them in Github Actions logs
|
||||||
|
export function exportCredentials(creds?: Partial<Credentials>, outputCredentials?: boolean) {
|
||||||
|
if (creds?.AccessKeyId) {
|
||||||
|
core.setSecret(creds.AccessKeyId);
|
||||||
|
core.exportVariable('AWS_ACCESS_KEY_ID', creds.AccessKeyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creds?.SecretAccessKey) {
|
||||||
|
core.setSecret(creds.SecretAccessKey);
|
||||||
|
core.exportVariable('AWS_SECRET_ACCESS_KEY', creds.SecretAccessKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creds?.SessionToken) {
|
||||||
|
core.setSecret(creds.SessionToken);
|
||||||
|
core.exportVariable('AWS_SESSION_TOKEN', creds.SessionToken);
|
||||||
|
} else if (process.env['AWS_SESSION_TOKEN']) {
|
||||||
|
// clear session token from previous credentials action
|
||||||
|
core.exportVariable('AWS_SESSION_TOKEN', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputCredentials) {
|
||||||
|
if (creds?.AccessKeyId) {
|
||||||
|
core.setOutput('aws-access-key-id', creds.AccessKeyId);
|
||||||
|
}
|
||||||
|
if (creds?.SecretAccessKey) {
|
||||||
|
core.setOutput('aws-secret-access-key', creds.SecretAccessKey);
|
||||||
|
}
|
||||||
|
if (creds?.SessionToken) {
|
||||||
|
core.setOutput('aws-session-token', creds.SessionToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unsetCredentials() {
|
||||||
|
core.exportVariable('AWS_ACCESS_KEY_ID', '');
|
||||||
|
core.exportVariable('AWS_SECRET_ACCESS_KEY', '');
|
||||||
|
core.exportVariable('AWS_SESSION_TOKEN', '');
|
||||||
|
core.exportVariable('AWS_REGION', '');
|
||||||
|
core.exportVariable('AWS_DEFAULT_REGION', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function exportRegion(region: string) {
|
||||||
|
core.exportVariable('AWS_DEFAULT_REGION', region);
|
||||||
|
core.exportVariable('AWS_REGION', region);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtains account ID from STS Client and sets it as output
|
||||||
|
export async function exportAccountId(credentialsClient: CredentialsClient, maskAccountId?: boolean) {
|
||||||
|
const client = credentialsClient.stsClient;
|
||||||
|
const identity = await client.send(new GetCallerIdentityCommand({}));
|
||||||
|
const accountId = identity.Account;
|
||||||
|
if (!accountId) {
|
||||||
|
throw new Error('Could not get Account ID from STS. Did you set credentials?');
|
||||||
|
}
|
||||||
|
if (maskAccountId) {
|
||||||
|
core.setSecret(accountId);
|
||||||
|
}
|
||||||
|
core.setOutput('aws-account-id', accountId);
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tags have a more restrictive set of acceptable characters than GitHub environment variables can.
|
||||||
|
// This replaces anything not conforming to the tag restrictions by inverting the regular expression.
|
||||||
|
// See the AWS documentation for constraint specifics https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html.
|
||||||
|
export function sanitizeGitHubVariables(name: string) {
|
||||||
|
const nameWithoutSpecialCharacters = name.replace(/[^\p{L}\p{Z}\p{N}_.:/=+\-@]/gu, SANITIZATION_CHARACTER);
|
||||||
|
const nameTruncated = nameWithoutSpecialCharacters.slice(0, MAX_TAG_VALUE_LENGTH);
|
||||||
|
return nameTruncated;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function defaultSleep(ms: number) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
let sleep = defaultSleep;
|
||||||
|
|
||||||
|
export function withsleep(s: typeof sleep) {
|
||||||
|
sleep = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function reset() {
|
||||||
|
sleep = defaultSleep;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function verifyKeys(creds: Partial<Credentials> | undefined) {
|
||||||
|
if (!creds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (creds.AccessKeyId) {
|
||||||
|
if (SPECIAL_CHARS_REGEX.test(creds.AccessKeyId)) {
|
||||||
|
throw new Error('AccessKeyId contains special characters.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (creds.SecretAccessKey) {
|
||||||
|
if (SPECIAL_CHARS_REGEX.test(creds.SecretAccessKey)) {
|
||||||
|
throw new Error('SecretAccessKey contains special characters.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retries the promise with exponential backoff if the error isRetryable up to maxRetries time.
|
||||||
|
export async function retryAndBackoff<T>(
|
||||||
|
fn: () => Promise<T>,
|
||||||
|
isRetryable: boolean,
|
||||||
|
maxRetries = 12,
|
||||||
|
retries = 0,
|
||||||
|
base = 50
|
||||||
|
): Promise<T> {
|
||||||
|
try {
|
||||||
|
return await fn();
|
||||||
|
} catch (err) {
|
||||||
|
if (!isRetryable) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
// It's retryable, so sleep and retry.
|
||||||
|
await sleep(Math.random() * (Math.pow(2, retries) * base));
|
||||||
|
retries += 1;
|
||||||
|
if (retries >= maxRetries) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
return await retryAndBackoff(fn, isRetryable, maxRetries, retries, base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* c8 ignore start */
|
||||||
|
export function errorMessage(error: unknown) {
|
||||||
|
return error instanceof Error ? error.message : String(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isDefined<T>(i: T | undefined | null): i is T {
|
||||||
|
return i !== undefined && i !== null;
|
||||||
|
}
|
||||||
|
/* c8 ignore stop */
|
||||||
182
src/index.ts
Normal file
182
src/index.ts
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import { assumeRole } from './assumeRole';
|
||||||
|
import { CredentialsClient } from './CredentialsClient';
|
||||||
|
import {
|
||||||
|
errorMessage,
|
||||||
|
retryAndBackoff,
|
||||||
|
exportRegion,
|
||||||
|
exportCredentials,
|
||||||
|
exportAccountId,
|
||||||
|
unsetCredentials,
|
||||||
|
} from './helpers';
|
||||||
|
|
||||||
|
const DEFAULT_ROLE_DURATION = 3600; // One hour (seconds)
|
||||||
|
const ROLE_SESSION_NAME = 'GitHubActions';
|
||||||
|
const REGION_REGEX = /^[a-z0-9-]+$/g;
|
||||||
|
|
||||||
|
export async function run() {
|
||||||
|
try {
|
||||||
|
// Get inputs
|
||||||
|
const AccessKeyId = core.getInput('aws-access-key-id', { required: false });
|
||||||
|
const SecretAccessKey = core.getInput('aws-secret-access-key', { required: false });
|
||||||
|
const sessionTokenInput = core.getInput('aws-session-token', { required: false });
|
||||||
|
const SessionToken = sessionTokenInput === '' ? undefined : sessionTokenInput;
|
||||||
|
const region = core.getInput('aws-region', { required: true });
|
||||||
|
const roleToAssume = core.getInput('role-to-assume', { required: false });
|
||||||
|
const audience = core.getInput('audience', { required: false });
|
||||||
|
const maskAccountIdInput = core.getInput('mask-aws-account-id', { required: false }) || 'false';
|
||||||
|
const maskAccountId = maskAccountIdInput.toLowerCase() === 'true';
|
||||||
|
const roleExternalId = core.getInput('role-external-id', { required: false });
|
||||||
|
const webIdentityTokenFile = core.getInput('web-identity-token-file', { required: false });
|
||||||
|
const roleDuration = parseInt(core.getInput('role-duration-seconds', { required: false })) || DEFAULT_ROLE_DURATION;
|
||||||
|
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
|
||||||
|
const roleSkipSessionTaggingInput = core.getInput('role-skip-session-tagging', { required: false }) || 'false';
|
||||||
|
const roleSkipSessionTagging = roleSkipSessionTaggingInput.toLowerCase() === 'true';
|
||||||
|
const proxyServer = core.getInput('http-proxy', { required: false });
|
||||||
|
const inlineSessionPolicy = core.getInput('inline-session-policy', { required: false });
|
||||||
|
const managedSessionPoliciesInput = core.getMultilineInput('managed-session-policies', { required: false });
|
||||||
|
const managedSessionPolicies: any[] = [];
|
||||||
|
const roleChainingInput = core.getInput('role-chaining', { required: false }) || 'false';
|
||||||
|
const roleChaining = roleChainingInput.toLowerCase() === 'true';
|
||||||
|
const outputCredentialsInput = core.getInput('output-credentials', { required: false }) || 'false';
|
||||||
|
const outputCredentials = outputCredentialsInput.toLowerCase() === 'true';
|
||||||
|
const unsetCurrentCredentialsInput = core.getInput('unset-current-credentials', { required: false }) || 'false';
|
||||||
|
const unsetCurrentCredentials = unsetCurrentCredentialsInput.toLowerCase() === 'true';
|
||||||
|
const disableRetryInput = core.getInput('disable-retry', { required: false }) || 'false';
|
||||||
|
const disableRetry = disableRetryInput.toLowerCase() === 'true';
|
||||||
|
let maxRetries = parseInt(core.getInput('retry-max-attempts', { required: false })) || 12;
|
||||||
|
if (maxRetries < 1) {
|
||||||
|
maxRetries = 1;
|
||||||
|
}
|
||||||
|
for (const managedSessionPolicy of managedSessionPoliciesInput) {
|
||||||
|
managedSessionPolicies.push({ arn: managedSessionPolicy });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logic to decide whether to attempt to use OIDC or not
|
||||||
|
const useGitHubOIDCProvider = () => {
|
||||||
|
// The `ACTIONS_ID_TOKEN_REQUEST_TOKEN` environment variable is set when the `id-token` permission is granted.
|
||||||
|
// This is necessary to authenticate with OIDC, but not strictly set just for OIDC. If it is not set and all other
|
||||||
|
// checks pass, it is likely but not guaranteed that the user needs but lacks this permission in their workflow.
|
||||||
|
// So, we will log a warning when it is the only piece absent
|
||||||
|
if (
|
||||||
|
!!roleToAssume &&
|
||||||
|
!webIdentityTokenFile &&
|
||||||
|
!AccessKeyId &&
|
||||||
|
!process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] &&
|
||||||
|
!roleChaining
|
||||||
|
) {
|
||||||
|
core.info(
|
||||||
|
'It looks like you might be trying to authenticate with OIDC. Did you mean to set the `id-token` permission?'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
!!roleToAssume &&
|
||||||
|
!!process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] &&
|
||||||
|
!AccessKeyId &&
|
||||||
|
!webIdentityTokenFile &&
|
||||||
|
!roleChaining
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (unsetCurrentCredentials) {
|
||||||
|
unsetCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!region.match(REGION_REGEX)) {
|
||||||
|
throw new Error(`Region is not valid: ${region}`);
|
||||||
|
}
|
||||||
|
exportRegion(region);
|
||||||
|
|
||||||
|
// Instantiate credentials client
|
||||||
|
const credentialsClient = new CredentialsClient({ region, proxyServer });
|
||||||
|
let sourceAccountId: string;
|
||||||
|
let webIdentityToken: string;
|
||||||
|
|
||||||
|
// If OIDC is being used, generate token
|
||||||
|
// Else, export credentials provided as input
|
||||||
|
if (useGitHubOIDCProvider()) {
|
||||||
|
try {
|
||||||
|
webIdentityToken = await retryAndBackoff(
|
||||||
|
async () => {
|
||||||
|
return core.getIDToken(audience);
|
||||||
|
},
|
||||||
|
!disableRetry,
|
||||||
|
maxRetries
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`getIDToken call failed: ${errorMessage(error)}`);
|
||||||
|
}
|
||||||
|
} else if (AccessKeyId) {
|
||||||
|
if (!SecretAccessKey) {
|
||||||
|
throw new Error("'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided");
|
||||||
|
}
|
||||||
|
// The STS client for calling AssumeRole pulls creds from the environment.
|
||||||
|
// Plus, in the assume role case, if the AssumeRole call fails, we want
|
||||||
|
// the source credentials to already be masked as secrets
|
||||||
|
// in any error messages.
|
||||||
|
exportCredentials({ AccessKeyId, SecretAccessKey, SessionToken });
|
||||||
|
} else if (!webIdentityTokenFile && !roleChaining) {
|
||||||
|
throw new Error('Could not determine how to assume credentials. Please check your inputs and try again.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AccessKeyId || roleChaining) {
|
||||||
|
// Validate that the SDK can actually pick up credentials.
|
||||||
|
// This validates cases where this action is using existing environment credentials,
|
||||||
|
// and cases where the user intended to provide input credentials but the secrets inputs resolved to empty strings.
|
||||||
|
await credentialsClient.validateCredentials(AccessKeyId, roleChaining);
|
||||||
|
sourceAccountId = await exportAccountId(credentialsClient, maskAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get role credentials if configured to do so
|
||||||
|
if (roleToAssume) {
|
||||||
|
const roleCredentials = await retryAndBackoff(
|
||||||
|
async () => {
|
||||||
|
return assumeRole({
|
||||||
|
credentialsClient,
|
||||||
|
sourceAccountId,
|
||||||
|
roleToAssume,
|
||||||
|
roleExternalId,
|
||||||
|
roleDuration,
|
||||||
|
roleSessionName,
|
||||||
|
roleSkipSessionTagging,
|
||||||
|
webIdentityTokenFile,
|
||||||
|
webIdentityToken,
|
||||||
|
inlineSessionPolicy,
|
||||||
|
managedSessionPolicies,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
!disableRetry,
|
||||||
|
maxRetries
|
||||||
|
);
|
||||||
|
core.info(`Authenticated as assumedRoleId ${roleCredentials.AssumedRoleUser!.AssumedRoleId!}`);
|
||||||
|
exportCredentials(roleCredentials.Credentials, outputCredentials);
|
||||||
|
// We need to validate the credentials in 2 of our use-cases
|
||||||
|
// First: self-hosted runners. If the GITHUB_ACTIONS environment variable
|
||||||
|
// is set to `true` then we are NOT in a self-hosted runner.
|
||||||
|
// Second: Customer provided credentials manually (IAM User keys stored in GH Secrets)
|
||||||
|
if (!process.env['GITHUB_ACTIONS'] || AccessKeyId) {
|
||||||
|
await credentialsClient.validateCredentials(roleCredentials.Credentials?.AccessKeyId);
|
||||||
|
}
|
||||||
|
await exportAccountId(credentialsClient, maskAccountId);
|
||||||
|
} else {
|
||||||
|
core.info('Proceeding with IAM user credentials');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
core.setFailed(errorMessage(error));
|
||||||
|
|
||||||
|
const showStackTrace = process.env['SHOW_STACK_TRACE'];
|
||||||
|
|
||||||
|
if (showStackTrace === 'true') {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* c8 ignore start */
|
||||||
|
if (require.main === module) {
|
||||||
|
(async () => {
|
||||||
|
await run();
|
||||||
|
})().catch((error) => {
|
||||||
|
core.setFailed(errorMessage(error));
|
||||||
|
});
|
||||||
|
}
|
||||||
52
test/cleanup.test.ts
Normal file
52
test/cleanup.test.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import { cleanup } from '../src/cleanup';
|
||||||
|
|
||||||
|
const FAKE_ACCESS_KEY_ID = 'MY-AWS-ACCESS-KEY-ID';
|
||||||
|
const FAKE_SECRET_ACCESS_KEY = 'MY-AWS-SECRET-ACCESS-KEY';
|
||||||
|
const FAKE_SESSION_TOKEN = 'MY-AWS-SESSION-TOKEN';
|
||||||
|
const FAKE_REGION = 'fake-region-1';
|
||||||
|
const ACTION_ENVIRONMENT_VARIABLES = {
|
||||||
|
AWS_ACCESS_KEY_ID: FAKE_ACCESS_KEY_ID,
|
||||||
|
AWS_SECRET_ACCESS_KEY: FAKE_SECRET_ACCESS_KEY,
|
||||||
|
AWS_SESSION_TOKEN: FAKE_SESSION_TOKEN,
|
||||||
|
AWS_DEFAULT_REGION: FAKE_REGION,
|
||||||
|
AWS_REGION: FAKE_REGION,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Configure AWS Credentials', () => {
|
||||||
|
const OLD_ENV = process.env;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
jest.spyOn(core, 'exportVariable').mockImplementation();
|
||||||
|
jest.spyOn(core, 'setSecret').mockImplementation();
|
||||||
|
jest.spyOn(core, 'setOutput').mockImplementation();
|
||||||
|
jest.spyOn(core, 'setFailed').mockImplementation();
|
||||||
|
process.env = { ...OLD_ENV, ...ACTION_ENVIRONMENT_VARIABLES };
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = OLD_ENV;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('replaces AWS credential and region env vars with empty strings', () => {
|
||||||
|
cleanup();
|
||||||
|
expect(core.setFailed).toHaveBeenCalledTimes(0);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', '');
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', '');
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', '');
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('error is caught and fails the action', () => {
|
||||||
|
jest.spyOn(core, 'exportVariable').mockImplementation(() => {
|
||||||
|
throw new Error();
|
||||||
|
});
|
||||||
|
|
||||||
|
cleanup();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
26
test/helpers.test.ts
Normal file
26
test/helpers.test.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import * as helpers from '../src/helpers';
|
||||||
|
describe('helpers', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removes brackets from GitHub Actor', () => {
|
||||||
|
expect(helpers.sanitizeGitHubVariables('foo[bot]')).toEqual('foo_bot_');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removes special characters from worflow names', () => {
|
||||||
|
expect(helpers.sanitizeGitHubVariables('sdf234@#$%$^&*()_+{}|:"<>?')).toEqual('sdf234@__________+___:____');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('can sleep', () => {
|
||||||
|
const sleep = helpers.defaultSleep(10);
|
||||||
|
expect(Promise.race([sleep, new Promise((_res, rej) => setTimeout(rej, 20))])).resolves;
|
||||||
|
});
|
||||||
|
|
||||||
|
test("backoff function doesn't retry non-retryable errors", async () => {
|
||||||
|
const fn = jest.fn().mockRejectedValue('i am not retryable');
|
||||||
|
await expect(helpers.retryAndBackoff(fn, false)).rejects.toMatch('i am not retryable');
|
||||||
|
expect(fn).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
847
test/index.test.ts
Normal file
847
test/index.test.ts
Normal file
@@ -0,0 +1,847 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import {
|
||||||
|
AssumeRoleCommand,
|
||||||
|
AssumeRoleWithWebIdentityCommand,
|
||||||
|
GetCallerIdentityCommand,
|
||||||
|
STSClient,
|
||||||
|
} from '@aws-sdk/client-sts';
|
||||||
|
import { fromEnv } from '@aws-sdk/credential-provider-env';
|
||||||
|
import { CredentialsProviderError } from '@aws-sdk/property-provider';
|
||||||
|
import { mockClient } from 'aws-sdk-client-mock';
|
||||||
|
import { withsleep, reset } from '../src/helpers';
|
||||||
|
import { run } from '../src/index';
|
||||||
|
|
||||||
|
// #region
|
||||||
|
const FAKE_ACCESS_KEY_ID = 'MYAWSACCESSKEYID';
|
||||||
|
const FAKE_SECRET_ACCESS_KEY = 'MYAWSSECRETACCESSKEY';
|
||||||
|
const FAKE_SESSION_TOKEN = 'MYAWSSESSIONTOKEN';
|
||||||
|
const FAKE_STS_ACCESS_KEY_ID = 'STSAWSACCESSKEYID';
|
||||||
|
const FAKE_STS_SECRET_ACCESS_KEY = 'STSAWSSECRETACCESSKEY';
|
||||||
|
const FAKE_STS_SESSION_TOKEN = 'STSAWSSESSIONTOKEN';
|
||||||
|
const FAKE_ASSUMED_ROLE_ID = 'AROAFAKEASSUMEDROLEID';
|
||||||
|
const FAKE_REGION = 'fake-region-1';
|
||||||
|
const FAKE_ACCOUNT_ID = '123456789012';
|
||||||
|
const FAKE_ROLE_ACCOUNT_ID = '111111111111';
|
||||||
|
const ROLE_NAME = 'MY-ROLE';
|
||||||
|
const ROLE_ARN = 'arn:aws:iam::111111111111:role/MY-ROLE';
|
||||||
|
const MANAGED_SESSION_POLICY_INPUT = [
|
||||||
|
'arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess',
|
||||||
|
'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess',
|
||||||
|
];
|
||||||
|
const ENVIRONMENT_VARIABLE_OVERRIDES = {
|
||||||
|
SHOW_STACK_TRACE: 'false',
|
||||||
|
GITHUB_REPOSITORY: 'MY-REPOSITORY-NAME',
|
||||||
|
GITHUB_WORKFLOW: 'MY-WORKFLOW-ID',
|
||||||
|
GITHUB_ACTION: 'MY-ACTION-NAME',
|
||||||
|
GITHUB_ACTOR: 'MY-USERNAME[bot]',
|
||||||
|
GITHUB_SHA: 'MY-COMMIT-ID',
|
||||||
|
GITHUB_REF: 'MY-BRANCH',
|
||||||
|
GITHUB_WORKSPACE: '/home/github',
|
||||||
|
};
|
||||||
|
const GITHUB_ACTOR_SANITIZED = 'MY-USERNAME_bot_';
|
||||||
|
const CREDS_INPUTS = {
|
||||||
|
'aws-access-key-id': FAKE_ACCESS_KEY_ID,
|
||||||
|
'aws-secret-access-key': FAKE_SECRET_ACCESS_KEY,
|
||||||
|
};
|
||||||
|
const DEFAULT_INPUTS = {
|
||||||
|
...CREDS_INPUTS,
|
||||||
|
'aws-session-token': FAKE_SESSION_TOKEN,
|
||||||
|
'aws-region': FAKE_REGION,
|
||||||
|
};
|
||||||
|
const ASSUME_ROLE_INPUTS = { ...CREDS_INPUTS, 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION };
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
const mockedSTS = mockClient(STSClient);
|
||||||
|
function mockGetInput(requestResponse: Record<string, string>) {
|
||||||
|
return function (name: string, _options: unknown): string {
|
||||||
|
return requestResponse[name]!;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function mockGetMultilineInput(requestResponse: Record<string, string[]>) {
|
||||||
|
return function (name: string, _options: unknown): string[] {
|
||||||
|
return requestResponse[name]!;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
|
jest.mock('fs', () => ({
|
||||||
|
...jest.requireActual('fs'),
|
||||||
|
existsSync: jest.fn(() => true),
|
||||||
|
readFileSync: jest.fn(() => 'testpayload'),
|
||||||
|
}));
|
||||||
|
jest.mock('@aws-sdk/credential-provider-env', () => ({
|
||||||
|
// This is the actual implementation in the SDK ^_^
|
||||||
|
fromEnv: jest.fn().mockImplementation(() => () => {
|
||||||
|
const accessKeyId = process.env['AWS_ACCESS_KEY_ID'];
|
||||||
|
const secretAccessKey = process.env['AWS_SECRET_ACCESS_KEY'];
|
||||||
|
const sessionToken = process.env['AWS_SESSION_TOKEN'];
|
||||||
|
const expiration = process.env['AWS_CREDENTIAL_EXPIRATION'];
|
||||||
|
return {
|
||||||
|
accessKeyId,
|
||||||
|
secretAccessKey,
|
||||||
|
sessionToken,
|
||||||
|
expiration,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('Configure AWS Credentials', () => {
|
||||||
|
const OLD_ENV = process.env;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetModules();
|
||||||
|
process.env = { ...OLD_ENV, ...ENVIRONMENT_VARIABLE_OVERRIDES };
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockedSTS.reset();
|
||||||
|
(fromEnv as jest.Mock).mockReset();
|
||||||
|
jest.spyOn(core, 'getMultilineInput').mockImplementation(() => []);
|
||||||
|
jest.spyOn(core, 'getIDToken').mockImplementation(async () => Promise.resolve('testtoken'));
|
||||||
|
jest.spyOn(core, 'exportVariable').mockImplementation();
|
||||||
|
jest.spyOn(core, 'setSecret').mockImplementation();
|
||||||
|
jest.spyOn(core, 'setOutput').mockImplementation();
|
||||||
|
jest.spyOn(core, 'setFailed').mockImplementation();
|
||||||
|
jest.spyOn(core, 'debug').mockImplementation();
|
||||||
|
jest.spyOn(core, 'info').mockImplementation((string) => {
|
||||||
|
return string;
|
||||||
|
});
|
||||||
|
(fromEnv as jest.Mock)
|
||||||
|
.mockImplementationOnce(() => () => ({
|
||||||
|
accessKeyId: FAKE_ACCESS_KEY_ID,
|
||||||
|
secretAccessKey: FAKE_SECRET_ACCESS_KEY,
|
||||||
|
}))
|
||||||
|
.mockImplementationOnce(() => () => ({
|
||||||
|
accessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||||
|
secretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||||
|
}));
|
||||||
|
mockedSTS
|
||||||
|
.on(GetCallerIdentityCommand)
|
||||||
|
.resolvesOnce({ Account: FAKE_ACCOUNT_ID })
|
||||||
|
.resolvesOnce({ Account: FAKE_ROLE_ACCOUNT_ID });
|
||||||
|
mockedSTS.on(AssumeRoleCommand).resolves({
|
||||||
|
Credentials: {
|
||||||
|
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||||
|
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||||
|
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||||
|
Expiration: new Date(8640000000000000),
|
||||||
|
},
|
||||||
|
AssumedRoleUser: {
|
||||||
|
AssumedRoleId: FAKE_ASSUMED_ROLE_ID,
|
||||||
|
Arn: ROLE_ARN,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
mockedSTS.on(AssumeRoleWithWebIdentityCommand).resolves({
|
||||||
|
Credentials: {
|
||||||
|
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||||
|
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||||
|
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||||
|
Expiration: new Date(8640000000000000),
|
||||||
|
},
|
||||||
|
AssumedRoleUser: {
|
||||||
|
AssumedRoleId: FAKE_ASSUMED_ROLE_ID,
|
||||||
|
Arn: ROLE_ARN,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
withsleep(async () => {
|
||||||
|
return Promise.resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
process.env = OLD_ENV;
|
||||||
|
reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('exports env vars', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledTimes(3);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', FAKE_SESSION_TOKEN);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SESSION_TOKEN);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
|
||||||
|
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('action fails when github env vars are not set', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||||
|
delete process.env['GITHUB_SHA'];
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(
|
||||||
|
'Missing required environment variables. Are you running in GitHub Actions?'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('action does not require GITHUB_REF env var', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||||
|
delete process.env['GITHUB_REF'];
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('action with no accessible credentials fails', async () => {
|
||||||
|
const mockInputs = { 'aws-region': FAKE_REGION };
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||||
|
(fromEnv as jest.Mock).mockReset();
|
||||||
|
(fromEnv as jest.Mock).mockImplementation(() => () => {
|
||||||
|
throw new CredentialsProviderError('test');
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(
|
||||||
|
'Could not determine how to assume credentials. Please check your inputs and try again.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('action with empty credentials fails', async () => {
|
||||||
|
const mockInputs = { 'aws-region': FAKE_REGION };
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||||
|
(fromEnv as jest.Mock).mockReset();
|
||||||
|
(fromEnv as jest.Mock).mockImplementation(
|
||||||
|
() => async () => Promise.resolve({ accessKeyId: '', secretAccessKey: '' })
|
||||||
|
);
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(
|
||||||
|
'Could not determine how to assume credentials. Please check your inputs and try again.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('action fails when credentials are not set in the SDK correctly', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||||
|
(fromEnv as jest.Mock).mockReset();
|
||||||
|
(fromEnv as jest.Mock).mockImplementationOnce(() => async () => Promise.resolve({ accessKeyId: '123' }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(
|
||||||
|
'Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('session token is optional', async () => {
|
||||||
|
const mockInputs = { ...CREDS_INPUTS, 'aws-region': 'eu-west-1' };
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledTimes(2);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
|
||||||
|
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('existing env var creds are cleared', async () => {
|
||||||
|
const mockInputs = { ...CREDS_INPUTS, 'aws-region': 'eu-west-1' };
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||||
|
process.env['AWS_ACCESS_KEY_ID'] = 'foo';
|
||||||
|
process.env['AWS_SECRET_ACCESS_KEY'] = 'bar';
|
||||||
|
process.env['AWS_SESSION_TOKEN'] = 'helloworld';
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledTimes(2);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
|
||||||
|
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('validates region name', async () => {
|
||||||
|
const mockInputs = { ...CREDS_INPUTS, 'aws-region': '$AWS_REGION' };
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith('Region is not valid: $AWS_REGION');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('throws error if access key id exists but missing secret access key', async () => {
|
||||||
|
const inputsWIthoutSecretKey = { ...DEFAULT_INPUTS };
|
||||||
|
//@ts-expect-error deleting a required property to test failure condition
|
||||||
|
delete inputsWIthoutSecretKey['aws-secret-access-key'];
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(inputsWIthoutSecretKey));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(
|
||||||
|
"'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('can opt into masking account ID', async () => {
|
||||||
|
const mockInputs = { ...CREDS_INPUTS, 'aws-region': 'us-east-1', 'mask-aws-account-id': 'true' };
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(mockInputs));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)).toHaveLength(0);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'us-east-1');
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'us-east-1');
|
||||||
|
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||||
|
expect(core.setSecret).toHaveBeenCalledTimes(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('error is caught by core.setFailed and caught', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||||
|
mockedSTS.reset();
|
||||||
|
mockedSTS.on(GetCallerIdentityCommand).rejects();
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption tags', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption duration provided', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-duration-seconds': '5' }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 5,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption session name provided', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-session-name': 'MySessionName' }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'MySessionName',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role name provided instead of ARN', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...CREDS_INPUTS, 'role-to-assume': ROLE_NAME, 'aws-region': FAKE_REGION }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: 'arn:aws:iam::123456789012:role/MY-ROLE',
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('web identity token file provided with absolute path', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(
|
||||||
|
mockGetInput({
|
||||||
|
'role-to-assume': ROLE_ARN,
|
||||||
|
'aws-region': FAKE_REGION,
|
||||||
|
'web-identity-token-file': '/fake/token/file',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
WebIdentityToken: 'testpayload',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('web identity token file provided with relative path', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(
|
||||||
|
mockGetInput({
|
||||||
|
'role-to-assume': ROLE_ARN,
|
||||||
|
'aws-region': FAKE_REGION,
|
||||||
|
'web-identity-token-file': 'fake/token/file',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
WebIdentityToken: 'testpayload',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('only role arn and region provided to use GH OIDC Token', async () => {
|
||||||
|
process.env['GITHUB_ACTIONS'] = 'true';
|
||||||
|
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = 'test-token';
|
||||||
|
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
WebIdentityToken: 'testtoken',
|
||||||
|
});
|
||||||
|
expect(core.getIDToken).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getIDToken call retries when failing', async () => {
|
||||||
|
process.env['GITHUB_ACTIONS'] = 'true';
|
||||||
|
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = 'test-token';
|
||||||
|
jest.spyOn(core, 'getIDToken').mockImplementation(() => {
|
||||||
|
throw new Error('test error');
|
||||||
|
});
|
||||||
|
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.getIDToken).toHaveBeenCalledTimes(12);
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith('getIDToken call failed: test error');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('GH OIDC With custom role duration', async () => {
|
||||||
|
const CUSTOM_ROLE_DURATION = '1234';
|
||||||
|
process.env['GITHUB_ACTIONS'] = 'true';
|
||||||
|
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = 'test-token';
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(
|
||||||
|
mockGetInput({
|
||||||
|
'role-to-assume': ROLE_ARN,
|
||||||
|
'aws-region': FAKE_REGION,
|
||||||
|
'role-duration-seconds': CUSTOM_ROLE_DURATION,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: parseInt(CUSTOM_ROLE_DURATION),
|
||||||
|
WebIdentityToken: 'testtoken',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('GH OIDC check fails if token is not set', async () => {
|
||||||
|
process.env['GITHUB_ACTIONS'] = 'true';
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(
|
||||||
|
mockGetInput({
|
||||||
|
'role-to-assume': ROLE_ARN,
|
||||||
|
'aws-region': FAKE_REGION,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.info).toHaveBeenCalledWith(
|
||||||
|
'It looks like you might be trying to authenticate with OIDC. Did you mean to set the `id-token` permission?'
|
||||||
|
);
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(
|
||||||
|
'Could not determine how to assume credentials. Please check your inputs and try again.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption fails after maximum trials using OIDC provider', async () => {
|
||||||
|
process.env['GITHUB_ACTIONS'] = 'true';
|
||||||
|
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = 'test-token';
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION }));
|
||||||
|
|
||||||
|
mockedSTS.reset();
|
||||||
|
mockedSTS.on(AssumeRoleWithWebIdentityCommand).rejects();
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand).length).toEqual(12);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption fails after one trial when disabling retry', async () => {
|
||||||
|
process.env['GITHUB_ACTIONS'] = 'true';
|
||||||
|
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = 'test-token';
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(
|
||||||
|
mockGetInput({ 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION, 'disable-retry': 'true' })
|
||||||
|
);
|
||||||
|
|
||||||
|
mockedSTS.reset();
|
||||||
|
mockedSTS.on(AssumeRoleWithWebIdentityCommand).rejects();
|
||||||
|
|
||||||
|
await run();
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand).length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption fails if access key id contains special characters', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||||
|
|
||||||
|
mockedSTS.on(AssumeRoleCommand).resolves({
|
||||||
|
Credentials: {
|
||||||
|
AccessKeyId: 'asdf+',
|
||||||
|
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||||
|
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||||
|
Expiration: new Date(8640000000000000),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(12);
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(
|
||||||
|
'Could not assume role with user credentials: AccessKeyId contains special characters.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption fails if secret access key contains special characters', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||||
|
|
||||||
|
mockedSTS.on(AssumeRoleCommand).resolves({
|
||||||
|
Credentials: {
|
||||||
|
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||||
|
SecretAccessKey: 'asdf+',
|
||||||
|
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||||
|
Expiration: new Date(8640000000000000),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(12);
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(
|
||||||
|
'Could not assume role with user credentials: SecretAccessKey contains special characters.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role assumption succeeds if keys have no special characters', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||||
|
|
||||||
|
mockedSTS.on(AssumeRoleCommand).resolves({
|
||||||
|
Credentials: {
|
||||||
|
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||||
|
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||||
|
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||||
|
Expiration: new Date(8640000000000000),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('max retries is configurable', async () => {
|
||||||
|
process.env['GITHUB_ACTIONS'] = 'true';
|
||||||
|
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = 'test-token';
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(
|
||||||
|
mockGetInput({
|
||||||
|
'role-to-assume': ROLE_ARN,
|
||||||
|
'aws-region': FAKE_REGION,
|
||||||
|
'retry-max-attempts': '15',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
mockedSTS.reset();
|
||||||
|
mockedSTS.on(AssumeRoleWithWebIdentityCommand).rejects();
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand).length).toEqual(15);
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith('Could not assume role with OIDC: ');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('max retries negative input does not retry', async () => {
|
||||||
|
process.env['GITHUB_ACTIONS'] = 'true';
|
||||||
|
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = 'test-token';
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(
|
||||||
|
mockGetInput({
|
||||||
|
'role-to-assume': ROLE_ARN,
|
||||||
|
'aws-region': FAKE_REGION,
|
||||||
|
'retry-max-attempts': '-1',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
mockedSTS.reset();
|
||||||
|
mockedSTS.on(AssumeRoleWithWebIdentityCommand).rejects();
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand).length).toEqual(1);
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith('Could not assume role with OIDC: ');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('role external ID provided', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-external-id': 'abcdef' }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
ExternalId: 'abcdef',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('workflow name sanitized in role assumption tags', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||||
|
|
||||||
|
process.env = {
|
||||||
|
...process.env,
|
||||||
|
GITHUB_WORKFLOW:
|
||||||
|
'Workflow!"#$%&\'()*+, -./:;<=>?@[]^_`{|}~🙂💥🍌1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZai9D2AN2RlWCxtMqChNtxuxjqeqhoQZo0oaq39sjcRZgAAAAAAA',
|
||||||
|
};
|
||||||
|
|
||||||
|
const sanitizedWorkflowName =
|
||||||
|
'Workflow__________+_ -./:__=__@____________1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZa';
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: sanitizedWorkflowName },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('skip tagging provided as true', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': 'true' }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: undefined,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('skip tagging provided as false', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': 'false' }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('skip tagging not provided', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('masks variables before exporting', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||||
|
|
||||||
|
const maskedValues: string[] = [];
|
||||||
|
const publicFields = ['AWS_REGION', 'AWS_DEFAULT_REGION'];
|
||||||
|
jest.spyOn(core, 'setSecret').mockImplementation((secret) => {
|
||||||
|
maskedValues.push(secret);
|
||||||
|
});
|
||||||
|
jest.spyOn(core, 'exportVariable').mockImplementation((name, value) => {
|
||||||
|
const val = String(value);
|
||||||
|
if (!maskedValues.includes(val) && !publicFields.includes(name)) {
|
||||||
|
throw new Error(`{value} for variable ${name} is not masked yet!`);
|
||||||
|
}
|
||||||
|
process.env[name] = val;
|
||||||
|
});
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.exportVariable).toReturn();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('inline policy and managed session policies are provided in assume role calls', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'inline-session-policy': 'inline' }));
|
||||||
|
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getMultilineInput')
|
||||||
|
.mockImplementation(mockGetMultilineInput({ 'managed-session-policies': MANAGED_SESSION_POLICY_INPUT }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(mockedSTS.commandCalls(AssumeRoleCommand)[0]?.args[0].input).toEqual({
|
||||||
|
RoleArn: ROLE_ARN,
|
||||||
|
RoleSessionName: 'GitHubActions',
|
||||||
|
DurationSeconds: 3600,
|
||||||
|
Tags: [
|
||||||
|
{ Key: 'GitHub', Value: 'Actions' },
|
||||||
|
{ Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY },
|
||||||
|
{ Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW },
|
||||||
|
{ Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION },
|
||||||
|
{ Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED },
|
||||||
|
{ Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA },
|
||||||
|
{ Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF },
|
||||||
|
],
|
||||||
|
Policy: 'inline',
|
||||||
|
PolicyArns: [
|
||||||
|
{ arn: 'arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess' },
|
||||||
|
{ arn: 'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('prints assumed role id', async () => {
|
||||||
|
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.info).toHaveBeenCalledWith(`Authenticated as assumedRoleId ${FAKE_ASSUMED_ROLE_ID}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('unsets credentials if enabled', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'unset-current-credentials': 'true' }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(12);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sets credentials as output if enabled', async () => {
|
||||||
|
jest
|
||||||
|
.spyOn(core, 'getInput')
|
||||||
|
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'output-credentials': 'true' }));
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setOutput).toHaveBeenCalledTimes(4);
|
||||||
|
});
|
||||||
|
});
|
||||||
9
tsconfig.build.json
Normal file
9
tsconfig.build.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"exclude": [
|
||||||
|
"test/**/*.ts"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "src"
|
||||||
|
},
|
||||||
|
}
|
||||||
34
tsconfig.json
Normal file
34
tsconfig.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowUnreachableCode": false,
|
||||||
|
"allowUnusedLabels": false,
|
||||||
|
"strict": true,
|
||||||
|
"exactOptionalPropertyTypes": false,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"module": "CommonJS",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"outDir": "build",
|
||||||
|
"declaration": true,
|
||||||
|
"newLine": "lf",
|
||||||
|
"noEmitOnError": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"disableSizeLimit": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"lib": [ "ES2020" ],
|
||||||
|
"target": "ES2020",
|
||||||
|
"noErrorTruncation": true,
|
||||||
|
"esModuleInterop": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts",
|
||||||
|
"test/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [],
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user