mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-08-31 05:35:04 +09:00
Compare commits
601 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2748f18272 | |||
| e977f476bf | |||
| ab0d61f6a0 | |||
| ccf493e3b1 | |||
| 05ed620dc8 | |||
| 62f98f6930 | |||
| 5a780d06ff | |||
| d3cb30b08b | |||
| eb48debd38 | |||
| e69af16b6c | |||
| 7fb20f0656 | |||
| 4e7ae70130 | |||
| 9ae780b171 | |||
| 517a711dbc | |||
| d01d678e65 | |||
| 8efa52b284 | |||
| 8e1eed5c14 | |||
| 112421a93a | |||
| fbc01c6585 | |||
| b12ca875eb | |||
| d314f7f43d | |||
| a53b65b84a | |||
| 338d2c1839 | |||
| b94086889d | |||
| 9df7c63a2f | |||
| c35a5960bf | |||
| 187c14ee87 | |||
| c403f3cb69 | |||
| 08319dee24 | |||
| d2e2926774 | |||
| 90f23cf274 | |||
| 26d9fee367 | |||
| 6686d5a051 | |||
| 254c19bd24 | |||
| a20cf827fe | |||
| 4d281fbc56 | |||
| e004cdcd28 | |||
| 88aa3695d3 | |||
| 687331b272 | |||
| ea607be060 | |||
| 6d136066d8 | |||
| 71a32ae408 | |||
| b290f2ca79 | |||
| 0cd4b34a9b | |||
| e6e5af76de | |||
| 7089b3a41f | |||
| 1a6323c7ef | |||
| 8136aa1bcb | |||
| ffffc0fe9d | |||
| 93823cfbdc | |||
| 7397aaead8 | |||
| fc8f6a6abe | |||
| 3c7bb1cb09 | |||
| 024bb07a82 | |||
| 86c1acf81a | |||
| 50c2567845 | |||
| 270cb5b1d9 | |||
| 51e8115730 | |||
| 7f56bcdc8b | |||
| 357812ba85 | |||
| 6a57fcec9b | |||
| 11b91e35b6 | |||
| eeef317384 | |||
| 586cfded7b | |||
| ff89a791a6 | |||
| c2036624d0 | |||
| 68fa256f0b | |||
| 97363c92bb | |||
| 05c3e92d7e | |||
| 037dd16322 | |||
| 89a34d9b83 | |||
| d63f12fba5 | |||
| aefb6ea018 | |||
| bf27562715 | |||
| 4f3ef32554 | |||
| 26b365ff2f | |||
| 262ce4cfb5 | |||
| e7f100cf4c | |||
| bbbffeab00 | |||
| d6f5dc331b | |||
| 12014c0798 | |||
| 4ab3589ed2 | |||
| 99214aa688 | |||
| 217d17914b | |||
| 5548f3441b | |||
| 77cd089899 | |||
| dbacf3135e | |||
| 87eb0cf693 | |||
| acca2b1b20 | |||
| c329d242ce | |||
| c39f282697 | |||
| 8188bee95b | |||
| 477988d772 | |||
| 9a5ab5bbe8 | |||
| baa1fdfef9 | |||
| 4be0a3c167 | |||
| f85f964a2e | |||
| 6fddd0cf67 | |||
| 254d42c4b6 | |||
| 01e40c97bf | |||
| 48a00774d0 | |||
| 18e0298e7d | |||
| 36eb080f7f | |||
| 3d40fa4093 | |||
| 3cc0e19239 | |||
| e8614cfbf0 | |||
| 4684f47f89 | |||
| 48b8685c96 | |||
| fe6ad3af19 | |||
| 2520c5e921 | |||
| bc1093db1d | |||
| ffde832a1d | |||
| 707acd96f6 | |||
| a7c33ae483 | |||
| 713aaabfec | |||
| e6e8eba750 | |||
| 58e7c47adf | |||
| f35a7d7d7e | |||
| 3884f59ecd | |||
| e0ba768507 | |||
| 6795889618 | |||
| 29d1be3027 | |||
| ef734cca81 | |||
| 7521c55910 | |||
| c0e2737f14 | |||
| dbd503f368 | |||
| 18a236fbd1 | |||
| 1ab31502aa | |||
| 1fb495c4b2 | |||
| 1e8fec8ea1 | |||
| a388f23f7d | |||
| 3f7e1b63d7 | |||
| e35449909c | |||
| 958a80fc34 | |||
| 540d0c13ae | |||
| 07ada0fe07 | |||
| f8d4eb68a9 | |||
| 8d52d05d7a | |||
| 681892c11b | |||
| dc2353e57a | |||
| 61f50f630f | |||
| c36525a567 | |||
| 39d1702721 | |||
| 4cfda40a13 | |||
| 8856e12f3a | |||
| 64d8e82527 | |||
| 78f374f6d1 | |||
| d979d5b3a7 | |||
| d4a9acd8d3 | |||
| fc44f4ae40 | |||
| 0b8336f1ba | |||
| 8c5bf33eed | |||
| 53df0c1c32 | |||
| c2c55827d2 | |||
| bd0031d7c3 | |||
| 6ab499a698 | |||
| bc94895858 | |||
| 934ca25ed2 | |||
| 2141953f88 | |||
| bee39e8d77 | |||
| 21c0950dc0 | |||
| 94fd6c27a4 | |||
| 3c8d2af9dc | |||
| ee2d8e963b | |||
| 66e76254c4 | |||
| c36c0e55fd | |||
| 59c3fbfdaa | |||
| 5e19c1aa7a | |||
| aa48afa741 | |||
| 3e32d92984 | |||
| 795d57b736 | |||
| 8ff6de5203 | |||
| 3436a392ac | |||
| 3c894dabff | |||
| 787075d425 | |||
| 80269b713c | |||
| 1f08c8a67c | |||
| 930440c681 | |||
| d3bef17c22 | |||
| 61dcf734bf | |||
| ff6a0a0749 | |||
| 30a5c4561c | |||
| 000d6227cc | |||
| c315e354eb | |||
| 7945953394 | |||
| 870695bc36 | |||
| ec43ad8ccf | |||
| ec61189d14 | |||
| 81676eb9eb | |||
| dc64d28371 | |||
| bc0a50afbe | |||
| 9ea6412aba | |||
| 0a8759496b | |||
| a7f0c828ac | |||
| e6bb6e5ff3 | |||
| 11b1c58b24 | |||
| 51635dbf41 | |||
| 8d0763f1dd | |||
| 563c6001b1 | |||
| 86ccf31ce5 | |||
| 75adeddc6d | |||
| 84e4970378 | |||
| f86e2d2212 | |||
| c256fd5d4c | |||
| c422da5be3 | |||
| 21cbb61e80 | |||
| 118f2eabc7 | |||
| 8c3df7a7e3 | |||
| ea65c961f1 | |||
| ed95fff515 | |||
| 8f2e168fe8 | |||
| 7a319c378c | |||
| b1257c4001 | |||
| e08afaa6ae | |||
| 668d1470ed | |||
| 24d6c03371 | |||
| 97361f40d9 | |||
| b2e4eaa23d | |||
| 615659e46e | |||
| 2bb9df827e | |||
| 2ab6fc87e4 | |||
| f8de47bf3e | |||
| 0820d92983 | |||
| 9d1c42024f | |||
| b6772acfeb | |||
| 33712a4c0c | |||
| 4a69b64afd | |||
| 5b448139a8 | |||
| 589732a070 | |||
| 01320c3462 | |||
| c6fe21d5fb | |||
| 2e454faab9 | |||
| 915869ead1 | |||
| 29a5036ebe | |||
| 7642046d79 | |||
| 45ab090e10 | |||
| 3bd622937f | |||
| b47aa7bd72 | |||
| 4a7f27f713 | |||
| f98ea5fac2 | |||
| 2db830a320 | |||
| 6e631f05b2 | |||
| c575728438 | |||
| 96507ba8cf | |||
| c3b2204dd6 | |||
| c95c3899f6 | |||
| f487a3d994 | |||
| b9539eec90 | |||
| ac7d2f7df3 | |||
| e30d08aad1 | |||
| c00f62bf94 | |||
| 4ce2bbcf5d | |||
| 0f01265ceb | |||
| bb84b6db01 | |||
| b8de5565ca | |||
| 028c01e898 | |||
| 8df5847569 | |||
| d22a0f8af5 | |||
| f7b8181755 | |||
| c367a6acb0 | |||
| 7ceaf96edc | |||
| a7a2c1125c | |||
| 6e3375df07 | |||
| 98abed7841 | |||
| bf3adbbb94 | |||
| db43b8b90a | |||
| fc999da49a | |||
| 4f2ba7fe9c | |||
| a9717e6ab0 | |||
| 5638c55000 | |||
| 9260701d07 | |||
| 2a2d67de88 | |||
| 1f91feff98 | |||
| 5a45798cc2 | |||
| 03ca40259f | |||
| fdaa1bdaab | |||
| 76cd0519f8 | |||
| d8821142e5 | |||
| 455579b45d | |||
| aa67178d69 | |||
| 4b8f2761e5 | |||
| f63ad03df6 | |||
| 00e1ea3dc5 | |||
| 71fa3f4cf0 | |||
| eb0f73c987 | |||
| ab20c8bb65 | |||
| 65d5a3ae87 | |||
| acc79c2e07 | |||
| b1e95de918 | |||
| 86903cfb2e | |||
| 26e9ba52a0 | |||
| b5c9882977 | |||
| 5ffcf010cf | |||
| dffada93d8 | |||
| b61bf5b567 | |||
| 31f53c456e | |||
| 4df9a01ef6 | |||
| dad3c3ee8b | |||
| a12214142d | |||
| 7669a6d405 | |||
| 2763a9e234 | |||
| 731c99bf59 | |||
| 82399fd121 | |||
| 827e0dd2c7 | |||
| 92cde8da32 | |||
| 1b36ca57f6 | |||
| 50ecfdead0 | |||
| 66fa6511a5 | |||
| 96008b1ef1 | |||
| 40fe06d904 | |||
| 228103980f | |||
| ffde586b91 | |||
| 92ca50a768 | |||
| ac60232d49 | |||
| c2ee69e5ef | |||
| 756668eaa3 | |||
| d936e04b3a | |||
| bf7978d83a | |||
| a032176f30 | |||
| 9c1f8ca0da | |||
| 26dce75391 | |||
| fd26731f53 | |||
| e5756ca1e0 | |||
| 34fc1d2aec | |||
| 1e12ebe97f | |||
| dde546460d | |||
| eb454ac214 | |||
| c41df0cb9a | |||
| 3e2185aea7 | |||
| b700559a4e | |||
| 240d5c0842 | |||
| 07805a4645 | |||
| 802e33dfc8 | |||
| eec2841a24 | |||
| 20eb4eea7a | |||
| fd1fab4c46 | |||
| 3e5ba48531 | |||
| 7353058e3d | |||
| 21d1a5dae5 | |||
| 5435336b28 | |||
| 6ee38f3e09 | |||
| d2df8fb83e | |||
| 6693fa69d2 | |||
| 5ac87a6bfa | |||
| 700d8245cb | |||
| 683ebee979 | |||
| 9676be21f8 | |||
| a6afc9d2bb | |||
| 97d28c427e | |||
| 3e8ea3f06f | |||
| 6e03995d2b | |||
| c8c213ac38 | |||
| ad637adc0d | |||
| 9b543ae650 | |||
| fca1f956f0 | |||
| 448705b338 | |||
| 1b144e932e | |||
| 91d8d22b3e | |||
| 04950cd7bd | |||
| 7097ca2b49 | |||
| d8a900d19b | |||
| 7d628b0df3 | |||
| fc11d7f742 | |||
| 2873226d5a | |||
| f64865f02d | |||
| 84e14cfa24 | |||
| 0c446a4f26 | |||
| 6c80fb6597 | |||
| 59974ea689 | |||
| d02ec080f0 | |||
| 5f6824cc21 | |||
| 5ef9a45125 | |||
| 1c3bb301a5 | |||
| 73bfb11c3e | |||
| ce10ea457f | |||
| 6e6743c58a | |||
| 7695a63157 | |||
| 177dade8f5 | |||
| a87e741eba | |||
| 215dbfc2e0 | |||
| 569add8750 | |||
| 45e9b2361a | |||
| 9aa437c71f | |||
| 1b22251287 | |||
| 30f1979f73 | |||
| c8eae42842 | |||
| d1738addf8 | |||
| 3c81eaa0ac | |||
| c1f99d9919 | |||
| c8d2acc8cd | |||
| 10d0957229 | |||
| 1db6a8d36b | |||
| 26ee0db93b | |||
| 368291f3c1 | |||
| af208eb863 | |||
| 4f7685c9d1 | |||
| 7de3ac08ca | |||
| 9515e12615 | |||
| e1f27963af | |||
| 44e3fb90db | |||
| 0a6b7158f2 | |||
| ecfe99e00b | |||
| 7203c21033 | |||
| 827af033de | |||
| cd8279cd8c | |||
| d0a05da0c8 | |||
| 9fb1716ceb | |||
| ae5e76d11f | |||
| 4f0bc4ee1c | |||
| 84104e7415 | |||
| 81dc407534 | |||
| 2e3dfc44a9 | |||
| d89333df1f | |||
| 38d8c64eb3 | |||
| a7097b0e08 | |||
| e75f7e3d06 | |||
| b54432e49c | |||
| f913942884 | |||
| 993411ece6 | |||
| e8cc5bc2e0 | |||
| 9466cfb60a | |||
| 6357374424 | |||
| 0a2792614c | |||
| d2c16a05bc | |||
| fcf6a5e397 | |||
| 1dfb9b5b42 | |||
| 50338e4c8b | |||
| ea9c29ec48 | |||
| 1e33ae6ecf | |||
| f0523e4a99 | |||
| e179430bce | |||
| a2e38048be | |||
| c50a0a9b27 | |||
| d141330353 | |||
| b6378a5559 | |||
| 5ebb541f8e | |||
| 0a8a3fde10 | |||
| 6b29d970f2 | |||
| caf97ba94e | |||
| 832f3f157a | |||
| 9fee09aa0f | |||
| 0ecfd13b95 | |||
| 80ed412f2c | |||
| 979931c880 | |||
| 8490feb378 | |||
| 16829738f0 | |||
| 0ec5ceba16 | |||
| 00aa8475ff | |||
| e19fa45bbe | |||
| 5858805023 | |||
| 2a9d16e130 | |||
| 3c03de593f | |||
| 58c637bfde | |||
| 87ec0e2f9a | |||
| be798e597e | |||
| 9f25b942f3 | |||
| a16a4a650d | |||
| 5106596545 | |||
| 953dc09b57 | |||
| a8c653ebfd | |||
| 28e5c8cc3c | |||
| c1ccd11e42 | |||
| 386556ad7a | |||
| 83abc2cb18 | |||
| 627aa7d3f0 | |||
| 09c6ab0945 | |||
| 9520a4e0cd | |||
| 58e38ace1e | |||
| 14fe238815 | |||
| 2f368822bc | |||
| ea5f0819c5 | |||
| 8a82d2d5ab | |||
| e2c7d37fe6 | |||
| a6182fef59 | |||
| a94e0a7ea6 | |||
| ed4a6054d8 | |||
| 09242f526d | |||
| 0cb77eaa44 | |||
| 7bbb5b2868 | |||
| 3d28c41d1c | |||
| 9c6719055e | |||
| 2d5ba6312f | |||
| dd91a7329e | |||
| b207c2ce9c | |||
| 8ef6b3dfde | |||
| 6b62b82e1a | |||
| 3b040fe7c1 | |||
| 3991c2aa73 | |||
| 3e1cb2c6fa | |||
| e378c2d267 | |||
| a26a7d8191 | |||
| 23f8661f4e | |||
| 623eede63e | |||
| c97f36fa83 | |||
| 12acc19c37 | |||
| 2f4ebbbbe9 | |||
| 9dfbd92b40 | |||
| e1dd6a9dff | |||
| 3b7b986954 | |||
| d086bfff83 | |||
| 2957ddac72 | |||
| 055bcbf797 | |||
| 7f1ac84759 | |||
| 25e258c360 | |||
| 3efb5d271f | |||
| f02f0dd54b | |||
| b0e79a919c | |||
| b8672ce0f2 | |||
| 5c173daddc | |||
| d1341457f1 | |||
| d30a6ec102 | |||
| 8b40776d15 | |||
| 1bd534f39d | |||
| 52c94ca47d | |||
| 3cb16d3813 | |||
| 724331c579 | |||
| b31db2fc7e | |||
| cfba6e3fe6 | |||
| 98a2c004ab | |||
| 592da77779 | |||
| d6e92fbf6c | |||
| c4313d89d1 | |||
| a54abe3f65 | |||
| 523f5b70b1 | |||
| 96797d5da1 | |||
| 35e11996f9 | |||
| 2d8e953343 | |||
| 636ab0a6c4 | |||
| cfc284beb6 | |||
| 465c2714be | |||
| 7fab3c1652 | |||
| 7b4c4016d3 | |||
| fe7827697e | |||
| 5f34186b4f | |||
| 514d965912 | |||
| 431bb0e5e3 | |||
| bd4992e70f | |||
| 640ff09de4 | |||
| 6cbe04160d | |||
| f189ab2733 | |||
| d1bb999f84 | |||
| 2f322f74a4 | |||
| 3dd0d555d3 | |||
| a587f63dfc | |||
| 84ec638d5c | |||
| fd26919f2e | |||
| cd5db3dc55 | |||
| d746073c3b | |||
| 858051bf2c | |||
| dccf3358c4 | |||
| 93333921c2 | |||
| 38af36b139 | |||
| e1b30a229e | |||
| e0972b3bd3 | |||
| c48c1abdc6 | |||
| 4f56c48b61 | |||
| b94e285a37 | |||
| c99770cf05 | |||
| 053e07cf5a | |||
| 6ebc88dc2e | |||
| aa68dca51c | |||
| 06d7aa1874 | |||
| 3d611684e4 | |||
| 484ffd482b | |||
| 4c2b9cc816 | |||
| 9c281c2db1 | |||
| c68210be47 | |||
| 55344e88d5 | |||
| 368aaaea8b | |||
| d4cbe72c98 | |||
| 5865cbb75b | |||
| 5f81b77081 | |||
| 6f77caca4f | |||
| d469565038 | |||
| 5146ad8b13 | |||
| 63fbbb2125 | |||
| 92b7fa8c77 | |||
| 0e60bf36c5 | |||
| d297d10b3c | |||
| b547701ef9 | |||
| 53f685283e | |||
| 76fa2a9a47 | |||
| adc3ddb68e | |||
| 2bb2c9f343 | |||
| b7485ed56c | |||
| cf459bd402 | |||
| 8cab366214 | |||
| 23e6365778 | |||
| 8b8c83f061 | |||
| ce3b5b9a77 | |||
| 81d81299bd | |||
| 93b7c87b95 | |||
| 259eac73d3 | |||
| fb04784af2 | |||
| c2d97f1165 | |||
| e72552b2cd | |||
| 4cb75e3962 | |||
| e435456e03 | |||
| 0ffb4a5509 | |||
| 7fe9149dbf | |||
| 232435c0c0 |
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"inputs": ["./package.json"],
|
||||||
|
"output": "./THIRD-PARTY",
|
||||||
|
"overwrite": true,
|
||||||
|
"ci": true
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
*Issue #, if available:*
|
_Issue #, if available:_
|
||||||
|
|
||||||
*Description of changes:*
|
_Description of changes:_
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
* [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws-actions/configure-aws-credentials/blob/main/CONTRIBUTING.md)
|
- [ ] Have you followed the guidelines in our
|
||||||
|
[Contributing guide?](https://github.com/aws-actions/configure-aws-credentials/blob/main/CONTRIBUTING.md)
|
||||||
|
|
||||||
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
|
By submitting this pull request, I confirm that you can use, modify, copy, and
|
||||||
|
redistribute this contribution, under the terms of your choice.
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
name: "CodeQL config"
|
||||||
|
|
||||||
|
paths-ignore:
|
||||||
|
- dist
|
||||||
|
- node_modules
|
||||||
@@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Configure AWS credentials
|
- name: Configure AWS credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5
|
uses: aws-actions/configure-aws-credentials@v6
|
||||||
with:
|
with:
|
||||||
aws-region: us-west-2
|
aws-region: us-west-2
|
||||||
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
|
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
name: Clone repo
|
name: Clone repo
|
||||||
- name: Configure AWS credentials
|
- name: Configure AWS credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5
|
uses: aws-actions/configure-aws-credentials@v6
|
||||||
with:
|
with:
|
||||||
aws-region: us-west-2
|
aws-region: us-west-2
|
||||||
role-to-assume: ${{ secrets.CONFIGUREAWSCREDENTIALSPACKAGEROLEARN }}
|
role-to-assume: ${{ secrets.CONFIGUREAWSCREDENTIALSPACKAGEROLEARN }}
|
||||||
|
|||||||
@@ -28,7 +28,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@v5
|
uses: aws-actions/configure-aws-credentials@v6
|
||||||
with:
|
with:
|
||||||
aws-region: us-west-2
|
aws-region: us-west-2
|
||||||
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
|
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
|
||||||
@@ -47,5 +47,6 @@ jobs:
|
|||||||
git config user.email "github-aws-sdk-osds-automation@amazon.com"
|
git config user.email "github-aws-sdk-osds-automation@amazon.com"
|
||||||
git remote set-url origin https://${{ env.OSDS_ACCESS_TOKEN }}@github.com/aws-actions/configure-aws-credentials.git
|
git remote set-url origin https://${{ env.OSDS_ACCESS_TOKEN }}@github.com/aws-actions/configure-aws-credentials.git
|
||||||
git add dist
|
git add dist
|
||||||
|
git add THIRD-PARTY
|
||||||
git commit -m "chore: Update dist" || echo "No changes to commit"
|
git commit -m "chore: Update dist" || echo "No changes to commit"
|
||||||
git push --force origin
|
git push --force origin
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
@@ -20,7 +21,7 @@
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5
|
uses: aws-actions/configure-aws-credentials@v6
|
||||||
with:
|
with:
|
||||||
aws-region: us-west-2
|
aws-region: us-west-2
|
||||||
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
|
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
|
||||||
@@ -35,9 +36,44 @@
|
|||||||
${{ secrets.OSDS_PACKAGING_ROLE }}
|
${{ secrets.OSDS_PACKAGING_ROLE }}
|
||||||
|
|
||||||
- name: Run release-please
|
- name: Run release-please
|
||||||
|
id: release
|
||||||
uses: googleapis/release-please-action@v4
|
uses: googleapis/release-please-action@v4
|
||||||
with:
|
with:
|
||||||
release-type: node
|
release-type: node
|
||||||
token: ${{ env.OSDS_ACCESS_TOKEN }}
|
token: ${{ env.OSDS_ACCESS_TOKEN }}
|
||||||
config-file: release-please-config.json
|
config-file: release-please-config.json
|
||||||
manifest-file: .release-please-manifest.json
|
manifest-file: .release-please-manifest.json
|
||||||
|
|
||||||
|
- name: Checkout Again
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Tag Major Version
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
run: |
|
||||||
|
git config user.name "GitHub Actions"
|
||||||
|
git config user.email "github-aws-sdk-osds-automation@amazon.com"
|
||||||
|
echo "::add-mask::${{ env.OSDS_ACCESS_TOKEN }}"
|
||||||
|
git remote set-url origin https://${{ env.OSDS_ACCESS_TOKEN }}@github.com/aws-actions/configure-aws-credentials.git
|
||||||
|
if git rev-parse "v${{ steps.release.outputs.major }}" >/dev/null 2>&1; then
|
||||||
|
git tag -d "v${{ steps.release.outputs.major }}"
|
||||||
|
git push origin ":v${{ steps.release.outputs.major }}"
|
||||||
|
fi
|
||||||
|
git tag -a "v${{ steps.release.outputs.major }}" -m "Release v${{ steps.release.outputs.major }}"
|
||||||
|
git push origin "v${{ steps.release.outputs.major }}"
|
||||||
|
|
||||||
|
- name: Update README version references
|
||||||
|
if: ${{ steps.release.outputs.release_created }}
|
||||||
|
run: |
|
||||||
|
sed -i 's|configure-aws-credentials@v[0-9]*\.[0-9]*\.[0-9]*|configure-aws-credentials@${{ steps.release.outputs.tag_name }}|g' README.md
|
||||||
|
if git diff --quiet README.md; then
|
||||||
|
echo "README already up to date"
|
||||||
|
else
|
||||||
|
echo "::add-mask::${{ env.OSDS_ACCESS_TOKEN }}"
|
||||||
|
git remote set-url origin https://${{ env.OSDS_ACCESS_TOKEN }}@github.com/aws-actions/configure-aws-credentials.git
|
||||||
|
git add README.md
|
||||||
|
git commit -m "docs: update README version references to ${{ steps.release.outputs.tag_name }}"
|
||||||
|
git push --force origin
|
||||||
|
fi
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
name: Run pre-release integ tests
|
name: Run pre-release integ tests
|
||||||
on:
|
on:
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
|
workflow_dispatch:
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
oidc:
|
oidc:
|
||||||
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
|
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials') }}
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
strategy:
|
strategy:
|
||||||
@@ -32,12 +33,17 @@ jobs:
|
|||||||
|
|
||||||
#can cut this test out if it's not necessary
|
#can cut this test out if it's not necessary
|
||||||
static_assumeRole:
|
static_assumeRole:
|
||||||
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
|
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials') }}
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-latest, ubuntu-latest, macos-latest]
|
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
name: Static IAM creds test
|
name: Static IAM creds test
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
@@ -45,19 +51,45 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Configure AWS credentials
|
- name: assume creator Role
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
aws-region: us-west-2
|
aws-region: us-west-2
|
||||||
aws-access-key-id: ${{ secrets.STATIC_ak_id }}
|
role-to-assume: ${{ secrets.STATIC_USER_CREATION_ROLE }}
|
||||||
aws-secret-access-key: ${{ secrets.STATIC_secret_ak }}
|
- name: create and mask access key
|
||||||
role-to-assume: ${{ secrets.STATIC_role }}
|
id: create-key
|
||||||
- name: Get Caller Identity
|
|
||||||
run: |
|
run: |
|
||||||
aws sts get-caller-identity
|
AK_OUTPUT=$(aws iam create-access-key --user-name integ-test-static-user-${{ runner.os }})
|
||||||
|
AK_ID=$(echo $AK_OUTPUT | jq -r '.AccessKey.AccessKeyId')
|
||||||
|
SECRET_AK=$(echo $AK_OUTPUT | jq -r '.AccessKey.SecretAccessKey')
|
||||||
|
echo "::add-mask::$AK_ID"
|
||||||
|
echo "::add-mask::$SECRET_AK"
|
||||||
|
echo "STATIC_ACCESS_KEY_ID=$AK_ID" >> $GITHUB_OUTPUT
|
||||||
|
echo "STATIC_SECRET_ACCESS_KEY=$SECRET_AK" >> $GITHUB_OUTPUT
|
||||||
|
- name: sleep so key can propagate
|
||||||
|
run: sleep 30
|
||||||
|
- name: assume role with static creds
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
aws-region: us-west-2
|
||||||
|
role-to-assume: ${{ secrets.STATIC_TEST_TARGET_ROLE }}
|
||||||
|
aws-access-key-id: ${{ steps.create-key.outputs.STATIC_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ steps.create-key.outputs.STATIC_SECRET_ACCESS_KEY }}
|
||||||
|
- name: check account
|
||||||
|
run: aws sts get-caller-identity
|
||||||
|
- name: log back into creator role
|
||||||
|
if: success() || failure()
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
aws-region: us-west-2
|
||||||
|
role-to-assume: ${{ secrets.STATIC_USER_CREATION_ROLE }}
|
||||||
|
- name: delete access key
|
||||||
|
if: success() || failure()
|
||||||
|
run: |
|
||||||
|
aws iam delete-access-key --user-name integ-test-static-user-${{ runner.os }} --access-key-id ${{ steps.create-key.outputs.STATIC_ACCESS_KEY_ID }}
|
||||||
|
|
||||||
role_chaining:
|
role_chaining:
|
||||||
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
|
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials') }}
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
strategy:
|
strategy:
|
||||||
@@ -91,7 +123,7 @@ jobs:
|
|||||||
aws sts get-caller-identity
|
aws sts get-caller-identity
|
||||||
|
|
||||||
inline_policy:
|
inline_policy:
|
||||||
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
|
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials') }}
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
strategy:
|
strategy:
|
||||||
@@ -129,7 +161,7 @@ jobs:
|
|||||||
run: exit 1
|
run: exit 1
|
||||||
|
|
||||||
http-proxy:
|
http-proxy:
|
||||||
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
|
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials') }}
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -163,7 +195,7 @@ jobs:
|
|||||||
run: exit 1
|
run: exit 1
|
||||||
|
|
||||||
token-file:
|
token-file:
|
||||||
if: ${{ github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials' }}
|
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials') }}
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
id-token: write
|
||||||
strategy:
|
strategy:
|
||||||
@@ -179,7 +211,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: fetch token and write to file
|
- name: fetch token and write to file
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v8
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@@ -200,3 +232,50 @@ jobs:
|
|||||||
retry-max-attempts: 4
|
retry-max-attempts: 4
|
||||||
- name: check creds
|
- name: check creds
|
||||||
run: aws sts get-caller-identity
|
run: aws sts get-caller-identity
|
||||||
|
|
||||||
|
profile-oidc:
|
||||||
|
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.user.login == 'aws-sdk-osds' && github.repository == 'aws-actions/configure-aws-credentials') }}
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
name: OIDC profile writing test
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: make profile 1
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
aws-region: us-east-1
|
||||||
|
role-to-assume: ${{ secrets.INTEG_PROFILE_ROLE_1 }}
|
||||||
|
aws-profile: TestProfile1
|
||||||
|
|
||||||
|
- name: make profile 2
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
aws-region: us-east-2
|
||||||
|
role-to-assume: ${{ secrets.INTEG_PROFILE_ROLE_2 }}
|
||||||
|
aws-profile: TestProfile2
|
||||||
|
|
||||||
|
- name: check profile1
|
||||||
|
run: aws sts get-caller-identity --profile TestProfile1
|
||||||
|
|
||||||
|
- name: check profile2
|
||||||
|
run: aws sts get-caller-identity --profile TestProfile2
|
||||||
|
|
||||||
|
- name: Get Caller Identity
|
||||||
|
id: no-creds-sts-step
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
aws sts get-caller-identity
|
||||||
|
|
||||||
|
- name: fail if we got caller id with env creds
|
||||||
|
if: steps.no-creds-sts-step.outcome == 'success'
|
||||||
|
run: exit 1
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ jobs:
|
|||||||
- name: "Checkout repository"
|
- name: "Checkout repository"
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
- name: "Setup node"
|
- name: "Setup node"
|
||||||
uses: actions/setup-node@v4.4.0
|
uses: actions/setup-node@v6.4.0
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 24
|
||||||
- name: "Install dependencies"
|
- name: "Install dependencies"
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: "Run tests"
|
- name: "Run tests"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
.history
|
||||||
node_modules
|
node_modules
|
||||||
coverage
|
coverage
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
default: true
|
||||||
|
MD007:
|
||||||
|
indent: 4
|
||||||
|
heading-style:
|
||||||
|
style: atx
|
||||||
|
ul-style:
|
||||||
|
style: dash
|
||||||
|
line-length:
|
||||||
|
stern: true
|
||||||
|
tables: false
|
||||||
|
code_blocks: false
|
||||||
|
no-inline-html:
|
||||||
|
allowed_elements:
|
||||||
|
- details
|
||||||
|
- summary
|
||||||
|
code-block-style:
|
||||||
|
style: fenced
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
".release-please-manifest.json": "4.0.2",
|
".release-please-manifest.json": "4.0.2",
|
||||||
"package.json": "4.0.2",
|
"package.json": "6.0.0",
|
||||||
".": "5.1.1"
|
".": "6.2.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,78 @@
|
|||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
## [6.2.2](https://github.com/aws-actions/configure-aws-credentials/compare/v6.2.1...v6.2.2) (2026-07-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous Chores
|
||||||
|
|
||||||
|
* release 6.2.2 ([d01d678](https://github.com/aws-actions/configure-aws-credentials/commit/d01d678e65d6d2bd9d5ca7a95d6f07b00e25f2c2))
|
||||||
|
|
||||||
|
## [6.2.1](https://github.com/aws-actions/configure-aws-credentials/compare/v6.2.0...v6.2.1) (2026-06-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* enforce allowed-account-ids on all auth paths ([#1847](https://github.com/aws-actions/configure-aws-credentials/issues/1847)) ([4d281fb](https://github.com/aws-actions/configure-aws-credentials/commit/4d281fbc56a82e63c3fc14f2cc22361f34c97493))
|
||||||
|
|
||||||
|
## [6.2.0](https://github.com/aws-actions/configure-aws-credentials/compare/v6.1.3...v6.2.0) (2026-06-01)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add additional session tags by default ([#1775](https://github.com/aws-actions/configure-aws-credentials/issues/1775)) ([e0ba768](https://github.com/aws-actions/configure-aws-credentials/commit/e0ba7685077379a14a82d01fefd511490344ebfc))
|
||||||
|
* add more retry logic and better logging ([#1764](https://github.com/aws-actions/configure-aws-credentials/issues/1764)) ([540d0c1](https://github.com/aws-actions/configure-aws-credentials/commit/540d0c13aedb8d55501d220bd2f0b3cdedfe84e8))
|
||||||
|
* add regex validation to role-session-name ([#1765](https://github.com/aws-actions/configure-aws-credentials/issues/1765)) ([e354499](https://github.com/aws-actions/configure-aws-credentials/commit/e35449909c6ede5083a48ba4b8bbfaaa1cf09ba1))
|
||||||
|
* Allow custom session tags to be passed when assuming a role ([#1759](https://github.com/aws-actions/configure-aws-credentials/issues/1759)) ([61f50f6](https://github.com/aws-actions/configure-aws-credentials/commit/61f50f630f383628add73c1eab3f1935ba07da2b))
|
||||||
|
* expose run id in STS client user-agent ([#1774](https://github.com/aws-actions/configure-aws-credentials/issues/1774)) ([29d1be3](https://github.com/aws-actions/configure-aws-credentials/commit/29d1be30273e7ef371d59fccf6ec54572c64ec89))
|
||||||
|
* support custom STS endpoints ([#1762](https://github.com/aws-actions/configure-aws-credentials/issues/1762)) ([8d52d05](https://github.com/aws-actions/configure-aws-credentials/commit/8d52d05d7a4521fa52b39de50cb6114b12e5c332))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* skip credential check on output-env-credentials: false ([#1778](https://github.com/aws-actions/configure-aws-credentials/issues/1778)) ([58e7c47](https://github.com/aws-actions/configure-aws-credentials/commit/58e7c47adf77846879008deadfeeef8a6969fe6c))
|
||||||
|
* assumeRole failing from session tag size too large ([#1808](https://github.com/aws-actions/configure-aws-credentials/issues/1808)) ([d6f5dc3](https://github.com/aws-actions/configure-aws-credentials/commit/d6f5dc331b44474b19a52caaf85fa4d637b13c8e))
|
||||||
|
|
||||||
|
## [6.1.3](https://github.com/aws-actions/configure-aws-credentials/compare/v6.1.2...v6.1.3) (2026-05-28)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix: allow kubelet token symlink in [#1805](https://github.com/aws-actions/configure-aws-credentials/issues/1805)
|
||||||
|
|
||||||
|
## [6.1.2](https://github.com/aws-actions/configure-aws-credentials/compare/v6.1.1...v6.1.2) (2026-05-26)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* additional filesystem checks ([#1799](https://github.com/aws-actions/configure-aws-credentials/issues/1799)) ([c39f282](https://github.com/aws-actions/configure-aws-credentials/commit/c39f282697aca8a78c522ecf1f7da9899a31432c))
|
||||||
|
|
||||||
|
## [6.1.1](https://github.com/aws-actions/configure-aws-credentials/compare/v6.1.0...v6.1.1) (2026-05-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Miscellaneous Chores
|
||||||
|
|
||||||
|
* various dependency updates
|
||||||
|
|
||||||
|
## [6.1.0](https://github.com/aws-actions/configure-aws-credentials/compare/v6.0.0...v6.1.0) (2026-04-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add skip cleanup option ([#1716](https://github.com/aws-actions/configure-aws-credentials/issues/1716)) ([11b1c58](https://github.com/aws-actions/configure-aws-credentials/commit/11b1c58b24724e66aa52a847862a0c1b0c4b0c7b)), closes [#1545](https://github.com/aws-actions/configure-aws-credentials/issues/1545)
|
||||||
|
* Support usage of AWS Profiles ([#1696](https://github.com/aws-actions/configure-aws-credentials/issues/1696)) ([a7f0c82](https://github.com/aws-actions/configure-aws-credentials/commit/a7f0c828ac76e0d049e34c920172c60f579f9eb3))
|
||||||
|
|
||||||
|
## [6.0.0](https://github.com/aws-actions/configure-aws-credentials/compare/v5.1.1...v6.0.0) (2026-02-04)
|
||||||
|
|
||||||
|
|
||||||
|
### ⚠ BREAKING CHANGES
|
||||||
|
|
||||||
|
* Update action to use node24 ([#1632](https://github.com/aws-actions/configure-aws-credentials/pull/1632)) ([a7a2c11](https://github.com/aws-actions/configure-aws-credentials/commit/a7a2c1125c67f40a1e95768f4e4a7d8f019f87af))
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add support to define transitive tag keys ([#1316](https://github.com/aws-actions/configure-aws-credentials/pull/1316)) ([232435c](https://github.com/aws-actions/configure-aws-credentials/commit/232435c0c05e51137544f0203931b84893d13b74)) ([930ebd9](https://github.com/aws-actions/configure-aws-credentials/pull/1628/changes/930ebd9bcaed959c3ba9e21567e8abbc3cae72c0))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* properly output `aws-account-id` and `authenticated-arn` when using role-chaining ([#1633](https://github.com/aws-actions/configure-aws-credentials/pull/1633)) ([7ceaf96](https://github.com/aws-actions/configure-aws-credentials/commit/7ceaf96edc86cc1713cef59eba79feeb23f59da1))
|
||||||
|
|
||||||
## [5.1.1](https://github.com/aws-actions/configure-aws-credentials/compare/v5.1.0...v5.1.1) (2025-11-24)
|
## [5.1.1](https://github.com/aws-actions/configure-aws-credentials/compare/v5.1.0...v5.1.1) (2025-11-24)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -1,4 +1,8 @@
|
|||||||
## Code of Conduct
|
# Code of Conduct
|
||||||
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
|
|
||||||
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
This project has adopted the
|
||||||
opensource-codeofconduct@amazon.com with any additional questions or comments.
|
[Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). For
|
||||||
|
more information see the
|
||||||
|
[Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
||||||
|
<opensource-codeofconduct@amazon.com> with any additional questions or
|
||||||
|
comments.
|
||||||
|
|||||||
+84
-28
@@ -1,61 +1,117 @@
|
|||||||
# Contributing Guidelines
|
# Contributing Guidelines
|
||||||
|
|
||||||
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
|
Thank you for your interest in contributing to our project. Whether it's a bug
|
||||||
documentation, we greatly value feedback and contributions from our community.
|
report, new feature, correction, or additional documentation, we greatly value
|
||||||
|
feedback and contributions from our community.
|
||||||
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
|
|
||||||
information to effectively respond to your bug report or contribution.
|
|
||||||
|
|
||||||
|
Please read through this document before submitting any issues or pull requests
|
||||||
|
to ensure we have all the necessary information to effectively respond to your
|
||||||
|
bug report or contribution.
|
||||||
|
|
||||||
## Reporting Bugs/Feature Requests
|
## Reporting Bugs/Feature Requests
|
||||||
|
|
||||||
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
|
We welcome you to use the GitHub issue tracker to report bugs or suggest
|
||||||
|
features.
|
||||||
|
|
||||||
When filing an issue, please check [existing open](https://github.com/aws-actions/configure-aws-credentials/issues), or [recently closed](https://github.com/aws-actions/configure-aws-credentials/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already
|
When filing an issue, please check [existing open][open-issues],
|
||||||
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
|
or [recently closed][closed-issues], issues to make sure somebody
|
||||||
|
else hasn't already reported the issue.
|
||||||
|
|
||||||
* A reproducible test case or series of steps
|
[open-issues]: https://github.com/aws-actions/configure-aws-credentials/issues
|
||||||
* The version of our code being used
|
[closed-issues]: https://github.com/aws-actions/configure-aws-credentials/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20
|
||||||
* Any modifications you've made relevant to the bug
|
|
||||||
* Anything unusual about your environment or deployment
|
|
||||||
|
|
||||||
|
Please try to include as much information as you can. Details like
|
||||||
|
these are incredibly useful:
|
||||||
|
|
||||||
|
- A reproducible test case or series of steps
|
||||||
|
- The version of our code being used
|
||||||
|
- Any modifications you've made relevant to the bug
|
||||||
|
- Anything unusual about your environment or deployment
|
||||||
|
|
||||||
## Contributing via Pull Requests
|
## Contributing via Pull Requests
|
||||||
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
|
|
||||||
|
|
||||||
1. You are working against the latest source on the *main* branch.
|
Contributions via pull requests are much appreciated. Before sending us a pull
|
||||||
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
|
request, please ensure that:
|
||||||
3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
|
|
||||||
|
1. You are working against the latest source on the _main_ branch.
|
||||||
|
2. You check existing open, and recently merged, pull requests to make sure
|
||||||
|
someone else hasn't addressed the problem already.
|
||||||
|
3. You open an issue to discuss any significant work - we would hate for your
|
||||||
|
time to be wasted.
|
||||||
|
|
||||||
To send us a pull request, please:
|
To send us a pull request, please:
|
||||||
|
|
||||||
1. Fork the repository.
|
1. Fork the repository.
|
||||||
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
|
2. Modify the source; please focus on the specific change you are contributing.
|
||||||
|
If you also reformat all the code, it will be hard for us to focus on your
|
||||||
|
change.
|
||||||
3. Ensure local tests pass.
|
3. Ensure local tests pass.
|
||||||
4. Commit to your fork using clear commit messages.
|
4. Commit to your fork using clear commit messages.
|
||||||
5. Send us a pull request, answering any default questions in the pull request interface.
|
5. Send us a pull request, answering any default questions in the pull request
|
||||||
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
|
interface.
|
||||||
|
6. Pay attention to any automated CI failures reported in the pull request, and
|
||||||
|
stay involved in the conversation.
|
||||||
|
|
||||||
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
|
GitHub provides additional document on
|
||||||
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
|
[forking a repository](https://help.github.com/articles/fork-a-repo/) and
|
||||||
|
[creating a pull request][create-pr].
|
||||||
|
|
||||||
|
[create-pr]:
|
||||||
|
https://help.github.com/articles/creating-a-pull-request/
|
||||||
|
|
||||||
## Finding contributions to work on
|
## Finding contributions to work on
|
||||||
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws-actions/configure-aws-credentials/labels/help%20wanted) issues is a great place to start.
|
|
||||||
|
|
||||||
|
Looking at the existing issues is a great way to find something to contribute
|
||||||
|
on. As our projects, by default, use the default GitHub issue labels
|
||||||
|
(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any
|
||||||
|
['help wanted'](https://github.com/aws-actions/configure-aws-credentials/labels/help%20wanted)
|
||||||
|
issues is a great place to start.
|
||||||
|
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
|
|
||||||
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
|
||||||
opensource-codeofconduct@amazon.com with any additional questions or comments.
|
|
||||||
|
|
||||||
|
This project has adopted the
|
||||||
|
[Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). For
|
||||||
|
more information see the
|
||||||
|
[Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
||||||
|
<opensource-codeofconduct@amazon.com> with any additional questions or
|
||||||
|
comments.
|
||||||
|
|
||||||
## Security issue notifications
|
## Security issue notifications
|
||||||
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
|
|
||||||
|
|
||||||
|
If you discover a potential security issue in this project we ask that you
|
||||||
|
notify AWS/Amazon Security via our
|
||||||
|
[vulnerability reporting page][vuln-report].
|
||||||
|
|
||||||
|
[vuln-report]:
|
||||||
|
http://aws.amazon.com/security/vulnerability-reporting/
|
||||||
|
Please do **not** create a public github issue.
|
||||||
|
|
||||||
|
## Automated Tools
|
||||||
|
|
||||||
|
The use of AI tooling for assisted development work is accepted and encouraged
|
||||||
|
in this repository, but due to the volume of submissions we ask that you observe
|
||||||
|
the following rules:
|
||||||
|
|
||||||
|
- All issue and pull request submissions to this repository that are sourced by
|
||||||
|
AI must first be reviewed by a human before submitting to the repository.
|
||||||
|
Items reviewed in this way must include a statement like "generated by AI
|
||||||
|
tools, and reviewed by [person]"
|
||||||
|
- Please ensure that your submissions are actually improvements. While we are
|
||||||
|
grateful for any proposed fixes, even if they are very small, behavior that
|
||||||
|
looks like creating noisy PRs or artificially inflating submission counts
|
||||||
|
is not acceptable.
|
||||||
|
- We may close issues or pull requests, or limit your ability to interact with
|
||||||
|
this repository, for behavior that in our estimation violates these rules or
|
||||||
|
any of the other rules in this repository's
|
||||||
|
[Code of Conduct](CODE_OF_CONDUCT.md).
|
||||||
|
|
||||||
## Licensing
|
## Licensing
|
||||||
|
|
||||||
See the [LICENSE](https://github.com/aws-actions/configure-aws-credentials/blob/main/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
|
See the
|
||||||
|
[LICENSE](https://github.com/aws-actions/configure-aws-credentials/blob/main/LICENSE)
|
||||||
|
file for our project's licensing. We will ask you to confirm the licensing of
|
||||||
|
your contribution.
|
||||||
|
|
||||||
We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
|
We may ask you to sign a
|
||||||
|
[Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement)
|
||||||
|
for larger changes.
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
Configure AWS Credentials
|
# Configure AWS Credentials
|
||||||
=========================
|
|
||||||
Authenticate to AWS in GitHub Actions! Works especially well with [AWS Secrets
|
Authenticate to AWS in GitHub Actions (and others)! Works especially well with
|
||||||
Manager](https://github.com/aws-actions/aws-secretsmanager-get-secrets).
|
[AWS Secrets Manager][secretsmanager].
|
||||||
|
|
||||||
|
[secretsmanager]: https://github.com/aws-actions/aws-secretsmanager-get-secrets
|
||||||
|
|
||||||
|
## Quick Start (OIDC, recommended)
|
||||||
|
|
||||||
Quick Start (OIDC, recommended)
|
|
||||||
-------------------------------
|
|
||||||
1. Create an IAM Identity Provider in your AWS account for GitHub OIDC. (See
|
1. Create an IAM Identity Provider in your AWS account for GitHub OIDC. (See
|
||||||
[OIDC configuration](#oidc-configuration) below for details.)
|
[OIDC configuration](#oidc-configuration-details) below for details.)
|
||||||
2. Create an IAM Role in your AWS account with a trust policy that allows GitHub
|
2. Create an IAM Role in your AWS account with a trust policy that allows GitHub
|
||||||
Actions to assume it:
|
Actions to assume it. (Expand the sections below) <details>
|
||||||
<details>
|
|
||||||
<summary>GitHub OIDC Trust Policy</summary>
|
<summary>GitHub OIDC Trust Policy</summary>
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -25,18 +26,30 @@ Actions to assume it:
|
|||||||
"Condition": {
|
"Condition": {
|
||||||
"StringEquals": {
|
"StringEquals": {
|
||||||
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
|
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
|
||||||
"token.actions.githubusercontent.com:sub": "repo:<GITHUB_ORG>/<GITHUB_REPOSITORY>:ref:refs/heads/<GITHUB_BRANCH>"
|
"token.actions.githubusercontent.com:sub": "repo:<GITHUB_ORG>@<ORG_ID>/<GITHUB_REPOSITORY>@<REPO_ID>:ref:refs/heads/<GITHUB_BRANCH>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
Note: The value of the `sub` claim may be different depending on the workflow
|
||||||
|
and the environment in which it's running. Workflows in repositories created
|
||||||
|
prior to [15 July 2026][immutable-sub] will omit the `@<ORG_ID>` and
|
||||||
|
`@<REPO_ID>` suffixes unless opted in. Workflows running in GitHub
|
||||||
|
environments will include an`environment:<ENVIRONMENT_NAME>` stanza. See
|
||||||
|
[Claims and scoping permissions](#claims-and-scoping-permissions) for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
[immutable-sub]:
|
||||||
|
https://github.blog/changelog/2026-04-23-immutable-subject-claims-for-github-actions-oidc-tokens/
|
||||||
|
|
||||||
3. Attach permissions to the IAM Role that allow it to access the AWS resources
|
3. Attach permissions to the IAM Role that allow it to access the AWS resources
|
||||||
you need.
|
you need.
|
||||||
4. Add the following to your GitHub Actions workflow:
|
4. Add the following to your GitHub Actions workflow: <details>
|
||||||
<details>
|
|
||||||
<summary>Example Workflow</summary>
|
<summary>Example Workflow</summary>
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -48,7 +61,7 @@ you need.
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@main # Or a specific version
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
role-to-assume: <Role ARN you created in step 2>
|
role-to-assume: <Role ARN you created in step 2>
|
||||||
aws-region: <AWS Region you want to use>
|
aws-region: <AWS Region you want to use>
|
||||||
@@ -57,30 +70,38 @@ you need.
|
|||||||
# Your commands that require AWS credentials
|
# Your commands that require AWS credentials
|
||||||
aws sts get-caller-identity
|
aws sts get-caller-identity
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
That's it! Your GitHub Actions workflow can now access AWS resources using the
|
That's it! Your GitHub Actions workflow can now access AWS resources using the
|
||||||
IAM Role you created. Other authentication scenarios are also supported (see
|
IAM Role you created. Other authentication scenarios are also supported (see
|
||||||
below).
|
below).
|
||||||
|
|
||||||
Security Recommendations
|
## Security Recommendations
|
||||||
------------------------
|
|
||||||
* Use temporary credentials when possible. OIDC is recommended because it
|
- Use temporary credentials when possible. OIDC is recommended because it
|
||||||
provides temporary credentials and it's easy to set up.
|
provides temporary credentials and it's easy to set up.
|
||||||
* Do not store credentials in your repository's code. Consider using
|
- Do not store credentials in your repository's code. Consider using
|
||||||
[git-secrets](https://github.com/awslabs/git-secrets) to prevent committing
|
[git-secrets](https://github.com/awslabs/git-secrets) to prevent committing
|
||||||
secrets to your repository.
|
secrets to your repository.
|
||||||
* [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)
|
- [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)
|
||||||
to your workflows. Grant only those permissions that are necessary for the
|
to your workflows. Grant only those permissions that are necessary for the
|
||||||
workflow to run.
|
workflow to run.
|
||||||
* [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log)
|
- [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log)
|
||||||
of the credentials used in workflows.
|
of the credentials used in workflows.
|
||||||
* Periodically rotate any long-lived credentials that you use.
|
- Periodically rotate any long-lived credentials that you use.
|
||||||
* Store sensitive information in a secure way, such as using
|
- Store sensitive information in a secure way, such as using
|
||||||
[AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) or
|
[AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) or [GitHub
|
||||||
[GitHub Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets).
|
Secrets][gh-secrets].
|
||||||
|
- Be especially careful about running Actions in non-ephemeral environments, or
|
||||||
|
[triggering workflows on `pull_request_target`](https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#pull_request_target)
|
||||||
|
events.
|
||||||
|
|
||||||
|
[gh-secrets]:
|
||||||
|
https://docs.github.com/en/actions/security-guides/encrypted-secrets
|
||||||
|
|
||||||
|
## Non-OIDC Authentication Options
|
||||||
|
|
||||||
Other Authentication Scenarios
|
|
||||||
------------------------------
|
|
||||||
This action supports five different authentication methods that are configured
|
This action supports five different authentication methods that are configured
|
||||||
by specifying different inputs.
|
by specifying different inputs.
|
||||||
|
|
||||||
@@ -95,40 +116,50 @@ by specifying different inputs.
|
|||||||
credentials via STS AssumeRole.
|
credentials via STS AssumeRole.
|
||||||
|
|
||||||
Because we use the AWS JavaScript SDK, we always will use the [credential
|
Because we use the AWS JavaScript SDK, we always will use the [credential
|
||||||
resolution flow for Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html).
|
resolution flow for Node.js][cred-resolution].
|
||||||
|
|
||||||
|
[cred-resolution]:
|
||||||
|
https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html
|
||||||
|
|
||||||
Depending on your inputs, the action might override parts of this flow.
|
Depending on your inputs, the action might override parts of this flow.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Inputs and their effects on the credential resolution flow</summary>
|
<summary>Inputs and their effects on the credential resolution flow</summary>
|
||||||
|
|
||||||
| **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` |
|
||||||
| ---------------------------------------- | ------------------- | ---------------- | ------------------------- | --------------- |
|
| --------------------------------------- | ------------------- | ---------------- | ------------------------- | --------------- |
|
||||||
| [✅ Recommended] GitHub OIDC | | ✔ | | |
|
| [✅ Recommended] GitHub OIDC | | ✔ | | |
|
||||||
| IAM User (no AssumeRole) | ✔ | | | |
|
| IAM User (no AssumeRole) | ✔ | | | |
|
||||||
| AssumeRole using static IAM credentials | ✔ | ✔ | | |
|
| AssumeRole using static IAM credentials | ✔ | ✔ | | |
|
||||||
| AssumeWithWebIdentity use a token file | | ✔ | ✔ | |
|
| AssumeWithWebIdentity use a token file | | ✔ | ✔ | |
|
||||||
| AssumeRole using existing credentials | | ✔ | | ✔ |
|
| AssumeRole using existing credentials | | ✔ | | ✔ |
|
||||||
|
|
||||||
*Note: `role-chaining` is not always necessary to use existing credentials.
|
_Note: `role-chaining` is not always necessary to use existing credentials. If
|
||||||
If you're getting a "Credentials loaded by the SDK do not match" error,
|
you're getting a "Credentials loaded by the SDK do not match" error, try
|
||||||
try enabling this option.*
|
enabling this option._
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
Additionally, **`aws-region`** is always required.
|
Additionally, **`aws-region`** is always required.
|
||||||
|
|
||||||
*Note: If you use GitHub Enterprise Server, you must use the you may need to
|
_Note: If you use GitHub Enterprise Server, you may need to adjust examples here
|
||||||
adjust examples here to match your environment.*
|
to match your environment._
|
||||||
|
|
||||||
|
## Additional Options
|
||||||
|
|
||||||
Additional Options
|
|
||||||
------------------
|
|
||||||
### Options
|
### Options
|
||||||
See [action.yml](./action.yml) for more detail.
|
|
||||||
|
The options list can be expanded below. See [action.yml](./action.yml) for more
|
||||||
|
detail.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Options list and descriptions</summary>
|
<summary>Options list and descriptions</summary>
|
||||||
|
|
||||||
| Option | Description | Required |
|
| Option | Description | Required |
|
||||||
|---------------------------|---------------------------------------------------------------------------------------------------|----------|
|
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
|
||||||
| aws-region | Which AWS region to use | Yes |
|
| aws-region | Which AWS region to use | Yes |
|
||||||
|
| aws-profile | Name of the AWS profile to configure. When provided, credentials are written to `~/.aws/credentials` and `~/.aws/config` files. This enables configuring multiple profiles in a single workflow. Name cannot contain whitespace, square brackets, or slashes. When set, credentials will not be exported as environment variables unless `output-env-credentials` is manually set to true. | No |
|
||||||
|
| overwrite-aws-profile | Overwrite the given AWS profile if it already exists. When set to false or not set, an error will be thrown if the profile already exists. | No |
|
||||||
| role-to-assume | Role for which to fetch credentials. Only required for some authentication types. | No |
|
| role-to-assume | Role for which to fetch credentials. Only required for some authentication types. | No |
|
||||||
| aws-access-key-id | AWS access key to use. Only required for some authentication types. | No |
|
| aws-access-key-id | AWS access key to use. Only required for some authentication types. | No |
|
||||||
| aws-secret-access-key | AWS secret key to use. Only required for some authentication types. | No |
|
| aws-secret-access-key | AWS secret key to use. Only required for some authentication types. | No |
|
||||||
@@ -141,10 +172,12 @@ See [action.yml](./action.yml) for more detail.
|
|||||||
| role-external-id | The external ID of the role to assume. Only needed if your role requires it. | No |
|
| role-external-id | The external ID of the role to assume. Only needed if your role requires it. | No |
|
||||||
| role-session-name | Defaults to "GitHubActions", but may be changed if required. | No |
|
| role-session-name | Defaults to "GitHubActions", but may be changed if required. | No |
|
||||||
| role-skip-session-tagging | Skips session tagging if set. | No |
|
| role-skip-session-tagging | Skips session tagging if set. | No |
|
||||||
|
| transitive-tag-keys | Define a list of transitive tag keys to pass when assuming a role. | No |
|
||||||
|
| custom-tags | Additional tags to apply to the assumed role session. Must be a JSON object provided as a string. Custom tags are not usable with OIDC or web identity token authentication. | No |
|
||||||
| inline-session-policy | You may further restrict the assumed role policy by defining an inline policy here. | No |
|
| inline-session-policy | You may further restrict the assumed role policy by defining an inline policy here. | No |
|
||||||
| managed-session-policies | You may further restrict the assumed role policy by specifying a managed policy here. | No |
|
| managed-session-policies | You may further restrict the assumed role policy by specifying a managed policy here. | No |
|
||||||
| output-credentials | When set, outputs fetched credentials as action step output. (Outputs aws-access-key-id, aws-secret-access-key, aws-session-token, aws-account-id, authenticated-arn, and aws-expiration). Defaults to false. | No |
|
| output-credentials | When set, outputs fetched credentials as action step output. (Outputs aws-access-key-id, aws-secret-access-key, aws-session-token, aws-account-id, authenticated-arn, and aws-expiration). Defaults to false. | No |
|
||||||
| output-env-credentials | When set, outputs fetched credentials as environment variables (AWS_REGION, AWS_DEFAULT_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN). Defaults to true. Set to false if you need to avoid setting/changing env variables. You'd probably want to use output-credentials if you disable this. (NOTE: Setting to false will prevent the aws-account-id from being exported as a step output). | No |
|
| output-env-credentials | When set, outputs fetched credentials as environment variables (AWS_REGION, AWS_DEFAULT_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, and AWS_PROFILE (if profile option is used)). Defaults to true when `aws-profile` is not set, and false when `aws-profile` is set. Set to false to avoid setting env variables. (NOTE: Setting to false will prevent aws-account-id from being exported as a step output). | No |
|
||||||
| unset-current-credentials | When set, attempts to unset any existing credentials in your action runner. | No |
|
| unset-current-credentials | When set, attempts to unset any existing credentials in your action runner. | No |
|
||||||
| disable-retry | Disabled retry/backoff logic for assume role calls. By default, retries are enabled. | No |
|
| disable-retry | Disabled retry/backoff logic for assume role calls. By default, retries are enabled. | No |
|
||||||
| retry-max-attempts | Limits the number of retry attempts before giving up. Defaults to 12. | No |
|
| retry-max-attempts | Limits the number of retry attempts before giving up. Defaults to 12. | No |
|
||||||
@@ -153,24 +186,120 @@ See [action.yml](./action.yml) for more detail.
|
|||||||
| allowed-account-ids | A comma-delimited list of expected AWS account IDs. The action will fail if we receive credentials for the wrong account. | No |
|
| allowed-account-ids | A comma-delimited list of expected AWS account IDs. The action will fail if we receive credentials for the wrong account. | No |
|
||||||
| force-skip-oidc | When set, the action will skip using GitHub OIDC provider even if the id-token permission is set. | No |
|
| force-skip-oidc | When set, the action will skip using GitHub OIDC provider even if the id-token permission is set. | No |
|
||||||
| action-timeout-s | Global timeout for the action in seconds. If set to a value greater than 0, the action will fail if it takes longer than this time to complete. | No |
|
| action-timeout-s | Global timeout for the action in seconds. If set to a value greater than 0, the action will fail if it takes longer than this time to complete. | No |
|
||||||
|
| no-proxy | Hosts to skip for the proxy configuration. | No |
|
||||||
|
| sts-endpoint | Custom STS endpoint URL. Use this to point to an STS-compatible API (e.g. MinIO, LocalStack) instead of the default AWS STS endpoint for the region. | No |
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
#### Adjust the retry mechanism
|
#### Adjust the retry mechanism
|
||||||
You can configure retry settings for if the STS call fails. By default, we
|
|
||||||
retry with exponential backoff `12` times. You can disable this behavior
|
You can configure retry settings for if the STS call fails. By default, we retry
|
||||||
altogether by setting the `disable-retry` input to `true`, or you can configure
|
with exponential backoff `12` times. You can disable this behavior altogether by
|
||||||
the number of times it retries with the `retry-max-attempts` input.
|
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
|
#### Mask account ID
|
||||||
|
|
||||||
Your account ID is not masked by default in workflow logs. You can set the
|
Your account ID is not masked by default in workflow logs. You can set the
|
||||||
`mask-aws-account-id` input to `true` to mask your account ID in workflow logs
|
`mask-aws-account-id` input to `true` to mask your account ID in workflow logs
|
||||||
if desired.
|
if desired.
|
||||||
|
|
||||||
#### Unset current credentials
|
#### Unset current credentials
|
||||||
|
|
||||||
Sometimes, existing credentials in your runner can get in the way of the
|
Sometimes, existing credentials in your runner can get in the way of the
|
||||||
intended outcome. You can set the `unset-current-credentials` input to `true` to
|
intended outcome. You can set the `unset-current-credentials` input to `true` to
|
||||||
work around this issue.
|
work around this issue.
|
||||||
|
|
||||||
|
#### Configure named AWS profiles
|
||||||
|
|
||||||
|
By default, this action exports credentials as environment variables
|
||||||
|
(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, etc.). However, you can use the
|
||||||
|
`aws-profile` input to configure named AWS profiles. When `aws-profile` is
|
||||||
|
provided, credentials are written to `~/.aws/credentials` and `~/.aws/config`
|
||||||
|
files (which are created if they don't already exist). The default locations of
|
||||||
|
these files will be overridden if the `AWS_SHARED_CREDENTIALS_FILE` and
|
||||||
|
`AWS_CONFIG_FILE` environment variables are present.
|
||||||
|
|
||||||
|
Profile names may not contain whitespace, square brackets, or forward or
|
||||||
|
backslashes.
|
||||||
|
|
||||||
|
Writing to a profile will prevent credentials being written to the environment
|
||||||
|
by default. Use `output-env-credentials: true` if you would like the credentials
|
||||||
|
to also be exported as environment variables.
|
||||||
|
|
||||||
|
By default, the action will not overwrite existing profiles. If you would like
|
||||||
|
to overwrite a profile, set the `overwrite-aws-profile` input to `true`.
|
||||||
|
|
||||||
|
_Note: When writing profiles, the action will preserve existing profile sections
|
||||||
|
in the credentials and config files. However, comments in these files will not
|
||||||
|
be preserved._
|
||||||
|
|
||||||
|
_Caution: Writing to the AWS configuration file means that credentials will
|
||||||
|
persist in the execution environment even after the action cleanup step. Use
|
||||||
|
extreme care to ensure that this is safe in your environment and you do not leak
|
||||||
|
valid credentials unintentionally. Writing to configuration files is intended
|
||||||
|
for unusual authentication scenarios._
|
||||||
|
|
||||||
|
For using profiles with static IAM User Credentials or when using one role to
|
||||||
|
assume another, role chaining is needed:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
If using static credentials, it's necessary to set `role-chaining: true` and
|
||||||
|
specify the profile name as an environment variable in the job step:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS Credentials
|
||||||
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
|
with:
|
||||||
|
aws-region: us-east-1
|
||||||
|
role-to-assume: arn:aws:iam::123456789100:role/my-role
|
||||||
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
|
aws-profile: MyProfile1
|
||||||
|
role-chaining: true
|
||||||
|
env:
|
||||||
|
AWS_PROFILE: MyProfile1
|
||||||
|
```
|
||||||
|
|
||||||
|
If you are using one role to assume another while using profiles, the subsequent
|
||||||
|
steps must set `role-chaining: true` and specify the prior profile's name as
|
||||||
|
step environment variables:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS credentials
|
||||||
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
|
with:
|
||||||
|
aws-region: us-east-1
|
||||||
|
role-to-assume: arn:aws:iam::123456789100:role/my-first-role
|
||||||
|
aws-profile: firstRoleInChain
|
||||||
|
|
||||||
|
- name: assume second role
|
||||||
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
|
with:
|
||||||
|
aws-region: us-east-2
|
||||||
|
role-to-assume: arn:aws:iam::987654321000:role/my-second-role
|
||||||
|
role-chaining: true
|
||||||
|
aws-profile: secondRoleInChain
|
||||||
|
env:
|
||||||
|
AWS_PROFILE: firstRoleInChain
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
See the [Examples](#examples) section for more usage examples.
|
||||||
|
|
||||||
|
#### Skip the cleanup
|
||||||
|
|
||||||
|
By default, this action runs a post-job cleanup step that removes credentials
|
||||||
|
from the environment. To skip this step, set the `AWS_SKIP_CLEANUP_STEP`
|
||||||
|
environment variable to `true`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
env:
|
||||||
|
AWS_SKIP_CLEANUP_STEP: "true"
|
||||||
|
```
|
||||||
|
|
||||||
#### Use an HTTP proxy
|
#### Use an HTTP proxy
|
||||||
|
|
||||||
If need use an HTTP proxy you can set it in the action manually. Additionally
|
If need use an HTTP proxy you can set it in the action manually. Additionally
|
||||||
@@ -180,8 +309,9 @@ this action will always consider the `HTTP_PROXY` environment variable.
|
|||||||
<summary>Proxy configuration</summary>
|
<summary>Proxy configuration</summary>
|
||||||
|
|
||||||
Manually configured proxy:
|
Manually configured proxy:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
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
|
||||||
@@ -189,16 +319,23 @@ with:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Proxy configured in the environment variable:
|
Proxy configured in the environment variable:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Your environment configuration
|
# Your environment configuration
|
||||||
HTTP_PROXY="http://companydomain.com:3128"
|
HTTP_PROXY="http://companydomain.com:3128"
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
#### Special characters in AWS_SECRET_ACCESS_KEY
|
#### Special characters in AWS_SECRET_ACCESS_KEY
|
||||||
|
|
||||||
Some edge cases are unable to properly parse an `AWS_SECRET_ACCESS_KEY` if it
|
Some edge cases are unable to properly parse an `AWS_SECRET_ACCESS_KEY` if it
|
||||||
contains special characters. For more information, please see the
|
contains special characters. For more information, please see the [AWS CLI
|
||||||
[AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-troubleshooting.html#tshoot-signature-does-not-match).
|
documentation][aws-cli-troubleshooting].
|
||||||
|
|
||||||
|
[aws-cli-troubleshooting]:
|
||||||
|
https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-troubleshooting.html#tshoot-signature-does-not-match
|
||||||
|
|
||||||
If you set the `special-characters-workaround` option, this action will
|
If you set the `special-characters-workaround` option, this action will
|
||||||
continually retry fetching credentials until we get one that does not have
|
continually retry fetching credentials until we get one that does not have
|
||||||
special characters. This option overrides the `disable-retry` and
|
special characters. This option overrides the `disable-retry` and
|
||||||
@@ -206,18 +343,22 @@ special characters. This option overrides the `disable-retry` and
|
|||||||
unless required, because retrying APIs infinitely until they succeed is not best
|
unless required, because retrying APIs infinitely until they succeed is not best
|
||||||
practice.
|
practice.
|
||||||
|
|
||||||
Session Naming and Policies
|
## Session Naming and Policies
|
||||||
---------------------------
|
|
||||||
The default session name is "GitHubActions", and you can modify it by specifying
|
The default session name is "GitHubActions", and you can modify it by specifying
|
||||||
the desired name in `role-session-name`.
|
the desired name in `role-session-name`.
|
||||||
|
|
||||||
*Note: you might find it helpful to set the `role-session-name` to `${{ github.run_id }}`
|
_Note: you might find it helpful to set the `role-session-name` to
|
||||||
so as to clarify in audit logs which AWS actions were performed by which workflow
|
`${{ github.run_id }}` so as to clarify in audit logs which AWS actions were
|
||||||
run.*
|
performed by which workflow run._
|
||||||
|
|
||||||
The session will be tagged with the
|
The session will be tagged with the following tags: (Refer to [GitHub's
|
||||||
following tags: (Refer to [GitHub's documentation for `GITHUB_` environment
|
documentation for `GITHUB_` environment variable definitions][gh-env-vars])
|
||||||
variable definitions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables))
|
|
||||||
|
[gh-env-vars]:
|
||||||
|
https://docs.github.com/en/actions/reference/workflows-and-actions/variables#default-environment-variables
|
||||||
|
|
||||||
|
**Default tags** are always emitted when session tags are used.
|
||||||
|
|
||||||
| Key | Value |
|
| Key | Value |
|
||||||
| ---------- | ----------------- |
|
| ---------- | ----------------- |
|
||||||
@@ -226,24 +367,89 @@ variable definitions](https://help.github.com/en/actions/automating-your-workflo
|
|||||||
| Workflow | GITHUB_WORKFLOW |
|
| Workflow | GITHUB_WORKFLOW |
|
||||||
| Action | GITHUB_ACTION |
|
| Action | GITHUB_ACTION |
|
||||||
| Actor | GITHUB_ACTOR |
|
| Actor | GITHUB_ACTOR |
|
||||||
| Branch | GITHUB_REF |
|
|
||||||
| Commit | GITHUB_SHA |
|
| Commit | GITHUB_SHA |
|
||||||
|
| Branch | GITHUB_REF |
|
||||||
|
|
||||||
|
**Droppable tags** are automatically added to the set of default session tags.
|
||||||
|
If the session tags exceed the [packed size limit][packed-size-limit], these
|
||||||
|
tags will be dropped, and the AssumeRole call will be retried. If it still
|
||||||
|
fails, the action will error out. (It is difficult to predict the packed size
|
||||||
|
before making the call, as session tags and session policies are compressed into
|
||||||
|
a binary format as part of the call.)
|
||||||
|
|
||||||
|
[packed-size-limit]:
|
||||||
|
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_know
|
||||||
|
|
||||||
|
| Key | Value |
|
||||||
|
| --------------- | ----------------------- |
|
||||||
|
| EventName | GITHUB_EVENT_NAME |
|
||||||
|
| BaseRef | GITHUB_BASE_REF |
|
||||||
|
| HeadRef | GITHUB_HEAD_REF |
|
||||||
|
| RunId | GITHUB_RUN_ID |
|
||||||
|
| Job | GITHUB_JOB |
|
||||||
|
| TriggeringActor | GITHUB_TRIGGERING_ACTOR |
|
||||||
|
|
||||||
|
Tags whose source environment variable is unset are omitted (e.g., `BaseRef` and
|
||||||
|
`HeadRef` are only set on `pull_request` events).
|
||||||
|
|
||||||
_Note: all tag values must conform to
|
_Note: all tag values must conform to
|
||||||
[the tag requirements](https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html).
|
[the tag requirements][sts-tag-requirements].
|
||||||
Particularly, `GITHUB_WORKFLOW` will be truncated if it's too long. If
|
Values longer than 256 characters will be truncated, and characters outside the
|
||||||
`GITHUB_ACTOR` or `GITHUB_WORKFLOW` contain invalid characters, the characters
|
allowed set will be replaced with an underscore (`_`)._
|
||||||
will be replaced with an '*'._
|
|
||||||
|
|
||||||
The action will use session tagging by default unless you are using OIDC.
|
[sts-tag-requirements]:
|
||||||
|
https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html
|
||||||
|
|
||||||
|
The action will use session tagging by default unless you are using OIDC or a
|
||||||
|
Web Identify Token File.
|
||||||
|
|
||||||
|
To [forward session tags to subsequent sessions in a role
|
||||||
|
chain][session-tag-chaining], you can use the `transitive-tag-keys` input to
|
||||||
|
specify the keys of the tags to be passed.
|
||||||
|
|
||||||
|
[session-tag-chaining]:
|
||||||
|
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining
|
||||||
|
|
||||||
|
_Note that all subsequent roles in the chain must have
|
||||||
|
`role-skip-session-tagging` set to `true`_
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
uses: aws-actions/configure-aws-credentials@v6
|
||||||
|
with:
|
||||||
|
transitive-tag-keys: |
|
||||||
|
Repository
|
||||||
|
Workflow
|
||||||
|
Action
|
||||||
|
Actor
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom session tags
|
||||||
|
|
||||||
|
You can add custom session tags using the `custom-tags` input, which accepts a
|
||||||
|
JSON object. Custom tags cannot override existing tags. Note that AWS allows a
|
||||||
|
maximum of 50 tags (so you can supply a maximum of 43 custom tags), although it
|
||||||
|
is likely that you will exceed the [packed size limit][packed-size-limit]
|
||||||
|
before you exceed the maximum number of tags.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
uses: aws-actions/configure-aws-credentials@v6
|
||||||
|
with:
|
||||||
|
custom-tags: '{"Environment": "Production", "Team": "Platform"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
_Note: custom tags are not supported when using OIDC or web identity token
|
||||||
|
authentication. In those flows, session tags are controlled by the identity
|
||||||
|
provider's token claims._
|
||||||
|
|
||||||
### Session policies
|
### Session policies
|
||||||
|
|
||||||
Session policies are not required, but they allow you to limit the scope of the
|
Session policies are not required, but they allow you to limit the scope of the
|
||||||
fetched credentials without making changes to IAM roles. You can specify inline
|
fetched credentials without making changes to IAM roles. You can specify inline
|
||||||
session policies right in your workflow file, or refer to an existing managed
|
session policies right in your workflow file, or refer to an existing managed
|
||||||
session policy by its ARN.
|
session policy by its ARN.
|
||||||
|
|
||||||
#### Inline session policies
|
#### Inline session policies
|
||||||
|
|
||||||
An IAM policy in stringified JSON format that you want to use as an inline
|
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
|
session policy. Depending on preferences, the JSON could be written on a single
|
||||||
line.
|
line.
|
||||||
@@ -252,13 +458,15 @@ line.
|
|||||||
<summary>Inline session policy examples</summary>
|
<summary>Inline session policy examples</summary>
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
inline-session-policy: '{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:List*","Resource":"*"}]}'
|
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:
|
Or we can have a nicely formatted JSON as well:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
inline-session-policy: >-
|
inline-session-policy: >-
|
||||||
{
|
{
|
||||||
@@ -273,9 +481,11 @@ Or we can have a nicely formatted JSON as well:
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
#### Managed session policies
|
#### Managed session policies
|
||||||
|
|
||||||
The Amazon Resource Names (ARNs) of the IAM managed policies that you want to
|
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
|
use as managed session policies. The policies must exist in the same account as
|
||||||
the role.
|
the role.
|
||||||
@@ -284,36 +494,46 @@ the role.
|
|||||||
<summary>Managed session policy examples</summary>
|
<summary>Managed session policy examples</summary>
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
managed-session-policies: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
managed-session-policies: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
||||||
```
|
```
|
||||||
|
|
||||||
And we can pass multiple managed policies likes this:
|
And we can pass multiple managed policies likes this:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
managed-session-policies: |
|
managed-session-policies: |
|
||||||
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
||||||
arn:aws:iam::aws:policy/AmazonS3OutpostsReadOnlyAccess
|
arn:aws:iam::aws:policy/AmazonS3OutpostsReadOnlyAccess
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
OIDC Configuration
|
### Custom STS endpoint
|
||||||
-------------------
|
|
||||||
We recommend using [GitHub's OIDC
|
Use the `sts-endpoint` input to override the AWS STS endpoint URL. Most users
|
||||||
provider](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)
|
should not set this option and instead let the SDK derive the correct endpoint
|
||||||
|
from the specified region.
|
||||||
|
|
||||||
|
## OIDC Configuration Details
|
||||||
|
|
||||||
|
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, you
|
to get short-lived AWS credentials needed for your actions. When using OIDC, you
|
||||||
configure IAM to accept JWTs from GitHub's OIDC endpoint. This action will
|
configure IAM to accept JWTs from GitHub's OIDC endpoint. This action will then
|
||||||
then create a JWT unique to the workflow run using the OIDC endpoint, and it
|
create a JWT unique to the workflow run using the OIDC endpoint, and it will use
|
||||||
will use the JWT to assume the specified role with short-term credentials.
|
the JWT to assume the specified role with short-term credentials.
|
||||||
|
|
||||||
To get this to work
|
To get this to work
|
||||||
|
|
||||||
1. Configure your workflow to use the `id-token: write` permission.
|
1. Configure your workflow to use the `id-token: write` permission.
|
||||||
2. Configure your audience, if required.
|
2. Configure your audience, if required.
|
||||||
3. In your AWS account, configure IAM to trust GitHub's OIDC identity provider.
|
3. In your AWS account, configure IAM to trust GitHub's OIDC identity provider.
|
||||||
4. Configure an IAM role with appropriate claim limits and permission scope.
|
4. Configure an IAM role with appropriate claim limits and permission scope.
|
||||||
|
|
||||||
*Note*: Naming your role "GitHubActions" has been reported to not work. See
|
_Note_: Naming your role "GitHubActions" has been reported to not work. See
|
||||||
[#953](https://github.com/aws-actions/configure-aws-credentials/issues/953).
|
[#953](https://github.com/aws-actions/configure-aws-credentials/issues/953).
|
||||||
|
|
||||||
5. Specify that role's ARN when setting up this action.
|
5. Specify that role's ARN when setting up this action.
|
||||||
@@ -322,13 +542,13 @@ To get this to work
|
|||||||
|
|
||||||
When the JWT is created, an audience needs to be specified. Normally, you would
|
When the JWT is created, an audience needs to be specified. Normally, you would
|
||||||
use `sts.amazonaws.com`, and this action uses this by default if you don't
|
use `sts.amazonaws.com`, and this action uses this by default if you don't
|
||||||
specify one. This will work for most cases. Changing the default audience may
|
specify one. This will work for most cases. Changing the default audience may be
|
||||||
be necessary when using non-default AWS partitions, such as China regions.
|
necessary when using non-default AWS partitions, such as China regions. You can
|
||||||
You can specify the audience through the `audience` input:
|
specify the audience through the `audience` input:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials for China region audience
|
- name: Configure AWS Credentials for China region audience
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
audience: sts.amazonaws.com.cn
|
audience: sts.amazonaws.com.cn
|
||||||
aws-region: cn-northwest-1
|
aws-region: cn-northwest-1
|
||||||
@@ -336,10 +556,12 @@ You can specify the audience through the `audience` input:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Configuring IAM to trust GitHub
|
### Configuring IAM to trust GitHub
|
||||||
|
|
||||||
To use GitHub's OIDC provider, you must first set up federation in your AWS
|
To use GitHub's OIDC provider, you must first set up federation in your AWS
|
||||||
account. This involves creating an IAM Identity Provider that trusts GitHub's
|
account. This involves creating an IAM Identity Provider that trusts GitHub's
|
||||||
OIDC endpoint. You can create an IAM Identity Provider in the AWS Management
|
OIDC endpoint. You can create an IAM Identity Provider in the AWS Management
|
||||||
Console by specifying the following details:
|
Console by specifying the following details:
|
||||||
|
|
||||||
- **Provider Type**: OIDC
|
- **Provider Type**: OIDC
|
||||||
- **Provider URL**: `https://token.actions.githubusercontent.com`
|
- **Provider URL**: `https://token.actions.githubusercontent.com`
|
||||||
- **Audience**: `sts.amazonaws.com` (or your custom audience if you specified
|
- **Audience**: `sts.amazonaws.com` (or your custom audience if you specified
|
||||||
@@ -358,88 +580,179 @@ aws iam create-open-id-connect-provider \
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Claims and scoping permissions
|
### Claims and scoping permissions
|
||||||
|
|
||||||
To align with the Amazon IAM best practice of [granting least
|
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),
|
privilege][least-privilege], the assume role policy document should contain a
|
||||||
the assume role policy document should contain a
|
|
||||||
[`Condition`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html)
|
[`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
|
that restricts which workflows can assume the role. Without any condition, any
|
||||||
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)
|
GitHub user or repository could potentially assume the role.
|
||||||
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.
|
|
||||||
|
|
||||||
Without a subject (`sub`) condition, any GitHub user or repository could
|
GitHub provides a number of additional claims in the OIDC token that you can use
|
||||||
potentially assume the role. The subject can be scoped to a GitHub organization
|
in your IAM policies to scope down permissions. Early versions of this action
|
||||||
and repository as shown in the CloudFormation template. However, scoping it down
|
only supported the `sub` and `aud` claims, but AWS IAM and GitHub have since
|
||||||
to your org and repo may cause the role assumption to fail in some cases. See
|
added support for `sub` claim customization and a variety of additional
|
||||||
[Example subject claims](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims)
|
claims ([1][gh-blog-oidc], [2][sub-claim-custom]).
|
||||||
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)
|
> **Warning:** Avoid `ForAllValues:` in `Allow` statements. These operators
|
||||||
if you want full control over the information you can filter for in your trust
|
> return true when the claim is absent or misspelled, which can lead to
|
||||||
policy. If you aren't sure what your subject (`sub`) key is, you can add the
|
> unintended access. Instead, use `StringEquals` or `StringLike` operators to
|
||||||
|
> check for specific claim values.
|
||||||
|
|
||||||
|
#### Immutable subject claims
|
||||||
|
|
||||||
|
Repositories created on github.com on or after 15 July 2026, and older
|
||||||
|
repositories that have opted in, emit an [immutable `sub` claim][immutable-sub].
|
||||||
|
This claim appends the permanent numeric ID of the organization and of the
|
||||||
|
repository after each name, separated by `@`, so that a recycled org or
|
||||||
|
repository name cannot be used to mint tokens matching a stale trust policy.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
# Legacy (mutable) sub claim
|
||||||
|
repo:octo-org/octo-repo:ref:refs/heads/main
|
||||||
|
|
||||||
|
# Immutable sub claim
|
||||||
|
repo:octo-org@123456/octo-repo@789012:ref:refs/heads/main
|
||||||
|
```
|
||||||
|
|
||||||
|
If your trust policy matches the legacy name-only form and your repository emits
|
||||||
|
the immutable claim, `AssumeRoleWithWebIdentity` fails with `Not authorized to
|
||||||
|
perform sts:AssumeRoleWithWebIdentity`. To fix this, update the `sub` condition
|
||||||
|
to the immutable form. You can find your repository's prefix in the Settings,
|
||||||
|
or by following the token inspection steps below.
|
||||||
|
|
||||||
|
[least-privilege]:
|
||||||
|
https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege
|
||||||
|
[gh-blog-oidc]:
|
||||||
|
https://aws.amazon.com/about-aws/whats-new/2026/01/aws-sts-supports-validation-identity-provider-claims/
|
||||||
|
[sub-claim-custom]:
|
||||||
|
https://docs.github.com/en/rest/actions/oidc?apiVersion=2026-03-10
|
||||||
|
|
||||||
|
#### Inspecting the token
|
||||||
|
|
||||||
|
If you aren't sure what claim values your workflow is producing, the
|
||||||
[`actions-oidc-debugger`](https://github.com/github/actions-oidc-debugger)
|
[`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
|
action will print the decoded JWT payload. Run it in a private repository
|
||||||
other claims.
|
only; the token itself is short-lived but the claim values may be sensitive.
|
||||||
|
|
||||||
Additional claim conditions can be added for higher specificity as explained in
|
See the GitHub [security-hardening guide][gh-oidc-hardening] for further
|
||||||
the [GitHub documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect).
|
discussion of trust conditions and threat modeling.
|
||||||
Due to implementation details, not every OIDC claim is presently supported by
|
|
||||||
IAM.
|
[gh-oidc-hardening]:
|
||||||
|
https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect
|
||||||
|
|
||||||
### Further information about OIDC
|
### Further information about OIDC
|
||||||
|
|
||||||
For further information on OIDC and GitHub Actions, please see:
|
For further information on OIDC and GitHub Actions, please see:
|
||||||
|
|
||||||
* [AWS docs: Creating OpenID Connect (OIDC) identity providers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)
|
- [AWS docs: Creating OpenID Connect (OIDC) identity providers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)
|
||||||
* [AWS docs: IAM JSON policy elements: Condition](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html)
|
- [AWS docs: IAM JSON policy elements: Condition](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html)
|
||||||
* [GitHub docs: About security hardening with OpenID Connect](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
- [GitHub docs: About security hardening with OpenID Connect](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
||||||
* [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/)
|
||||||
|
|
||||||
Examples
|
## Getting Credentials in AWS Self-Hosted Runners
|
||||||
--------
|
|
||||||
|
If you are running GitHub Actions in a self-hosted runner using an AWS Service
|
||||||
|
(such as Codebuild or EKS) and you have properly configured the service,
|
||||||
|
credentials should be available by default; the AWS CLI will fetch credentials
|
||||||
|
using the AWS_CONTAINER_CREDENTIALS_FULL_URI or
|
||||||
|
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables. However, you may
|
||||||
|
still want to use this action if you need to export those credentials for use
|
||||||
|
with other tools in your workflow. You may also want to use this action in
|
||||||
|
scenarios where you need to use that 'default' role to assume another role.
|
||||||
|
|
||||||
|
To export credentials, simply run the action with `role-to-assume` set to the
|
||||||
|
default role of the container.
|
||||||
|
|
||||||
|
To assume another role from the container's default role, use the
|
||||||
|
`role-chaining: true` flag, so that the action fetches the default credentials
|
||||||
|
from the environment before assuming the other role.
|
||||||
|
|
||||||
|
If you are using EKS Pod Identities and encountering an error related to the
|
||||||
|
packed size of session tags, you must either run the action with
|
||||||
|
`role-skip-session-tagging: true` to disable the tags set by the action, or
|
||||||
|
[disable EKS session tagging][eks-disable-session-tagging] in the EKS settings
|
||||||
|
to disable the tags that are automatically set by the EKS Pod Identity Service.
|
||||||
|
Check the values of the action's session tags and the session tags that are
|
||||||
|
added by EKS so you can keep the set of tags which is more useful to you.
|
||||||
|
|
||||||
|
[eks-disable-session-tagging]:
|
||||||
|
https://docs.aws.amazon.com/eks/latest/userguide/pod-id-abac.html#pod-id-abac-tags
|
||||||
|
|
||||||
|
## Compatibility with non-GitHub Actions environments
|
||||||
|
|
||||||
|
This action has been sucessfully tested with
|
||||||
|
Codeberg/[Forgejo Actions](https://forgejo.org/docs/next/user/actions/overview/)
|
||||||
|
and should be generally compatible with any CI/CD environment that sets the
|
||||||
|
correct `GITHUB_` environment variables. For use with Foregejo, please review
|
||||||
|
the
|
||||||
|
[runner differences with GitHub's action runners][forgejo-gh-differences].
|
||||||
|
|
||||||
|
[forgejo-gh-differences]:
|
||||||
|
https://forgejo.org/docs/next/user/actions/github-actions/#known-list-of-differences
|
||||||
|
The main difference to be aware of is that Forgejo uses the
|
||||||
|
`enable-openid-connect` flag to enable OIDC instad of GitHub's `id-token: write`
|
||||||
|
permission. Forgejo also uses a slightly different syntax for the workflow
|
||||||
|
definition file, omitting some subkeys.
|
||||||
|
|
||||||
|
For OIDC use, the issuer name for the IAM IdP for GitHub Actions is
|
||||||
|
`token.actions.githubusercontent.com`. For Forgejo Actions it is
|
||||||
|
`[foregejo instance url]/api/actions`. As an example, Codeberg would use
|
||||||
|
`codeberg.org/api/actions` as the issuer URL when configuring the IAM Identity
|
||||||
|
Provider. The audience would still be `sts.amazonaws.com` by default.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
### AssumeRoleWithWebIdentity
|
### AssumeRoleWithWebIdentity
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
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
|
role-session-name: MySessionName
|
||||||
```
|
```
|
||||||
|
|
||||||
In this example, the Action will load the OIDC token from the GitHub-provided
|
In this example, the Action will load the OIDC token from the GitHub-provided
|
||||||
environment variable and use it to assume the role
|
environment variable and use it to assume the role
|
||||||
`arn:aws:iam::123456789100:role/my-github-actions-role` with the session name
|
`arn:aws:iam::123456789100:role/my-github-actions-role` with the session name
|
||||||
`MySessionName`.
|
`MySessionName`.
|
||||||
|
|
||||||
### AssumeRole with role previously assumed by action in same workflow
|
### AssumeRole with role previously assumed by action in same workflow
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
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
|
role-session-name: MySessionName
|
||||||
- name: Configure other AWS Credentials
|
- name: Configure other AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
role-to-assume: arn:aws:iam::987654321000:role/my-second-role
|
role-to-assume: arn:aws:iam::987654321000:role/my-second-role
|
||||||
role-session-name: MySessionName
|
role-session-name: MySessionName
|
||||||
role-chaining: true
|
role-chaining: true
|
||||||
```
|
```
|
||||||
|
|
||||||
In this two-step example, the first step will use OIDC to assume the role
|
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
|
`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
|
example. Following that, a second step will use this role to assume a different
|
||||||
role, `arn:aws:iam::987654321000:role/my-second-role`.
|
role, `arn:aws:iam::987654321000:role/my-second-role`.
|
||||||
|
|
||||||
Note that the trust relationship/trust policy of the second role must grant the permissions `sts:AssumeRole` and `sts:TagSession` to the first role. (Or, alternatively, the `TagSession` permission can be omitted if you are using the `role-skip-session-tagging: true` flag for the second step.)
|
Note that the trust relationship/trust policy of the second role must grant the
|
||||||
|
permissions `sts:AssumeRole` and `sts:TagSession` to the first role. (Or,
|
||||||
|
alternatively, the `TagSession` permission can be omitted if you are using the
|
||||||
|
`role-skip-session-tagging: true` flag for the second step.)
|
||||||
|
|
||||||
### AssumeRole with static IAM credentials in repository secrets
|
### AssumeRole with static IAM credentials in repository secrets
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||||
@@ -449,16 +762,18 @@ Note that the trust relationship/trust policy of the second role must grant the
|
|||||||
role-duration-seconds: 1200
|
role-duration-seconds: 1200
|
||||||
role-session-name: MySessionName
|
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
|
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
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Configure AWS Credentials 1
|
- name: Configure AWS Credentials 1
|
||||||
id: creds
|
id: creds
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||||
@@ -467,7 +782,7 @@ name, like `role-to-assume: my-github-actions-role`.
|
|||||||
run: |
|
run: |
|
||||||
aws sts get-caller-identity
|
aws sts get-caller-identity
|
||||||
- name: Configure AWS Credentials 2
|
- name: Configure AWS Credentials 2
|
||||||
uses: aws-actions/configure-aws-credentials@v5.1.0
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
with:
|
with:
|
||||||
aws-region: us-east-2
|
aws-region: us-east-2
|
||||||
aws-access-key-id: ${{ steps.creds.outputs.aws-access-key-id }}
|
aws-access-key-id: ${{ steps.creds.outputs.aws-access-key-id }}
|
||||||
@@ -478,25 +793,79 @@ name, like `role-to-assume: my-github-actions-role`.
|
|||||||
run: |
|
run: |
|
||||||
aws sts get-caller-identity
|
aws sts get-caller-identity
|
||||||
```
|
```
|
||||||
|
|
||||||
This example shows that you can reference the fetched credentials as outputs if
|
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
|
`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
|
the `aws-session-token` input in a situation where session tokens are fetched
|
||||||
and passed to this action.
|
and passed to this action.
|
||||||
|
|
||||||
Versioning
|
If you only want the credentials available as _step outputs_ and not exported to
|
||||||
----------
|
the environment (for example, on a self-hosted runner where you do not want the
|
||||||
Starting with version 5.0.0, this action uses semantic-style release tags and
|
assumed-role credentials to shadow an existing EC2 instance profile), pair
|
||||||
[immutable releases](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases).
|
`output-credentials: true` with `output-env-credentials: false`. In that mode,
|
||||||
A floating version tag (vN) is also provided for convenience: this tag will
|
the action does not run its post-credential SDK-pickup validation step, since
|
||||||
move to the latest major version (vN -> vN.2.1, vM -> vM.0.0, etc.).
|
the credentials were never written to the environment. The action still
|
||||||
|
validates the resolved credentials by calling `sts:GetCallerIdentity` with the
|
||||||
|
explicit credentials, so the `allowed-account-ids` check can be enforced if
|
||||||
|
provided.
|
||||||
|
|
||||||
|
### Configure multiple AWS profiles in a single workflow
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Configure AWS Credentials for Dev
|
||||||
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
|
with:
|
||||||
|
aws-region: us-east-1
|
||||||
|
role-to-assume: arn:aws:iam::111111111111:role/dev-role
|
||||||
|
aws-profile: dev
|
||||||
|
|
||||||
|
- name: Configure AWS Credentials for Prod
|
||||||
|
uses: aws-actions/configure-aws-credentials@v6.1.0
|
||||||
|
with:
|
||||||
|
aws-region: us-west-2
|
||||||
|
role-to-assume: arn:aws:iam::222222222222:role/prod-role
|
||||||
|
aws-profile: prod
|
||||||
|
|
||||||
|
- name: Use multiple profiles
|
||||||
|
run: |
|
||||||
|
# Check caller identity for dev account
|
||||||
|
aws sts get-caller-identity --profile dev
|
||||||
|
|
||||||
|
# Check caller identity for prod account
|
||||||
|
aws sts get-caller-identity --profile prod
|
||||||
|
|
||||||
|
# Deploy to dev using CDK
|
||||||
|
cdk deploy --profile dev
|
||||||
|
```
|
||||||
|
|
||||||
|
This example shows how to configure multiple named AWS profiles in a single
|
||||||
|
workflow. When using the `aws-profile` input, credentials are written to
|
||||||
|
`~/.aws/credentials` and `~/.aws/config` files, allowing you to reference
|
||||||
|
different profiles using the `--profile` flag with AWS CLI, SDKs, CDK, and other
|
||||||
|
tools.
|
||||||
|
|
||||||
|
Each profile is independent and can authenticate to different AWS accounts or
|
||||||
|
use different roles. This is particularly useful for multi-account deployments
|
||||||
|
or when you need to interact with multiple AWS environments in a single job.
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
Starting with version 5.0.0, this action uses semantic-style release tags and
|
||||||
|
[immutable releases][immutable-releases].
|
||||||
|
|
||||||
|
[immutable-releases]:
|
||||||
|
https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases
|
||||||
|
|
||||||
|
A floating version tag (vN) is also provided for convenience: this tag will move
|
||||||
|
to the latest major version (vN -> vN.2.1, vM -> vM.0.0, etc.).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
This code is made available under the MIT license.
|
This code is made available under the MIT license.
|
||||||
|
|
||||||
Security Disclosures
|
## Security Disclosures
|
||||||
--------------------
|
|
||||||
If you would like to report a potential security issue in this project, please
|
If you would like to report a potential security issue in this project, please
|
||||||
do not create a GitHub issue. Instead, please follow the instructions
|
do not create a GitHub issue. Instead, please follow the instructions
|
||||||
[here](https://aws.amazon.com/security/vulnerability-reporting/) or
|
[on the vulnerability reporting page](https://aws.amazon.com/security/vulnerability-reporting/)
|
||||||
[email AWS security](mailto:aws-security@amazon.com) directly.
|
or [email AWS security](mailto:aws-security@amazon.com) directly.
|
||||||
|
|||||||
+1254
-10724
File diff suppressed because it is too large
Load Diff
+17
-3
@@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
name: '"Configure AWS Credentials" Action for GitHub Actions'
|
name: '"Configure AWS Credentials" Action for GitHub Actions'
|
||||||
description: Configures AWS credentials for use in subsequent steps in a GitHub Action workflow
|
description: Configures AWS credentials for use in subsequent steps in a GitHub Action workflow
|
||||||
runs:
|
runs:
|
||||||
using: node20
|
using: node24
|
||||||
main: dist/index.js
|
main: dist/index.js
|
||||||
post: dist/cleanup/index.js
|
post: dist/cleanup/index.js
|
||||||
|
post-if: env.AWS_SKIP_CLEANUP_STEP != 'true'
|
||||||
branding:
|
branding:
|
||||||
color: orange
|
color: orange
|
||||||
icon: cloud
|
icon: cloud
|
||||||
@@ -12,6 +12,12 @@ inputs:
|
|||||||
aws-region:
|
aws-region:
|
||||||
description: AWS Region, e.g. us-east-2
|
description: AWS Region, e.g. us-east-2
|
||||||
required: true
|
required: true
|
||||||
|
aws-profile:
|
||||||
|
description: Name of the AWS profile to configure. When provided, credentials are written to ~/.aws/credentials and ~/.aws/config files instead of env variables (unless output-env-credentials is manually set to true). Name cannot contain whitespace, square brackets, or slashes.
|
||||||
|
required: false
|
||||||
|
overwrite-aws-profile:
|
||||||
|
description: Overwrite the given AWS profile if it already exists. Requires aws-profile. When set to false or not set, an error will be thrown if the profile already exists.
|
||||||
|
required: false
|
||||||
role-to-assume:
|
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.
|
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
|
||||||
@@ -55,6 +61,9 @@ inputs:
|
|||||||
role-skip-session-tagging:
|
role-skip-session-tagging:
|
||||||
description: Skip session tagging during role assumption
|
description: Skip session tagging during role assumption
|
||||||
required: false
|
required: false
|
||||||
|
transitive-tag-keys:
|
||||||
|
description: Define a list of transitive tag keys to pass when assuming a role
|
||||||
|
required: false
|
||||||
inline-session-policy:
|
inline-session-policy:
|
||||||
description: Define an inline session policy to use when assuming a role
|
description: Define an inline session policy to use when assuming a role
|
||||||
required: false
|
required: false
|
||||||
@@ -67,7 +76,6 @@ inputs:
|
|||||||
output-env-credentials:
|
output-env-credentials:
|
||||||
description: Whether to export credentials as environment variables. If you set this to false, you probably want to use output-credentials.
|
description: Whether to export credentials as environment variables. If you set this to false, you probably want to use output-credentials.
|
||||||
required: false
|
required: false
|
||||||
default: true
|
|
||||||
unset-current-credentials:
|
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
|
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
|
required: false
|
||||||
@@ -92,6 +100,12 @@ inputs:
|
|||||||
action-timeout-s:
|
action-timeout-s:
|
||||||
required: false
|
required: false
|
||||||
description: A global timeout in seconds for the action. When the timeout is reached, the action immediately exits. The default is to run without a timeout.
|
description: A global timeout in seconds for the action. When the timeout is reached, the action immediately exits. The default is to run without a timeout.
|
||||||
|
custom-tags:
|
||||||
|
description: Additional tags to apply to the assumed role session. Must be a JSON object provided as a string.
|
||||||
|
required: false
|
||||||
|
sts-endpoint:
|
||||||
|
description: Custom STS endpoint URL. Use this to point to an STS-compatible API (e.g. MinIO, LocalStack) instead of the default AWS STS endpoint for the region.
|
||||||
|
required: false
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
aws-account-id:
|
aws-account-id:
|
||||||
|
|||||||
-56
@@ -1,56 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 121;
|
|
||||||
exports.ids = [121];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 7121:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
var __webpack_unused_export__;
|
|
||||||
|
|
||||||
|
|
||||||
var client = __webpack_require__(5152);
|
|
||||||
var propertyProvider = __webpack_require__(1238);
|
|
||||||
|
|
||||||
const ENV_KEY = "AWS_ACCESS_KEY_ID";
|
|
||||||
const ENV_SECRET = "AWS_SECRET_ACCESS_KEY";
|
|
||||||
const ENV_SESSION = "AWS_SESSION_TOKEN";
|
|
||||||
const ENV_EXPIRATION = "AWS_CREDENTIAL_EXPIRATION";
|
|
||||||
const ENV_CREDENTIAL_SCOPE = "AWS_CREDENTIAL_SCOPE";
|
|
||||||
const ENV_ACCOUNT_ID = "AWS_ACCOUNT_ID";
|
|
||||||
const fromEnv = (init) => async () => {
|
|
||||||
init?.logger?.debug("@aws-sdk/credential-provider-env - fromEnv");
|
|
||||||
const accessKeyId = process.env[ENV_KEY];
|
|
||||||
const secretAccessKey = process.env[ENV_SECRET];
|
|
||||||
const sessionToken = process.env[ENV_SESSION];
|
|
||||||
const expiry = process.env[ENV_EXPIRATION];
|
|
||||||
const credentialScope = process.env[ENV_CREDENTIAL_SCOPE];
|
|
||||||
const accountId = process.env[ENV_ACCOUNT_ID];
|
|
||||||
if (accessKeyId && secretAccessKey) {
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId,
|
|
||||||
secretAccessKey,
|
|
||||||
...(sessionToken && { sessionToken }),
|
|
||||||
...(expiry && { expiration: new Date(expiry) }),
|
|
||||||
...(credentialScope && { credentialScope }),
|
|
||||||
...(accountId && { accountId }),
|
|
||||||
};
|
|
||||||
client.setCredentialFeature(credentials, "CREDENTIALS_ENV_VARS", "g");
|
|
||||||
return credentials;
|
|
||||||
}
|
|
||||||
throw new propertyProvider.CredentialsProviderError("Unable to find environment variable credentials.", { logger: init?.logger });
|
|
||||||
};
|
|
||||||
|
|
||||||
__webpack_unused_export__ = ENV_ACCOUNT_ID;
|
|
||||||
__webpack_unused_export__ = ENV_CREDENTIAL_SCOPE;
|
|
||||||
__webpack_unused_export__ = ENV_EXPIRATION;
|
|
||||||
__webpack_unused_export__ = ENV_KEY;
|
|
||||||
__webpack_unused_export__ = ENV_SECRET;
|
|
||||||
__webpack_unused_export__ = ENV_SESSION;
|
|
||||||
exports.fromEnv = fromEnv;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-903
@@ -1,903 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 136;
|
|
||||||
exports.ids = [136];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 3723:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.STSClient = exports.__Client = void 0;
|
|
||||||
const middleware_host_header_1 = __webpack_require__(2590);
|
|
||||||
const middleware_logger_1 = __webpack_require__(5242);
|
|
||||||
const middleware_recursion_detection_1 = __webpack_require__(1568);
|
|
||||||
const middleware_user_agent_1 = __webpack_require__(2959);
|
|
||||||
const config_resolver_1 = __webpack_require__(9316);
|
|
||||||
const core_1 = __webpack_require__(402);
|
|
||||||
const schema_1 = __webpack_require__(6890);
|
|
||||||
const middleware_content_length_1 = __webpack_require__(7212);
|
|
||||||
const middleware_endpoint_1 = __webpack_require__(99);
|
|
||||||
const middleware_retry_1 = __webpack_require__(9618);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
Object.defineProperty(exports, "__Client", ({ enumerable: true, get: function () { return smithy_client_1.Client; } }));
|
|
||||||
const httpAuthSchemeProvider_1 = __webpack_require__(7851);
|
|
||||||
const EndpointParameters_1 = __webpack_require__(6811);
|
|
||||||
const runtimeConfig_1 = __webpack_require__(6578);
|
|
||||||
const runtimeExtensions_1 = __webpack_require__(7742);
|
|
||||||
class STSClient extends smithy_client_1.Client {
|
|
||||||
config;
|
|
||||||
constructor(...[configuration]) {
|
|
||||||
const _config_0 = (0, runtimeConfig_1.getRuntimeConfig)(configuration || {});
|
|
||||||
super(_config_0);
|
|
||||||
this.initConfig = _config_0;
|
|
||||||
const _config_1 = (0, EndpointParameters_1.resolveClientEndpointParameters)(_config_0);
|
|
||||||
const _config_2 = (0, middleware_user_agent_1.resolveUserAgentConfig)(_config_1);
|
|
||||||
const _config_3 = (0, middleware_retry_1.resolveRetryConfig)(_config_2);
|
|
||||||
const _config_4 = (0, config_resolver_1.resolveRegionConfig)(_config_3);
|
|
||||||
const _config_5 = (0, middleware_host_header_1.resolveHostHeaderConfig)(_config_4);
|
|
||||||
const _config_6 = (0, middleware_endpoint_1.resolveEndpointConfig)(_config_5);
|
|
||||||
const _config_7 = (0, httpAuthSchemeProvider_1.resolveHttpAuthSchemeConfig)(_config_6);
|
|
||||||
const _config_8 = (0, runtimeExtensions_1.resolveRuntimeExtensions)(_config_7, configuration?.extensions || []);
|
|
||||||
this.config = _config_8;
|
|
||||||
this.middlewareStack.use((0, schema_1.getSchemaSerdePlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_user_agent_1.getUserAgentPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_retry_1.getRetryPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_content_length_1.getContentLengthPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_host_header_1.getHostHeaderPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_logger_1.getLoggerPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_recursion_detection_1.getRecursionDetectionPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, core_1.getHttpAuthSchemeEndpointRuleSetPlugin)(this.config, {
|
|
||||||
httpAuthSchemeParametersProvider: httpAuthSchemeProvider_1.defaultSTSHttpAuthSchemeParametersProvider,
|
|
||||||
identityProviderConfigProvider: async (config) => new core_1.DefaultIdentityProviderConfig({
|
|
||||||
"aws.auth#sigv4": config.credentials,
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
this.middlewareStack.use((0, core_1.getHttpSigningPlugin)(this.config));
|
|
||||||
}
|
|
||||||
destroy() {
|
|
||||||
super.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.STSClient = STSClient;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 4532:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.resolveHttpAuthRuntimeConfig = exports.getHttpAuthExtensionConfiguration = void 0;
|
|
||||||
const getHttpAuthExtensionConfiguration = (runtimeConfig) => {
|
|
||||||
const _httpAuthSchemes = runtimeConfig.httpAuthSchemes;
|
|
||||||
let _httpAuthSchemeProvider = runtimeConfig.httpAuthSchemeProvider;
|
|
||||||
let _credentials = runtimeConfig.credentials;
|
|
||||||
return {
|
|
||||||
setHttpAuthScheme(httpAuthScheme) {
|
|
||||||
const index = _httpAuthSchemes.findIndex((scheme) => scheme.schemeId === httpAuthScheme.schemeId);
|
|
||||||
if (index === -1) {
|
|
||||||
_httpAuthSchemes.push(httpAuthScheme);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_httpAuthSchemes.splice(index, 1, httpAuthScheme);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
httpAuthSchemes() {
|
|
||||||
return _httpAuthSchemes;
|
|
||||||
},
|
|
||||||
setHttpAuthSchemeProvider(httpAuthSchemeProvider) {
|
|
||||||
_httpAuthSchemeProvider = httpAuthSchemeProvider;
|
|
||||||
},
|
|
||||||
httpAuthSchemeProvider() {
|
|
||||||
return _httpAuthSchemeProvider;
|
|
||||||
},
|
|
||||||
setCredentials(credentials) {
|
|
||||||
_credentials = credentials;
|
|
||||||
},
|
|
||||||
credentials() {
|
|
||||||
return _credentials;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getHttpAuthExtensionConfiguration = getHttpAuthExtensionConfiguration;
|
|
||||||
const resolveHttpAuthRuntimeConfig = (config) => {
|
|
||||||
return {
|
|
||||||
httpAuthSchemes: config.httpAuthSchemes(),
|
|
||||||
httpAuthSchemeProvider: config.httpAuthSchemeProvider(),
|
|
||||||
credentials: config.credentials(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.resolveHttpAuthRuntimeConfig = resolveHttpAuthRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 7851:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.resolveHttpAuthSchemeConfig = exports.resolveStsAuthConfig = exports.defaultSTSHttpAuthSchemeProvider = exports.defaultSTSHttpAuthSchemeParametersProvider = void 0;
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const util_middleware_1 = __webpack_require__(6324);
|
|
||||||
const STSClient_1 = __webpack_require__(3723);
|
|
||||||
const defaultSTSHttpAuthSchemeParametersProvider = async (config, context, input) => {
|
|
||||||
return {
|
|
||||||
operation: (0, util_middleware_1.getSmithyContext)(context).operation,
|
|
||||||
region: (await (0, util_middleware_1.normalizeProvider)(config.region)()) ||
|
|
||||||
(() => {
|
|
||||||
throw new Error("expected `region` to be configured for `aws.auth#sigv4`");
|
|
||||||
})(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.defaultSTSHttpAuthSchemeParametersProvider = defaultSTSHttpAuthSchemeParametersProvider;
|
|
||||||
function createAwsAuthSigv4HttpAuthOption(authParameters) {
|
|
||||||
return {
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
signingProperties: {
|
|
||||||
name: "sts",
|
|
||||||
region: authParameters.region,
|
|
||||||
},
|
|
||||||
propertiesExtractor: (config, context) => ({
|
|
||||||
signingProperties: {
|
|
||||||
config,
|
|
||||||
context,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function createSmithyApiNoAuthHttpAuthOption(authParameters) {
|
|
||||||
return {
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const defaultSTSHttpAuthSchemeProvider = (authParameters) => {
|
|
||||||
const options = [];
|
|
||||||
switch (authParameters.operation) {
|
|
||||||
case "AssumeRoleWithWebIdentity": {
|
|
||||||
options.push(createSmithyApiNoAuthHttpAuthOption(authParameters));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
options.push(createAwsAuthSigv4HttpAuthOption(authParameters));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
exports.defaultSTSHttpAuthSchemeProvider = defaultSTSHttpAuthSchemeProvider;
|
|
||||||
const resolveStsAuthConfig = (input) => Object.assign(input, {
|
|
||||||
stsClientCtor: STSClient_1.STSClient,
|
|
||||||
});
|
|
||||||
exports.resolveStsAuthConfig = resolveStsAuthConfig;
|
|
||||||
const resolveHttpAuthSchemeConfig = (config) => {
|
|
||||||
const config_0 = (0, exports.resolveStsAuthConfig)(config);
|
|
||||||
const config_1 = (0, core_1.resolveAwsSdkSigV4Config)(config_0);
|
|
||||||
return Object.assign(config_1, {
|
|
||||||
authSchemePreference: (0, util_middleware_1.normalizeProvider)(config.authSchemePreference ?? []),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
exports.resolveHttpAuthSchemeConfig = resolveHttpAuthSchemeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 6811:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.commonParams = exports.resolveClientEndpointParameters = void 0;
|
|
||||||
const resolveClientEndpointParameters = (options) => {
|
|
||||||
return Object.assign(options, {
|
|
||||||
useDualstackEndpoint: options.useDualstackEndpoint ?? false,
|
|
||||||
useFipsEndpoint: options.useFipsEndpoint ?? false,
|
|
||||||
useGlobalEndpoint: options.useGlobalEndpoint ?? false,
|
|
||||||
defaultSigningName: "sts",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
exports.resolveClientEndpointParameters = resolveClientEndpointParameters;
|
|
||||||
exports.commonParams = {
|
|
||||||
UseGlobalEndpoint: { type: "builtInParams", name: "useGlobalEndpoint" },
|
|
||||||
UseFIPS: { type: "builtInParams", name: "useFipsEndpoint" },
|
|
||||||
Endpoint: { type: "builtInParams", name: "endpoint" },
|
|
||||||
Region: { type: "builtInParams", name: "region" },
|
|
||||||
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9765:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.defaultEndpointResolver = void 0;
|
|
||||||
const util_endpoints_1 = __webpack_require__(3068);
|
|
||||||
const util_endpoints_2 = __webpack_require__(9674);
|
|
||||||
const ruleset_1 = __webpack_require__(1670);
|
|
||||||
const cache = new util_endpoints_2.EndpointCache({
|
|
||||||
size: 50,
|
|
||||||
params: ["Endpoint", "Region", "UseDualStack", "UseFIPS", "UseGlobalEndpoint"],
|
|
||||||
});
|
|
||||||
const defaultEndpointResolver = (endpointParams, context = {}) => {
|
|
||||||
return cache.get(endpointParams, () => (0, util_endpoints_2.resolveEndpoint)(ruleset_1.ruleSet, {
|
|
||||||
endpointParams: endpointParams,
|
|
||||||
logger: context.logger,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
exports.defaultEndpointResolver = defaultEndpointResolver;
|
|
||||||
util_endpoints_2.customEndpointFunctions.aws = util_endpoints_1.awsEndpointFunctions;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 1670:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.ruleSet = void 0;
|
|
||||||
const F = "required", G = "type", H = "fn", I = "argv", J = "ref";
|
|
||||||
const a = false, b = true, c = "booleanEquals", d = "stringEquals", e = "sigv4", f = "sts", g = "us-east-1", h = "endpoint", i = "https://sts.{Region}.{PartitionResult#dnsSuffix}", j = "tree", k = "error", l = "getAttr", m = { [F]: false, [G]: "string" }, n = { [F]: true, "default": false, [G]: "boolean" }, o = { [J]: "Endpoint" }, p = { [H]: "isSet", [I]: [{ [J]: "Region" }] }, q = { [J]: "Region" }, r = { [H]: "aws.partition", [I]: [q], "assign": "PartitionResult" }, s = { [J]: "UseFIPS" }, t = { [J]: "UseDualStack" }, u = { "url": "https://sts.amazonaws.com", "properties": { "authSchemes": [{ "name": e, "signingName": f, "signingRegion": g }] }, "headers": {} }, v = {}, w = { "conditions": [{ [H]: d, [I]: [q, "aws-global"] }], [h]: u, [G]: h }, x = { [H]: c, [I]: [s, true] }, y = { [H]: c, [I]: [t, true] }, z = { [H]: l, [I]: [{ [J]: "PartitionResult" }, "supportsFIPS"] }, A = { [J]: "PartitionResult" }, B = { [H]: c, [I]: [true, { [H]: l, [I]: [A, "supportsDualStack"] }] }, C = [{ [H]: "isSet", [I]: [o] }], D = [x], E = [y];
|
|
||||||
const _data = { version: "1.0", parameters: { Region: m, UseDualStack: n, UseFIPS: n, Endpoint: m, UseGlobalEndpoint: n }, rules: [{ conditions: [{ [H]: c, [I]: [{ [J]: "UseGlobalEndpoint" }, b] }, { [H]: "not", [I]: C }, p, r, { [H]: c, [I]: [s, a] }, { [H]: c, [I]: [t, a] }], rules: [{ conditions: [{ [H]: d, [I]: [q, "ap-northeast-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "ap-south-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "ap-southeast-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "ap-southeast-2"] }], endpoint: u, [G]: h }, w, { conditions: [{ [H]: d, [I]: [q, "ca-central-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-central-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-north-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-west-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-west-2"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-west-3"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "sa-east-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, g] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "us-east-2"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "us-west-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "us-west-2"] }], endpoint: u, [G]: h }, { endpoint: { url: i, properties: { authSchemes: [{ name: e, signingName: f, signingRegion: "{Region}" }] }, headers: v }, [G]: h }], [G]: j }, { conditions: C, rules: [{ conditions: D, error: "Invalid Configuration: FIPS and custom endpoint are not supported", [G]: k }, { conditions: E, error: "Invalid Configuration: Dualstack and custom endpoint are not supported", [G]: k }, { endpoint: { url: o, properties: v, headers: v }, [G]: h }], [G]: j }, { conditions: [p], rules: [{ conditions: [r], rules: [{ conditions: [x, y], rules: [{ conditions: [{ [H]: c, [I]: [b, z] }, B], rules: [{ endpoint: { url: "https://sts-fips.{Region}.{PartitionResult#dualStackDnsSuffix}", properties: v, headers: v }, [G]: h }], [G]: j }, { error: "FIPS and DualStack are enabled, but this partition does not support one or both", [G]: k }], [G]: j }, { conditions: D, rules: [{ conditions: [{ [H]: c, [I]: [z, b] }], rules: [{ conditions: [{ [H]: d, [I]: [{ [H]: l, [I]: [A, "name"] }, "aws-us-gov"] }], endpoint: { url: "https://sts.{Region}.amazonaws.com", properties: v, headers: v }, [G]: h }, { endpoint: { url: "https://sts-fips.{Region}.{PartitionResult#dnsSuffix}", properties: v, headers: v }, [G]: h }], [G]: j }, { error: "FIPS is enabled but this partition does not support FIPS", [G]: k }], [G]: j }, { conditions: E, rules: [{ conditions: [B], rules: [{ endpoint: { url: "https://sts.{Region}.{PartitionResult#dualStackDnsSuffix}", properties: v, headers: v }, [G]: h }], [G]: j }, { error: "DualStack is enabled but this partition does not support DualStack", [G]: k }], [G]: j }, w, { endpoint: { url: i, properties: v, headers: v }, [G]: h }], [G]: j }], [G]: j }, { error: "Invalid Configuration: Missing Region", [G]: k }] };
|
|
||||||
exports.ruleSet = _data;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 1136:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var STSClient = __webpack_require__(3723);
|
|
||||||
var smithyClient = __webpack_require__(1411);
|
|
||||||
var middlewareEndpoint = __webpack_require__(99);
|
|
||||||
var EndpointParameters = __webpack_require__(6811);
|
|
||||||
var schema = __webpack_require__(6890);
|
|
||||||
var client = __webpack_require__(5152);
|
|
||||||
var regionConfigResolver = __webpack_require__(6463);
|
|
||||||
|
|
||||||
let STSServiceException$1 = class STSServiceException extends smithyClient.ServiceException {
|
|
||||||
constructor(options) {
|
|
||||||
super(options);
|
|
||||||
Object.setPrototypeOf(this, STSServiceException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let ExpiredTokenException$1 = class ExpiredTokenException extends STSServiceException$1 {
|
|
||||||
name = "ExpiredTokenException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "ExpiredTokenException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, ExpiredTokenException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let MalformedPolicyDocumentException$1 = class MalformedPolicyDocumentException extends STSServiceException$1 {
|
|
||||||
name = "MalformedPolicyDocumentException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "MalformedPolicyDocumentException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, MalformedPolicyDocumentException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let PackedPolicyTooLargeException$1 = class PackedPolicyTooLargeException extends STSServiceException$1 {
|
|
||||||
name = "PackedPolicyTooLargeException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "PackedPolicyTooLargeException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, PackedPolicyTooLargeException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let RegionDisabledException$1 = class RegionDisabledException extends STSServiceException$1 {
|
|
||||||
name = "RegionDisabledException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "RegionDisabledException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, RegionDisabledException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let IDPRejectedClaimException$1 = class IDPRejectedClaimException extends STSServiceException$1 {
|
|
||||||
name = "IDPRejectedClaimException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "IDPRejectedClaimException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, IDPRejectedClaimException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InvalidIdentityTokenException$1 = class InvalidIdentityTokenException extends STSServiceException$1 {
|
|
||||||
name = "InvalidIdentityTokenException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidIdentityTokenException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidIdentityTokenException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let IDPCommunicationErrorException$1 = class IDPCommunicationErrorException extends STSServiceException$1 {
|
|
||||||
name = "IDPCommunicationErrorException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "IDPCommunicationErrorException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, IDPCommunicationErrorException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const _A = "Arn";
|
|
||||||
const _AKI = "AccessKeyId";
|
|
||||||
const _AR = "AssumeRole";
|
|
||||||
const _ARI = "AssumedRoleId";
|
|
||||||
const _ARR = "AssumeRoleRequest";
|
|
||||||
const _ARRs = "AssumeRoleResponse";
|
|
||||||
const _ARU = "AssumedRoleUser";
|
|
||||||
const _ARWWI = "AssumeRoleWithWebIdentity";
|
|
||||||
const _ARWWIR = "AssumeRoleWithWebIdentityRequest";
|
|
||||||
const _ARWWIRs = "AssumeRoleWithWebIdentityResponse";
|
|
||||||
const _Au = "Audience";
|
|
||||||
const _C = "Credentials";
|
|
||||||
const _CA = "ContextAssertion";
|
|
||||||
const _DS = "DurationSeconds";
|
|
||||||
const _E = "Expiration";
|
|
||||||
const _EI = "ExternalId";
|
|
||||||
const _ETE = "ExpiredTokenException";
|
|
||||||
const _IDPCEE = "IDPCommunicationErrorException";
|
|
||||||
const _IDPRCE = "IDPRejectedClaimException";
|
|
||||||
const _IITE = "InvalidIdentityTokenException";
|
|
||||||
const _K = "Key";
|
|
||||||
const _MPDE = "MalformedPolicyDocumentException";
|
|
||||||
const _P = "Policy";
|
|
||||||
const _PA = "PolicyArns";
|
|
||||||
const _PAr = "ProviderArn";
|
|
||||||
const _PC = "ProvidedContexts";
|
|
||||||
const _PCLT = "ProvidedContextsListType";
|
|
||||||
const _PCr = "ProvidedContext";
|
|
||||||
const _PDT = "PolicyDescriptorType";
|
|
||||||
const _PI = "ProviderId";
|
|
||||||
const _PPS = "PackedPolicySize";
|
|
||||||
const _PPTLE = "PackedPolicyTooLargeException";
|
|
||||||
const _Pr = "Provider";
|
|
||||||
const _RA = "RoleArn";
|
|
||||||
const _RDE = "RegionDisabledException";
|
|
||||||
const _RSN = "RoleSessionName";
|
|
||||||
const _SAK = "SecretAccessKey";
|
|
||||||
const _SFWIT = "SubjectFromWebIdentityToken";
|
|
||||||
const _SI = "SourceIdentity";
|
|
||||||
const _SN = "SerialNumber";
|
|
||||||
const _ST = "SessionToken";
|
|
||||||
const _T = "Tags";
|
|
||||||
const _TC = "TokenCode";
|
|
||||||
const _TTK = "TransitiveTagKeys";
|
|
||||||
const _Ta = "Tag";
|
|
||||||
const _V = "Value";
|
|
||||||
const _WIT = "WebIdentityToken";
|
|
||||||
const _a = "arn";
|
|
||||||
const _aKST = "accessKeySecretType";
|
|
||||||
const _aQE = "awsQueryError";
|
|
||||||
const _c = "client";
|
|
||||||
const _cTT = "clientTokenType";
|
|
||||||
const _e = "error";
|
|
||||||
const _hE = "httpError";
|
|
||||||
const _m = "message";
|
|
||||||
const _pDLT = "policyDescriptorListType";
|
|
||||||
const _s = "smithy.ts.sdk.synthetic.com.amazonaws.sts";
|
|
||||||
const _tLT = "tagListType";
|
|
||||||
const n0 = "com.amazonaws.sts";
|
|
||||||
var accessKeySecretType = [0, n0, _aKST, 8, 0];
|
|
||||||
var clientTokenType = [0, n0, _cTT, 8, 0];
|
|
||||||
var AssumedRoleUser = [3, n0, _ARU, 0, [_ARI, _A], [0, 0]];
|
|
||||||
var AssumeRoleRequest = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_ARR,
|
|
||||||
0,
|
|
||||||
[_RA, _RSN, _PA, _P, _DS, _T, _TTK, _EI, _SN, _TC, _SI, _PC],
|
|
||||||
[0, 0, () => policyDescriptorListType, 0, 1, () => tagListType, 64 | 0, 0, 0, 0, 0, () => ProvidedContextsListType],
|
|
||||||
];
|
|
||||||
var AssumeRoleResponse = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_ARRs,
|
|
||||||
0,
|
|
||||||
[_C, _ARU, _PPS, _SI],
|
|
||||||
[[() => Credentials, 0], () => AssumedRoleUser, 1, 0],
|
|
||||||
];
|
|
||||||
var AssumeRoleWithWebIdentityRequest = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_ARWWIR,
|
|
||||||
0,
|
|
||||||
[_RA, _RSN, _WIT, _PI, _PA, _P, _DS],
|
|
||||||
[0, 0, [() => clientTokenType, 0], 0, () => policyDescriptorListType, 0, 1],
|
|
||||||
];
|
|
||||||
var AssumeRoleWithWebIdentityResponse = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_ARWWIRs,
|
|
||||||
0,
|
|
||||||
[_C, _SFWIT, _ARU, _PPS, _Pr, _Au, _SI],
|
|
||||||
[[() => Credentials, 0], 0, () => AssumedRoleUser, 1, 0, 0, 0],
|
|
||||||
];
|
|
||||||
var Credentials = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_C,
|
|
||||||
0,
|
|
||||||
[_AKI, _SAK, _ST, _E],
|
|
||||||
[0, [() => accessKeySecretType, 0], 0, 4],
|
|
||||||
];
|
|
||||||
var ExpiredTokenException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ETE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`ExpiredTokenException`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(ExpiredTokenException, ExpiredTokenException$1);
|
|
||||||
var IDPCommunicationErrorException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IDPCEE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`IDPCommunicationError`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(IDPCommunicationErrorException, IDPCommunicationErrorException$1);
|
|
||||||
var IDPRejectedClaimException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IDPRCE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 403,
|
|
||||||
[_aQE]: [`IDPRejectedClaim`, 403],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(IDPRejectedClaimException, IDPRejectedClaimException$1);
|
|
||||||
var InvalidIdentityTokenException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IITE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`InvalidIdentityToken`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidIdentityTokenException, InvalidIdentityTokenException$1);
|
|
||||||
var MalformedPolicyDocumentException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_MPDE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`MalformedPolicyDocument`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(MalformedPolicyDocumentException, MalformedPolicyDocumentException$1);
|
|
||||||
var PackedPolicyTooLargeException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_PPTLE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`PackedPolicyTooLarge`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(PackedPolicyTooLargeException, PackedPolicyTooLargeException$1);
|
|
||||||
var PolicyDescriptorType = [3, n0, _PDT, 0, [_a], [0]];
|
|
||||||
var ProvidedContext = [3, n0, _PCr, 0, [_PAr, _CA], [0, 0]];
|
|
||||||
var RegionDisabledException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_RDE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 403,
|
|
||||||
[_aQE]: [`RegionDisabledException`, 403],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(RegionDisabledException, RegionDisabledException$1);
|
|
||||||
var Tag = [3, n0, _Ta, 0, [_K, _V], [0, 0]];
|
|
||||||
var STSServiceException = [-3, _s, "STSServiceException", 0, [], []];
|
|
||||||
schema.TypeRegistry.for(_s).registerError(STSServiceException, STSServiceException$1);
|
|
||||||
var policyDescriptorListType = [1, n0, _pDLT, 0, () => PolicyDescriptorType];
|
|
||||||
var ProvidedContextsListType = [1, n0, _PCLT, 0, () => ProvidedContext];
|
|
||||||
var tagListType = [1, n0, _tLT, 0, () => Tag];
|
|
||||||
var AssumeRole = [9, n0, _AR, 0, () => AssumeRoleRequest, () => AssumeRoleResponse];
|
|
||||||
var AssumeRoleWithWebIdentity = [
|
|
||||||
9,
|
|
||||||
n0,
|
|
||||||
_ARWWI,
|
|
||||||
0,
|
|
||||||
() => AssumeRoleWithWebIdentityRequest,
|
|
||||||
() => AssumeRoleWithWebIdentityResponse,
|
|
||||||
];
|
|
||||||
|
|
||||||
class AssumeRoleCommand extends smithyClient.Command
|
|
||||||
.classBuilder()
|
|
||||||
.ep(EndpointParameters.commonParams)
|
|
||||||
.m(function (Command, cs, config, o) {
|
|
||||||
return [middlewareEndpoint.getEndpointPlugin(config, Command.getEndpointParameterInstructions())];
|
|
||||||
})
|
|
||||||
.s("AWSSecurityTokenServiceV20110615", "AssumeRole", {})
|
|
||||||
.n("STSClient", "AssumeRoleCommand")
|
|
||||||
.sc(AssumeRole)
|
|
||||||
.build() {
|
|
||||||
}
|
|
||||||
|
|
||||||
class AssumeRoleWithWebIdentityCommand extends smithyClient.Command
|
|
||||||
.classBuilder()
|
|
||||||
.ep(EndpointParameters.commonParams)
|
|
||||||
.m(function (Command, cs, config, o) {
|
|
||||||
return [middlewareEndpoint.getEndpointPlugin(config, Command.getEndpointParameterInstructions())];
|
|
||||||
})
|
|
||||||
.s("AWSSecurityTokenServiceV20110615", "AssumeRoleWithWebIdentity", {})
|
|
||||||
.n("STSClient", "AssumeRoleWithWebIdentityCommand")
|
|
||||||
.sc(AssumeRoleWithWebIdentity)
|
|
||||||
.build() {
|
|
||||||
}
|
|
||||||
|
|
||||||
const commands = {
|
|
||||||
AssumeRoleCommand,
|
|
||||||
AssumeRoleWithWebIdentityCommand,
|
|
||||||
};
|
|
||||||
class STS extends STSClient.STSClient {
|
|
||||||
}
|
|
||||||
smithyClient.createAggregatedClient(commands, STS);
|
|
||||||
|
|
||||||
const getAccountIdFromAssumedRoleUser = (assumedRoleUser) => {
|
|
||||||
if (typeof assumedRoleUser?.Arn === "string") {
|
|
||||||
const arnComponents = assumedRoleUser.Arn.split(":");
|
|
||||||
if (arnComponents.length > 4 && arnComponents[4] !== "") {
|
|
||||||
return arnComponents[4];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
const resolveRegion = async (_region, _parentRegion, credentialProviderLogger, loaderConfig = {}) => {
|
|
||||||
const region = typeof _region === "function" ? await _region() : _region;
|
|
||||||
const parentRegion = typeof _parentRegion === "function" ? await _parentRegion() : _parentRegion;
|
|
||||||
const stsDefaultRegion = await regionConfigResolver.stsRegionDefaultResolver(loaderConfig)();
|
|
||||||
credentialProviderLogger?.debug?.("@aws-sdk/client-sts::resolveRegion", "accepting first of:", `${region} (credential provider clientConfig)`, `${parentRegion} (contextual client)`, `${stsDefaultRegion} (STS default: AWS_REGION, profile region, or us-east-1)`);
|
|
||||||
return region ?? parentRegion ?? stsDefaultRegion;
|
|
||||||
};
|
|
||||||
const getDefaultRoleAssumer$1 = (stsOptions, STSClient) => {
|
|
||||||
let stsClient;
|
|
||||||
let closureSourceCreds;
|
|
||||||
return async (sourceCreds, params) => {
|
|
||||||
closureSourceCreds = sourceCreds;
|
|
||||||
if (!stsClient) {
|
|
||||||
const { logger = stsOptions?.parentClientConfig?.logger, profile = stsOptions?.parentClientConfig?.profile, region, requestHandler = stsOptions?.parentClientConfig?.requestHandler, credentialProviderLogger, userAgentAppId = stsOptions?.parentClientConfig?.userAgentAppId, } = stsOptions;
|
|
||||||
const resolvedRegion = await resolveRegion(region, stsOptions?.parentClientConfig?.region, credentialProviderLogger, {
|
|
||||||
logger,
|
|
||||||
profile,
|
|
||||||
});
|
|
||||||
const isCompatibleRequestHandler = !isH2(requestHandler);
|
|
||||||
stsClient = new STSClient({
|
|
||||||
...stsOptions,
|
|
||||||
userAgentAppId,
|
|
||||||
profile,
|
|
||||||
credentialDefaultProvider: () => async () => closureSourceCreds,
|
|
||||||
region: resolvedRegion,
|
|
||||||
requestHandler: isCompatibleRequestHandler ? requestHandler : undefined,
|
|
||||||
logger: logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const { Credentials, AssumedRoleUser } = await stsClient.send(new AssumeRoleCommand(params));
|
|
||||||
if (!Credentials || !Credentials.AccessKeyId || !Credentials.SecretAccessKey) {
|
|
||||||
throw new Error(`Invalid response from STS.assumeRole call with role ${params.RoleArn}`);
|
|
||||||
}
|
|
||||||
const accountId = getAccountIdFromAssumedRoleUser(AssumedRoleUser);
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId: Credentials.AccessKeyId,
|
|
||||||
secretAccessKey: Credentials.SecretAccessKey,
|
|
||||||
sessionToken: Credentials.SessionToken,
|
|
||||||
expiration: Credentials.Expiration,
|
|
||||||
...(Credentials.CredentialScope && { credentialScope: Credentials.CredentialScope }),
|
|
||||||
...(accountId && { accountId }),
|
|
||||||
};
|
|
||||||
client.setCredentialFeature(credentials, "CREDENTIALS_STS_ASSUME_ROLE", "i");
|
|
||||||
return credentials;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const getDefaultRoleAssumerWithWebIdentity$1 = (stsOptions, STSClient) => {
|
|
||||||
let stsClient;
|
|
||||||
return async (params) => {
|
|
||||||
if (!stsClient) {
|
|
||||||
const { logger = stsOptions?.parentClientConfig?.logger, profile = stsOptions?.parentClientConfig?.profile, region, requestHandler = stsOptions?.parentClientConfig?.requestHandler, credentialProviderLogger, userAgentAppId = stsOptions?.parentClientConfig?.userAgentAppId, } = stsOptions;
|
|
||||||
const resolvedRegion = await resolveRegion(region, stsOptions?.parentClientConfig?.region, credentialProviderLogger, {
|
|
||||||
logger,
|
|
||||||
profile,
|
|
||||||
});
|
|
||||||
const isCompatibleRequestHandler = !isH2(requestHandler);
|
|
||||||
stsClient = new STSClient({
|
|
||||||
...stsOptions,
|
|
||||||
userAgentAppId,
|
|
||||||
profile,
|
|
||||||
region: resolvedRegion,
|
|
||||||
requestHandler: isCompatibleRequestHandler ? requestHandler : undefined,
|
|
||||||
logger: logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const { Credentials, AssumedRoleUser } = await stsClient.send(new AssumeRoleWithWebIdentityCommand(params));
|
|
||||||
if (!Credentials || !Credentials.AccessKeyId || !Credentials.SecretAccessKey) {
|
|
||||||
throw new Error(`Invalid response from STS.assumeRoleWithWebIdentity call with role ${params.RoleArn}`);
|
|
||||||
}
|
|
||||||
const accountId = getAccountIdFromAssumedRoleUser(AssumedRoleUser);
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId: Credentials.AccessKeyId,
|
|
||||||
secretAccessKey: Credentials.SecretAccessKey,
|
|
||||||
sessionToken: Credentials.SessionToken,
|
|
||||||
expiration: Credentials.Expiration,
|
|
||||||
...(Credentials.CredentialScope && { credentialScope: Credentials.CredentialScope }),
|
|
||||||
...(accountId && { accountId }),
|
|
||||||
};
|
|
||||||
if (accountId) {
|
|
||||||
client.setCredentialFeature(credentials, "RESOLVED_ACCOUNT_ID", "T");
|
|
||||||
}
|
|
||||||
client.setCredentialFeature(credentials, "CREDENTIALS_STS_ASSUME_ROLE_WEB_ID", "k");
|
|
||||||
return credentials;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const isH2 = (requestHandler) => {
|
|
||||||
return requestHandler?.metadata?.handlerProtocol === "h2";
|
|
||||||
};
|
|
||||||
|
|
||||||
const getCustomizableStsClientCtor = (baseCtor, customizations) => {
|
|
||||||
if (!customizations)
|
|
||||||
return baseCtor;
|
|
||||||
else
|
|
||||||
return class CustomizableSTSClient extends baseCtor {
|
|
||||||
constructor(config) {
|
|
||||||
super(config);
|
|
||||||
for (const customization of customizations) {
|
|
||||||
this.middlewareStack.use(customization);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const getDefaultRoleAssumer = (stsOptions = {}, stsPlugins) => getDefaultRoleAssumer$1(stsOptions, getCustomizableStsClientCtor(STSClient.STSClient, stsPlugins));
|
|
||||||
const getDefaultRoleAssumerWithWebIdentity = (stsOptions = {}, stsPlugins) => getDefaultRoleAssumerWithWebIdentity$1(stsOptions, getCustomizableStsClientCtor(STSClient.STSClient, stsPlugins));
|
|
||||||
const decorateDefaultCredentialProvider = (provider) => (input) => provider({
|
|
||||||
roleAssumer: getDefaultRoleAssumer(input),
|
|
||||||
roleAssumerWithWebIdentity: getDefaultRoleAssumerWithWebIdentity(input),
|
|
||||||
...input,
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "$Command", ({
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return smithyClient.Command; }
|
|
||||||
}));
|
|
||||||
exports.AssumeRoleCommand = AssumeRoleCommand;
|
|
||||||
exports.AssumeRoleWithWebIdentityCommand = AssumeRoleWithWebIdentityCommand;
|
|
||||||
exports.ExpiredTokenException = ExpiredTokenException$1;
|
|
||||||
exports.IDPCommunicationErrorException = IDPCommunicationErrorException$1;
|
|
||||||
exports.IDPRejectedClaimException = IDPRejectedClaimException$1;
|
|
||||||
exports.InvalidIdentityTokenException = InvalidIdentityTokenException$1;
|
|
||||||
exports.MalformedPolicyDocumentException = MalformedPolicyDocumentException$1;
|
|
||||||
exports.PackedPolicyTooLargeException = PackedPolicyTooLargeException$1;
|
|
||||||
exports.RegionDisabledException = RegionDisabledException$1;
|
|
||||||
exports.STS = STS;
|
|
||||||
exports.STSServiceException = STSServiceException$1;
|
|
||||||
exports.decorateDefaultCredentialProvider = decorateDefaultCredentialProvider;
|
|
||||||
exports.getDefaultRoleAssumer = getDefaultRoleAssumer;
|
|
||||||
exports.getDefaultRoleAssumerWithWebIdentity = getDefaultRoleAssumerWithWebIdentity;
|
|
||||||
Object.keys(STSClient).forEach(function (k) {
|
|
||||||
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return STSClient[k]; }
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 6578:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getRuntimeConfig = void 0;
|
|
||||||
const tslib_1 = __webpack_require__(1860);
|
|
||||||
const package_json_1 = tslib_1.__importDefault(__webpack_require__(9955));
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const util_user_agent_node_1 = __webpack_require__(1656);
|
|
||||||
const config_resolver_1 = __webpack_require__(9316);
|
|
||||||
const core_2 = __webpack_require__(402);
|
|
||||||
const hash_node_1 = __webpack_require__(5092);
|
|
||||||
const middleware_retry_1 = __webpack_require__(9618);
|
|
||||||
const node_config_provider_1 = __webpack_require__(5704);
|
|
||||||
const node_http_handler_1 = __webpack_require__(1279);
|
|
||||||
const util_body_length_node_1 = __webpack_require__(3638);
|
|
||||||
const util_retry_1 = __webpack_require__(5518);
|
|
||||||
const runtimeConfig_shared_1 = __webpack_require__(4443);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const util_defaults_mode_node_1 = __webpack_require__(5435);
|
|
||||||
const smithy_client_2 = __webpack_require__(1411);
|
|
||||||
const getRuntimeConfig = (config) => {
|
|
||||||
(0, smithy_client_2.emitWarningIfUnsupportedVersion)(process.version);
|
|
||||||
const defaultsMode = (0, util_defaults_mode_node_1.resolveDefaultsModeConfig)(config);
|
|
||||||
const defaultConfigProvider = () => defaultsMode().then(smithy_client_1.loadConfigsForDefaultMode);
|
|
||||||
const clientSharedValues = (0, runtimeConfig_shared_1.getRuntimeConfig)(config);
|
|
||||||
(0, core_1.emitWarningIfUnsupportedVersion)(process.version);
|
|
||||||
const loaderConfig = {
|
|
||||||
profile: config?.profile,
|
|
||||||
logger: clientSharedValues.logger,
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
...clientSharedValues,
|
|
||||||
...config,
|
|
||||||
runtime: "node",
|
|
||||||
defaultsMode,
|
|
||||||
authSchemePreference: config?.authSchemePreference ?? (0, node_config_provider_1.loadConfig)(core_1.NODE_AUTH_SCHEME_PREFERENCE_OPTIONS, loaderConfig),
|
|
||||||
bodyLengthChecker: config?.bodyLengthChecker ?? util_body_length_node_1.calculateBodyLength,
|
|
||||||
defaultUserAgentProvider: config?.defaultUserAgentProvider ??
|
|
||||||
(0, util_user_agent_node_1.createDefaultUserAgentProvider)({ serviceId: clientSharedValues.serviceId, clientVersion: package_json_1.default.version }),
|
|
||||||
httpAuthSchemes: config?.httpAuthSchemes ?? [
|
|
||||||
{
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("aws.auth#sigv4") ||
|
|
||||||
(async (idProps) => await config.credentialDefaultProvider(idProps?.__config || {})()),
|
|
||||||
signer: new core_1.AwsSdkSigV4Signer(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("smithy.api#noAuth") || (async () => ({})),
|
|
||||||
signer: new core_2.NoAuthSigner(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
maxAttempts: config?.maxAttempts ?? (0, node_config_provider_1.loadConfig)(middleware_retry_1.NODE_MAX_ATTEMPT_CONFIG_OPTIONS, config),
|
|
||||||
region: config?.region ??
|
|
||||||
(0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_REGION_CONFIG_OPTIONS, { ...config_resolver_1.NODE_REGION_CONFIG_FILE_OPTIONS, ...loaderConfig }),
|
|
||||||
requestHandler: node_http_handler_1.NodeHttpHandler.create(config?.requestHandler ?? defaultConfigProvider),
|
|
||||||
retryMode: config?.retryMode ??
|
|
||||||
(0, node_config_provider_1.loadConfig)({
|
|
||||||
...middleware_retry_1.NODE_RETRY_MODE_CONFIG_OPTIONS,
|
|
||||||
default: async () => (await defaultConfigProvider()).retryMode || util_retry_1.DEFAULT_RETRY_MODE,
|
|
||||||
}, config),
|
|
||||||
sha256: config?.sha256 ?? hash_node_1.Hash.bind(null, "sha256"),
|
|
||||||
streamCollector: config?.streamCollector ?? node_http_handler_1.streamCollector,
|
|
||||||
useDualstackEndpoint: config?.useDualstackEndpoint ?? (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
useFipsEndpoint: config?.useFipsEndpoint ?? (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
userAgentAppId: config?.userAgentAppId ?? (0, node_config_provider_1.loadConfig)(util_user_agent_node_1.NODE_APP_ID_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getRuntimeConfig = getRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 4443:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getRuntimeConfig = void 0;
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const protocols_1 = __webpack_require__(7288);
|
|
||||||
const core_2 = __webpack_require__(402);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const url_parser_1 = __webpack_require__(4494);
|
|
||||||
const util_base64_1 = __webpack_require__(8385);
|
|
||||||
const util_utf8_1 = __webpack_require__(1577);
|
|
||||||
const httpAuthSchemeProvider_1 = __webpack_require__(7851);
|
|
||||||
const endpointResolver_1 = __webpack_require__(9765);
|
|
||||||
const getRuntimeConfig = (config) => {
|
|
||||||
return {
|
|
||||||
apiVersion: "2011-06-15",
|
|
||||||
base64Decoder: config?.base64Decoder ?? util_base64_1.fromBase64,
|
|
||||||
base64Encoder: config?.base64Encoder ?? util_base64_1.toBase64,
|
|
||||||
disableHostPrefix: config?.disableHostPrefix ?? false,
|
|
||||||
endpointProvider: config?.endpointProvider ?? endpointResolver_1.defaultEndpointResolver,
|
|
||||||
extensions: config?.extensions ?? [],
|
|
||||||
httpAuthSchemeProvider: config?.httpAuthSchemeProvider ?? httpAuthSchemeProvider_1.defaultSTSHttpAuthSchemeProvider,
|
|
||||||
httpAuthSchemes: config?.httpAuthSchemes ?? [
|
|
||||||
{
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("aws.auth#sigv4"),
|
|
||||||
signer: new core_1.AwsSdkSigV4Signer(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("smithy.api#noAuth") || (async () => ({})),
|
|
||||||
signer: new core_2.NoAuthSigner(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
logger: config?.logger ?? new smithy_client_1.NoOpLogger(),
|
|
||||||
protocol: config?.protocol ??
|
|
||||||
new protocols_1.AwsQueryProtocol({
|
|
||||||
defaultNamespace: "com.amazonaws.sts",
|
|
||||||
xmlNamespace: "https://sts.amazonaws.com/doc/2011-06-15/",
|
|
||||||
version: "2011-06-15",
|
|
||||||
}),
|
|
||||||
serviceId: config?.serviceId ?? "STS",
|
|
||||||
urlParser: config?.urlParser ?? url_parser_1.parseUrl,
|
|
||||||
utf8Decoder: config?.utf8Decoder ?? util_utf8_1.fromUtf8,
|
|
||||||
utf8Encoder: config?.utf8Encoder ?? util_utf8_1.toUtf8,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getRuntimeConfig = getRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 7742:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.resolveRuntimeExtensions = void 0;
|
|
||||||
const region_config_resolver_1 = __webpack_require__(6463);
|
|
||||||
const protocol_http_1 = __webpack_require__(2356);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const httpAuthExtensionConfiguration_1 = __webpack_require__(4532);
|
|
||||||
const resolveRuntimeExtensions = (runtimeConfig, extensions) => {
|
|
||||||
const extensionConfiguration = Object.assign((0, region_config_resolver_1.getAwsRegionExtensionConfiguration)(runtimeConfig), (0, smithy_client_1.getDefaultExtensionConfiguration)(runtimeConfig), (0, protocol_http_1.getHttpHandlerExtensionConfiguration)(runtimeConfig), (0, httpAuthExtensionConfiguration_1.getHttpAuthExtensionConfiguration)(runtimeConfig));
|
|
||||||
extensions.forEach((extension) => extension.configure(extensionConfiguration));
|
|
||||||
return Object.assign(runtimeConfig, (0, region_config_resolver_1.resolveAwsRegionExtensionConfiguration)(extensionConfiguration), (0, smithy_client_1.resolveDefaultRuntimeConfig)(extensionConfiguration), (0, protocol_http_1.resolveHttpHandlerRuntimeConfig)(extensionConfiguration), (0, httpAuthExtensionConfiguration_1.resolveHttpAuthRuntimeConfig)(extensionConfiguration));
|
|
||||||
};
|
|
||||||
exports.resolveRuntimeExtensions = resolveRuntimeExtensions;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9955:
|
|
||||||
/***/ ((module) => {
|
|
||||||
|
|
||||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@aws-sdk/nested-clients","version":"3.933.0","description":"Nested clients for AWS SDK packages.","main":"./dist-cjs/index.js","module":"./dist-es/index.js","types":"./dist-types/index.d.ts","scripts":{"build":"yarn lint && concurrently \'yarn:build:cjs\' \'yarn:build:es\' \'yarn:build:types\'","build:cjs":"node ../../scripts/compilation/inline nested-clients","build:es":"tsc -p tsconfig.es.json","build:include:deps":"lerna run --scope $npm_package_name --include-dependencies build","build:types":"tsc -p tsconfig.types.json","build:types:downlevel":"downlevel-dts dist-types dist-types/ts3.4","clean":"rimraf ./dist-* && rimraf *.tsbuildinfo","lint":"node ../../scripts/validation/submodules-linter.js --pkg nested-clients","test":"yarn g:vitest run","test:watch":"yarn g:vitest watch"},"engines":{"node":">=18.0.0"},"sideEffects":false,"author":{"name":"AWS SDK for JavaScript Team","url":"https://aws.amazon.com/javascript/"},"license":"Apache-2.0","dependencies":{"@aws-crypto/sha256-browser":"5.2.0","@aws-crypto/sha256-js":"5.2.0","@aws-sdk/core":"3.932.0","@aws-sdk/middleware-host-header":"3.930.0","@aws-sdk/middleware-logger":"3.930.0","@aws-sdk/middleware-recursion-detection":"3.933.0","@aws-sdk/middleware-user-agent":"3.932.0","@aws-sdk/region-config-resolver":"3.930.0","@aws-sdk/types":"3.930.0","@aws-sdk/util-endpoints":"3.930.0","@aws-sdk/util-user-agent-browser":"3.930.0","@aws-sdk/util-user-agent-node":"3.932.0","@smithy/config-resolver":"^4.4.3","@smithy/core":"^3.18.2","@smithy/fetch-http-handler":"^5.3.6","@smithy/hash-node":"^4.2.5","@smithy/invalid-dependency":"^4.2.5","@smithy/middleware-content-length":"^4.2.5","@smithy/middleware-endpoint":"^4.3.9","@smithy/middleware-retry":"^4.4.9","@smithy/middleware-serde":"^4.2.5","@smithy/middleware-stack":"^4.2.5","@smithy/node-config-provider":"^4.3.5","@smithy/node-http-handler":"^4.4.5","@smithy/protocol-http":"^5.3.5","@smithy/smithy-client":"^4.9.5","@smithy/types":"^4.9.0","@smithy/url-parser":"^4.2.5","@smithy/util-base64":"^4.3.0","@smithy/util-body-length-browser":"^4.2.0","@smithy/util-body-length-node":"^4.2.1","@smithy/util-defaults-mode-browser":"^4.3.8","@smithy/util-defaults-mode-node":"^4.2.11","@smithy/util-endpoints":"^3.2.5","@smithy/util-middleware":"^4.2.5","@smithy/util-retry":"^4.2.5","@smithy/util-utf8":"^4.2.0","tslib":"^2.6.2"},"devDependencies":{"concurrently":"7.0.0","downlevel-dts":"0.10.1","rimraf":"3.0.2","typescript":"~5.8.3"},"typesVersions":{"<4.0":{"dist-types/*":["dist-types/ts3.4/*"]}},"files":["./sso-oidc.d.ts","./sso-oidc.js","./sts.d.ts","./sts.js","dist-*/**"],"browser":{"./dist-es/submodules/sso-oidc/runtimeConfig":"./dist-es/submodules/sso-oidc/runtimeConfig.browser","./dist-es/submodules/sts/runtimeConfig":"./dist-es/submodules/sts/runtimeConfig.browser"},"react-native":{},"homepage":"https://github.com/aws/aws-sdk-js-v3/tree/main/packages/nested-clients","repository":{"type":"git","url":"https://github.com/aws/aws-sdk-js-v3.git","directory":"packages/nested-clients"},"exports":{"./sso-oidc":{"types":"./dist-types/submodules/sso-oidc/index.d.ts","module":"./dist-es/submodules/sso-oidc/index.js","node":"./dist-cjs/submodules/sso-oidc/index.js","import":"./dist-es/submodules/sso-oidc/index.js","require":"./dist-cjs/submodules/sso-oidc/index.js"},"./sts":{"types":"./dist-types/submodules/sts/index.d.ts","module":"./dist-es/submodules/sts/index.js","node":"./dist-cjs/submodules/sts/index.js","import":"./dist-es/submodules/sts/index.js","require":"./dist-cjs/submodules/sts/index.js"}}}');
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-93
@@ -1,93 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 360;
|
|
||||||
exports.ids = [360];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 5360:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var sharedIniFileLoader = __webpack_require__(4964);
|
|
||||||
var propertyProvider = __webpack_require__(1238);
|
|
||||||
var child_process = __webpack_require__(5317);
|
|
||||||
var util = __webpack_require__(9023);
|
|
||||||
var client = __webpack_require__(5152);
|
|
||||||
|
|
||||||
const getValidatedProcessCredentials = (profileName, data, profiles) => {
|
|
||||||
if (data.Version !== 1) {
|
|
||||||
throw Error(`Profile ${profileName} credential_process did not return Version 1.`);
|
|
||||||
}
|
|
||||||
if (data.AccessKeyId === undefined || data.SecretAccessKey === undefined) {
|
|
||||||
throw Error(`Profile ${profileName} credential_process returned invalid credentials.`);
|
|
||||||
}
|
|
||||||
if (data.Expiration) {
|
|
||||||
const currentTime = new Date();
|
|
||||||
const expireTime = new Date(data.Expiration);
|
|
||||||
if (expireTime < currentTime) {
|
|
||||||
throw Error(`Profile ${profileName} credential_process returned expired credentials.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let accountId = data.AccountId;
|
|
||||||
if (!accountId && profiles?.[profileName]?.aws_account_id) {
|
|
||||||
accountId = profiles[profileName].aws_account_id;
|
|
||||||
}
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId: data.AccessKeyId,
|
|
||||||
secretAccessKey: data.SecretAccessKey,
|
|
||||||
...(data.SessionToken && { sessionToken: data.SessionToken }),
|
|
||||||
...(data.Expiration && { expiration: new Date(data.Expiration) }),
|
|
||||||
...(data.CredentialScope && { credentialScope: data.CredentialScope }),
|
|
||||||
...(accountId && { accountId }),
|
|
||||||
};
|
|
||||||
client.setCredentialFeature(credentials, "CREDENTIALS_PROCESS", "w");
|
|
||||||
return credentials;
|
|
||||||
};
|
|
||||||
|
|
||||||
const resolveProcessCredentials = async (profileName, profiles, logger) => {
|
|
||||||
const profile = profiles[profileName];
|
|
||||||
if (profiles[profileName]) {
|
|
||||||
const credentialProcess = profile["credential_process"];
|
|
||||||
if (credentialProcess !== undefined) {
|
|
||||||
const execPromise = util.promisify(sharedIniFileLoader.externalDataInterceptor?.getTokenRecord?.().exec ?? child_process.exec);
|
|
||||||
try {
|
|
||||||
const { stdout } = await execPromise(credentialProcess);
|
|
||||||
let data;
|
|
||||||
try {
|
|
||||||
data = JSON.parse(stdout.trim());
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
throw Error(`Profile ${profileName} credential_process returned invalid JSON.`);
|
|
||||||
}
|
|
||||||
return getValidatedProcessCredentials(profileName, data, profiles);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(error.message, { logger });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Profile ${profileName} did not contain credential_process.`, { logger });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Profile ${profileName} could not be found in shared credentials file.`, {
|
|
||||||
logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const fromProcess = (init = {}) => async ({ callerClientConfig } = {}) => {
|
|
||||||
init.logger?.debug("@aws-sdk/credential-provider-process - fromProcess");
|
|
||||||
const profiles = await sharedIniFileLoader.parseKnownFiles(init);
|
|
||||||
return resolveProcessCredentials(sharedIniFileLoader.getProfileName({
|
|
||||||
profile: init.profile ?? callerClientConfig?.profile,
|
|
||||||
}), profiles, init.logger);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.fromProcess = fromProcess;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-794
@@ -1,794 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 443;
|
|
||||||
exports.ids = [443];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 8396:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.resolveHttpAuthSchemeConfig = exports.defaultSSOOIDCHttpAuthSchemeProvider = exports.defaultSSOOIDCHttpAuthSchemeParametersProvider = void 0;
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const util_middleware_1 = __webpack_require__(6324);
|
|
||||||
const defaultSSOOIDCHttpAuthSchemeParametersProvider = async (config, context, input) => {
|
|
||||||
return {
|
|
||||||
operation: (0, util_middleware_1.getSmithyContext)(context).operation,
|
|
||||||
region: (await (0, util_middleware_1.normalizeProvider)(config.region)()) ||
|
|
||||||
(() => {
|
|
||||||
throw new Error("expected `region` to be configured for `aws.auth#sigv4`");
|
|
||||||
})(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.defaultSSOOIDCHttpAuthSchemeParametersProvider = defaultSSOOIDCHttpAuthSchemeParametersProvider;
|
|
||||||
function createAwsAuthSigv4HttpAuthOption(authParameters) {
|
|
||||||
return {
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
signingProperties: {
|
|
||||||
name: "sso-oauth",
|
|
||||||
region: authParameters.region,
|
|
||||||
},
|
|
||||||
propertiesExtractor: (config, context) => ({
|
|
||||||
signingProperties: {
|
|
||||||
config,
|
|
||||||
context,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function createSmithyApiNoAuthHttpAuthOption(authParameters) {
|
|
||||||
return {
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const defaultSSOOIDCHttpAuthSchemeProvider = (authParameters) => {
|
|
||||||
const options = [];
|
|
||||||
switch (authParameters.operation) {
|
|
||||||
case "CreateToken": {
|
|
||||||
options.push(createSmithyApiNoAuthHttpAuthOption(authParameters));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
options.push(createAwsAuthSigv4HttpAuthOption(authParameters));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
exports.defaultSSOOIDCHttpAuthSchemeProvider = defaultSSOOIDCHttpAuthSchemeProvider;
|
|
||||||
const resolveHttpAuthSchemeConfig = (config) => {
|
|
||||||
const config_0 = (0, core_1.resolveAwsSdkSigV4Config)(config);
|
|
||||||
return Object.assign(config_0, {
|
|
||||||
authSchemePreference: (0, util_middleware_1.normalizeProvider)(config.authSchemePreference ?? []),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
exports.resolveHttpAuthSchemeConfig = resolveHttpAuthSchemeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 546:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.defaultEndpointResolver = void 0;
|
|
||||||
const util_endpoints_1 = __webpack_require__(3068);
|
|
||||||
const util_endpoints_2 = __webpack_require__(9674);
|
|
||||||
const ruleset_1 = __webpack_require__(9947);
|
|
||||||
const cache = new util_endpoints_2.EndpointCache({
|
|
||||||
size: 50,
|
|
||||||
params: ["Endpoint", "Region", "UseDualStack", "UseFIPS"],
|
|
||||||
});
|
|
||||||
const defaultEndpointResolver = (endpointParams, context = {}) => {
|
|
||||||
return cache.get(endpointParams, () => (0, util_endpoints_2.resolveEndpoint)(ruleset_1.ruleSet, {
|
|
||||||
endpointParams: endpointParams,
|
|
||||||
logger: context.logger,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
exports.defaultEndpointResolver = defaultEndpointResolver;
|
|
||||||
util_endpoints_2.customEndpointFunctions.aws = util_endpoints_1.awsEndpointFunctions;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9947:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.ruleSet = void 0;
|
|
||||||
const u = "required", v = "fn", w = "argv", x = "ref";
|
|
||||||
const a = true, b = "isSet", c = "booleanEquals", d = "error", e = "endpoint", f = "tree", g = "PartitionResult", h = "getAttr", i = { [u]: false, "type": "string" }, j = { [u]: true, "default": false, "type": "boolean" }, k = { [x]: "Endpoint" }, l = { [v]: c, [w]: [{ [x]: "UseFIPS" }, true] }, m = { [v]: c, [w]: [{ [x]: "UseDualStack" }, true] }, n = {}, o = { [v]: h, [w]: [{ [x]: g }, "supportsFIPS"] }, p = { [x]: g }, q = { [v]: c, [w]: [true, { [v]: h, [w]: [p, "supportsDualStack"] }] }, r = [l], s = [m], t = [{ [x]: "Region" }];
|
|
||||||
const _data = { version: "1.0", parameters: { Region: i, UseDualStack: j, UseFIPS: j, Endpoint: i }, rules: [{ conditions: [{ [v]: b, [w]: [k] }], rules: [{ conditions: r, error: "Invalid Configuration: FIPS and custom endpoint are not supported", type: d }, { conditions: s, error: "Invalid Configuration: Dualstack and custom endpoint are not supported", type: d }, { endpoint: { url: k, properties: n, headers: n }, type: e }], type: f }, { conditions: [{ [v]: b, [w]: t }], rules: [{ conditions: [{ [v]: "aws.partition", [w]: t, assign: g }], rules: [{ conditions: [l, m], rules: [{ conditions: [{ [v]: c, [w]: [a, o] }, q], rules: [{ endpoint: { url: "https://oidc-fips.{Region}.{PartitionResult#dualStackDnsSuffix}", properties: n, headers: n }, type: e }], type: f }, { error: "FIPS and DualStack are enabled, but this partition does not support one or both", type: d }], type: f }, { conditions: r, rules: [{ conditions: [{ [v]: c, [w]: [o, a] }], rules: [{ conditions: [{ [v]: "stringEquals", [w]: [{ [v]: h, [w]: [p, "name"] }, "aws-us-gov"] }], endpoint: { url: "https://oidc.{Region}.amazonaws.com", properties: n, headers: n }, type: e }, { endpoint: { url: "https://oidc-fips.{Region}.{PartitionResult#dnsSuffix}", properties: n, headers: n }, type: e }], type: f }, { error: "FIPS is enabled but this partition does not support FIPS", type: d }], type: f }, { conditions: s, rules: [{ conditions: [q], rules: [{ endpoint: { url: "https://oidc.{Region}.{PartitionResult#dualStackDnsSuffix}", properties: n, headers: n }, type: e }], type: f }, { error: "DualStack is enabled but this partition does not support DualStack", type: d }], type: f }, { endpoint: { url: "https://oidc.{Region}.{PartitionResult#dnsSuffix}", properties: n, headers: n }, type: e }], type: f }], type: f }, { error: "Invalid Configuration: Missing Region", type: d }] };
|
|
||||||
exports.ruleSet = _data;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9443:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
var __webpack_unused_export__;
|
|
||||||
|
|
||||||
|
|
||||||
var middlewareHostHeader = __webpack_require__(2590);
|
|
||||||
var middlewareLogger = __webpack_require__(5242);
|
|
||||||
var middlewareRecursionDetection = __webpack_require__(1568);
|
|
||||||
var middlewareUserAgent = __webpack_require__(2959);
|
|
||||||
var configResolver = __webpack_require__(9316);
|
|
||||||
var core = __webpack_require__(402);
|
|
||||||
var schema = __webpack_require__(6890);
|
|
||||||
var middlewareContentLength = __webpack_require__(7212);
|
|
||||||
var middlewareEndpoint = __webpack_require__(99);
|
|
||||||
var middlewareRetry = __webpack_require__(9618);
|
|
||||||
var smithyClient = __webpack_require__(1411);
|
|
||||||
var httpAuthSchemeProvider = __webpack_require__(8396);
|
|
||||||
var runtimeConfig = __webpack_require__(6901);
|
|
||||||
var regionConfigResolver = __webpack_require__(6463);
|
|
||||||
var protocolHttp = __webpack_require__(2356);
|
|
||||||
|
|
||||||
const resolveClientEndpointParameters = (options) => {
|
|
||||||
return Object.assign(options, {
|
|
||||||
useDualstackEndpoint: options.useDualstackEndpoint ?? false,
|
|
||||||
useFipsEndpoint: options.useFipsEndpoint ?? false,
|
|
||||||
defaultSigningName: "sso-oauth",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const commonParams = {
|
|
||||||
UseFIPS: { type: "builtInParams", name: "useFipsEndpoint" },
|
|
||||||
Endpoint: { type: "builtInParams", name: "endpoint" },
|
|
||||||
Region: { type: "builtInParams", name: "region" },
|
|
||||||
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" },
|
|
||||||
};
|
|
||||||
|
|
||||||
const getHttpAuthExtensionConfiguration = (runtimeConfig) => {
|
|
||||||
const _httpAuthSchemes = runtimeConfig.httpAuthSchemes;
|
|
||||||
let _httpAuthSchemeProvider = runtimeConfig.httpAuthSchemeProvider;
|
|
||||||
let _credentials = runtimeConfig.credentials;
|
|
||||||
return {
|
|
||||||
setHttpAuthScheme(httpAuthScheme) {
|
|
||||||
const index = _httpAuthSchemes.findIndex((scheme) => scheme.schemeId === httpAuthScheme.schemeId);
|
|
||||||
if (index === -1) {
|
|
||||||
_httpAuthSchemes.push(httpAuthScheme);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_httpAuthSchemes.splice(index, 1, httpAuthScheme);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
httpAuthSchemes() {
|
|
||||||
return _httpAuthSchemes;
|
|
||||||
},
|
|
||||||
setHttpAuthSchemeProvider(httpAuthSchemeProvider) {
|
|
||||||
_httpAuthSchemeProvider = httpAuthSchemeProvider;
|
|
||||||
},
|
|
||||||
httpAuthSchemeProvider() {
|
|
||||||
return _httpAuthSchemeProvider;
|
|
||||||
},
|
|
||||||
setCredentials(credentials) {
|
|
||||||
_credentials = credentials;
|
|
||||||
},
|
|
||||||
credentials() {
|
|
||||||
return _credentials;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const resolveHttpAuthRuntimeConfig = (config) => {
|
|
||||||
return {
|
|
||||||
httpAuthSchemes: config.httpAuthSchemes(),
|
|
||||||
httpAuthSchemeProvider: config.httpAuthSchemeProvider(),
|
|
||||||
credentials: config.credentials(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const resolveRuntimeExtensions = (runtimeConfig, extensions) => {
|
|
||||||
const extensionConfiguration = Object.assign(regionConfigResolver.getAwsRegionExtensionConfiguration(runtimeConfig), smithyClient.getDefaultExtensionConfiguration(runtimeConfig), protocolHttp.getHttpHandlerExtensionConfiguration(runtimeConfig), getHttpAuthExtensionConfiguration(runtimeConfig));
|
|
||||||
extensions.forEach((extension) => extension.configure(extensionConfiguration));
|
|
||||||
return Object.assign(runtimeConfig, regionConfigResolver.resolveAwsRegionExtensionConfiguration(extensionConfiguration), smithyClient.resolveDefaultRuntimeConfig(extensionConfiguration), protocolHttp.resolveHttpHandlerRuntimeConfig(extensionConfiguration), resolveHttpAuthRuntimeConfig(extensionConfiguration));
|
|
||||||
};
|
|
||||||
|
|
||||||
class SSOOIDCClient extends smithyClient.Client {
|
|
||||||
config;
|
|
||||||
constructor(...[configuration]) {
|
|
||||||
const _config_0 = runtimeConfig.getRuntimeConfig(configuration || {});
|
|
||||||
super(_config_0);
|
|
||||||
this.initConfig = _config_0;
|
|
||||||
const _config_1 = resolveClientEndpointParameters(_config_0);
|
|
||||||
const _config_2 = middlewareUserAgent.resolveUserAgentConfig(_config_1);
|
|
||||||
const _config_3 = middlewareRetry.resolveRetryConfig(_config_2);
|
|
||||||
const _config_4 = configResolver.resolveRegionConfig(_config_3);
|
|
||||||
const _config_5 = middlewareHostHeader.resolveHostHeaderConfig(_config_4);
|
|
||||||
const _config_6 = middlewareEndpoint.resolveEndpointConfig(_config_5);
|
|
||||||
const _config_7 = httpAuthSchemeProvider.resolveHttpAuthSchemeConfig(_config_6);
|
|
||||||
const _config_8 = resolveRuntimeExtensions(_config_7, configuration?.extensions || []);
|
|
||||||
this.config = _config_8;
|
|
||||||
this.middlewareStack.use(schema.getSchemaSerdePlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareUserAgent.getUserAgentPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareRetry.getRetryPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareContentLength.getContentLengthPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareHostHeader.getHostHeaderPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareLogger.getLoggerPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareRecursionDetection.getRecursionDetectionPlugin(this.config));
|
|
||||||
this.middlewareStack.use(core.getHttpAuthSchemeEndpointRuleSetPlugin(this.config, {
|
|
||||||
httpAuthSchemeParametersProvider: httpAuthSchemeProvider.defaultSSOOIDCHttpAuthSchemeParametersProvider,
|
|
||||||
identityProviderConfigProvider: async (config) => new core.DefaultIdentityProviderConfig({
|
|
||||||
"aws.auth#sigv4": config.credentials,
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
this.middlewareStack.use(core.getHttpSigningPlugin(this.config));
|
|
||||||
}
|
|
||||||
destroy() {
|
|
||||||
super.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let SSOOIDCServiceException$1 = class SSOOIDCServiceException extends smithyClient.ServiceException {
|
|
||||||
constructor(options) {
|
|
||||||
super(options);
|
|
||||||
Object.setPrototypeOf(this, SSOOIDCServiceException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessDeniedExceptionReason = {
|
|
||||||
KMS_ACCESS_DENIED: "KMS_AccessDeniedException",
|
|
||||||
};
|
|
||||||
let AccessDeniedException$1 = class AccessDeniedException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "AccessDeniedException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
reason;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "AccessDeniedException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, AccessDeniedException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.reason = opts.reason;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let AuthorizationPendingException$1 = class AuthorizationPendingException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "AuthorizationPendingException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "AuthorizationPendingException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, AuthorizationPendingException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let ExpiredTokenException$1 = class ExpiredTokenException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "ExpiredTokenException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "ExpiredTokenException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, ExpiredTokenException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InternalServerException$1 = class InternalServerException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InternalServerException";
|
|
||||||
$fault = "server";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InternalServerException",
|
|
||||||
$fault: "server",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InternalServerException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InvalidClientException$1 = class InvalidClientException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InvalidClientException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidClientException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidClientException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InvalidGrantException$1 = class InvalidGrantException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InvalidGrantException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidGrantException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidGrantException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const InvalidRequestExceptionReason = {
|
|
||||||
KMS_DISABLED_KEY: "KMS_DisabledException",
|
|
||||||
KMS_INVALID_KEY_USAGE: "KMS_InvalidKeyUsageException",
|
|
||||||
KMS_INVALID_STATE: "KMS_InvalidStateException",
|
|
||||||
KMS_KEY_NOT_FOUND: "KMS_NotFoundException",
|
|
||||||
};
|
|
||||||
let InvalidRequestException$1 = class InvalidRequestException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InvalidRequestException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
reason;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidRequestException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidRequestException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.reason = opts.reason;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InvalidScopeException$1 = class InvalidScopeException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InvalidScopeException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidScopeException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidScopeException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let SlowDownException$1 = class SlowDownException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "SlowDownException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "SlowDownException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, SlowDownException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let UnauthorizedClientException$1 = class UnauthorizedClientException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "UnauthorizedClientException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "UnauthorizedClientException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, UnauthorizedClientException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let UnsupportedGrantTypeException$1 = class UnsupportedGrantTypeException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "UnsupportedGrantTypeException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "UnsupportedGrantTypeException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, UnsupportedGrantTypeException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const _ADE = "AccessDeniedException";
|
|
||||||
const _APE = "AuthorizationPendingException";
|
|
||||||
const _AT = "AccessToken";
|
|
||||||
const _CS = "ClientSecret";
|
|
||||||
const _CT = "CreateToken";
|
|
||||||
const _CTR = "CreateTokenRequest";
|
|
||||||
const _CTRr = "CreateTokenResponse";
|
|
||||||
const _CV = "CodeVerifier";
|
|
||||||
const _ETE = "ExpiredTokenException";
|
|
||||||
const _ICE = "InvalidClientException";
|
|
||||||
const _IGE = "InvalidGrantException";
|
|
||||||
const _IRE = "InvalidRequestException";
|
|
||||||
const _ISE = "InternalServerException";
|
|
||||||
const _ISEn = "InvalidScopeException";
|
|
||||||
const _IT = "IdToken";
|
|
||||||
const _RT = "RefreshToken";
|
|
||||||
const _SDE = "SlowDownException";
|
|
||||||
const _UCE = "UnauthorizedClientException";
|
|
||||||
const _UGTE = "UnsupportedGrantTypeException";
|
|
||||||
const _aT = "accessToken";
|
|
||||||
const _c = "client";
|
|
||||||
const _cI = "clientId";
|
|
||||||
const _cS = "clientSecret";
|
|
||||||
const _cV = "codeVerifier";
|
|
||||||
const _co = "code";
|
|
||||||
const _dC = "deviceCode";
|
|
||||||
const _e = "error";
|
|
||||||
const _eI = "expiresIn";
|
|
||||||
const _ed = "error_description";
|
|
||||||
const _gT = "grantType";
|
|
||||||
const _h = "http";
|
|
||||||
const _hE = "httpError";
|
|
||||||
const _iT = "idToken";
|
|
||||||
const _r = "reason";
|
|
||||||
const _rT = "refreshToken";
|
|
||||||
const _rU = "redirectUri";
|
|
||||||
const _s = "scope";
|
|
||||||
const _se = "server";
|
|
||||||
const _sm = "smithy.ts.sdk.synthetic.com.amazonaws.ssooidc";
|
|
||||||
const _tT = "tokenType";
|
|
||||||
const n0 = "com.amazonaws.ssooidc";
|
|
||||||
var AccessToken = [0, n0, _AT, 8, 0];
|
|
||||||
var ClientSecret = [0, n0, _CS, 8, 0];
|
|
||||||
var CodeVerifier = [0, n0, _CV, 8, 0];
|
|
||||||
var IdToken = [0, n0, _IT, 8, 0];
|
|
||||||
var RefreshToken = [0, n0, _RT, 8, 0];
|
|
||||||
var AccessDeniedException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ADE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _r, _ed],
|
|
||||||
[0, 0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(AccessDeniedException, AccessDeniedException$1);
|
|
||||||
var AuthorizationPendingException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_APE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(AuthorizationPendingException, AuthorizationPendingException$1);
|
|
||||||
var CreateTokenRequest = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_CTR,
|
|
||||||
0,
|
|
||||||
[_cI, _cS, _gT, _dC, _co, _rT, _s, _rU, _cV],
|
|
||||||
[0, [() => ClientSecret, 0], 0, 0, 0, [() => RefreshToken, 0], 64 | 0, 0, [() => CodeVerifier, 0]],
|
|
||||||
];
|
|
||||||
var CreateTokenResponse = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_CTRr,
|
|
||||||
0,
|
|
||||||
[_aT, _tT, _eI, _rT, _iT],
|
|
||||||
[[() => AccessToken, 0], 0, 1, [() => RefreshToken, 0], [() => IdToken, 0]],
|
|
||||||
];
|
|
||||||
var ExpiredTokenException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ETE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(ExpiredTokenException, ExpiredTokenException$1);
|
|
||||||
var InternalServerException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ISE,
|
|
||||||
{
|
|
||||||
[_e]: _se,
|
|
||||||
[_hE]: 500,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InternalServerException, InternalServerException$1);
|
|
||||||
var InvalidClientException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ICE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 401,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidClientException, InvalidClientException$1);
|
|
||||||
var InvalidGrantException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IGE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidGrantException, InvalidGrantException$1);
|
|
||||||
var InvalidRequestException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IRE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _r, _ed],
|
|
||||||
[0, 0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidRequestException, InvalidRequestException$1);
|
|
||||||
var InvalidScopeException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ISEn,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidScopeException, InvalidScopeException$1);
|
|
||||||
var SlowDownException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_SDE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(SlowDownException, SlowDownException$1);
|
|
||||||
var UnauthorizedClientException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_UCE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(UnauthorizedClientException, UnauthorizedClientException$1);
|
|
||||||
var UnsupportedGrantTypeException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_UGTE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(UnsupportedGrantTypeException, UnsupportedGrantTypeException$1);
|
|
||||||
var SSOOIDCServiceException = [-3, _sm, "SSOOIDCServiceException", 0, [], []];
|
|
||||||
schema.TypeRegistry.for(_sm).registerError(SSOOIDCServiceException, SSOOIDCServiceException$1);
|
|
||||||
var CreateToken = [
|
|
||||||
9,
|
|
||||||
n0,
|
|
||||||
_CT,
|
|
||||||
{
|
|
||||||
[_h]: ["POST", "/token", 200],
|
|
||||||
},
|
|
||||||
() => CreateTokenRequest,
|
|
||||||
() => CreateTokenResponse,
|
|
||||||
];
|
|
||||||
|
|
||||||
class CreateTokenCommand extends smithyClient.Command
|
|
||||||
.classBuilder()
|
|
||||||
.ep(commonParams)
|
|
||||||
.m(function (Command, cs, config, o) {
|
|
||||||
return [middlewareEndpoint.getEndpointPlugin(config, Command.getEndpointParameterInstructions())];
|
|
||||||
})
|
|
||||||
.s("AWSSSOOIDCService", "CreateToken", {})
|
|
||||||
.n("SSOOIDCClient", "CreateTokenCommand")
|
|
||||||
.sc(CreateToken)
|
|
||||||
.build() {
|
|
||||||
}
|
|
||||||
|
|
||||||
const commands = {
|
|
||||||
CreateTokenCommand,
|
|
||||||
};
|
|
||||||
class SSOOIDC extends SSOOIDCClient {
|
|
||||||
}
|
|
||||||
smithyClient.createAggregatedClient(commands, SSOOIDC);
|
|
||||||
|
|
||||||
__webpack_unused_export__ = ({
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return smithyClient.Command; }
|
|
||||||
});
|
|
||||||
__webpack_unused_export__ = ({
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return smithyClient.Client; }
|
|
||||||
});
|
|
||||||
__webpack_unused_export__ = AccessDeniedException$1;
|
|
||||||
__webpack_unused_export__ = AccessDeniedExceptionReason;
|
|
||||||
__webpack_unused_export__ = AuthorizationPendingException$1;
|
|
||||||
exports.CreateTokenCommand = CreateTokenCommand;
|
|
||||||
__webpack_unused_export__ = ExpiredTokenException$1;
|
|
||||||
__webpack_unused_export__ = InternalServerException$1;
|
|
||||||
__webpack_unused_export__ = InvalidClientException$1;
|
|
||||||
__webpack_unused_export__ = InvalidGrantException$1;
|
|
||||||
__webpack_unused_export__ = InvalidRequestException$1;
|
|
||||||
__webpack_unused_export__ = InvalidRequestExceptionReason;
|
|
||||||
__webpack_unused_export__ = InvalidScopeException$1;
|
|
||||||
__webpack_unused_export__ = SSOOIDC;
|
|
||||||
exports.SSOOIDCClient = SSOOIDCClient;
|
|
||||||
__webpack_unused_export__ = SSOOIDCServiceException$1;
|
|
||||||
__webpack_unused_export__ = SlowDownException$1;
|
|
||||||
__webpack_unused_export__ = UnauthorizedClientException$1;
|
|
||||||
__webpack_unused_export__ = UnsupportedGrantTypeException$1;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 6901:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getRuntimeConfig = void 0;
|
|
||||||
const tslib_1 = __webpack_require__(1860);
|
|
||||||
const package_json_1 = tslib_1.__importDefault(__webpack_require__(9955));
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const util_user_agent_node_1 = __webpack_require__(1656);
|
|
||||||
const config_resolver_1 = __webpack_require__(9316);
|
|
||||||
const hash_node_1 = __webpack_require__(5092);
|
|
||||||
const middleware_retry_1 = __webpack_require__(9618);
|
|
||||||
const node_config_provider_1 = __webpack_require__(5704);
|
|
||||||
const node_http_handler_1 = __webpack_require__(1279);
|
|
||||||
const util_body_length_node_1 = __webpack_require__(3638);
|
|
||||||
const util_retry_1 = __webpack_require__(5518);
|
|
||||||
const runtimeConfig_shared_1 = __webpack_require__(1546);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const util_defaults_mode_node_1 = __webpack_require__(5435);
|
|
||||||
const smithy_client_2 = __webpack_require__(1411);
|
|
||||||
const getRuntimeConfig = (config) => {
|
|
||||||
(0, smithy_client_2.emitWarningIfUnsupportedVersion)(process.version);
|
|
||||||
const defaultsMode = (0, util_defaults_mode_node_1.resolveDefaultsModeConfig)(config);
|
|
||||||
const defaultConfigProvider = () => defaultsMode().then(smithy_client_1.loadConfigsForDefaultMode);
|
|
||||||
const clientSharedValues = (0, runtimeConfig_shared_1.getRuntimeConfig)(config);
|
|
||||||
(0, core_1.emitWarningIfUnsupportedVersion)(process.version);
|
|
||||||
const loaderConfig = {
|
|
||||||
profile: config?.profile,
|
|
||||||
logger: clientSharedValues.logger,
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
...clientSharedValues,
|
|
||||||
...config,
|
|
||||||
runtime: "node",
|
|
||||||
defaultsMode,
|
|
||||||
authSchemePreference: config?.authSchemePreference ?? (0, node_config_provider_1.loadConfig)(core_1.NODE_AUTH_SCHEME_PREFERENCE_OPTIONS, loaderConfig),
|
|
||||||
bodyLengthChecker: config?.bodyLengthChecker ?? util_body_length_node_1.calculateBodyLength,
|
|
||||||
defaultUserAgentProvider: config?.defaultUserAgentProvider ??
|
|
||||||
(0, util_user_agent_node_1.createDefaultUserAgentProvider)({ serviceId: clientSharedValues.serviceId, clientVersion: package_json_1.default.version }),
|
|
||||||
maxAttempts: config?.maxAttempts ?? (0, node_config_provider_1.loadConfig)(middleware_retry_1.NODE_MAX_ATTEMPT_CONFIG_OPTIONS, config),
|
|
||||||
region: config?.region ??
|
|
||||||
(0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_REGION_CONFIG_OPTIONS, { ...config_resolver_1.NODE_REGION_CONFIG_FILE_OPTIONS, ...loaderConfig }),
|
|
||||||
requestHandler: node_http_handler_1.NodeHttpHandler.create(config?.requestHandler ?? defaultConfigProvider),
|
|
||||||
retryMode: config?.retryMode ??
|
|
||||||
(0, node_config_provider_1.loadConfig)({
|
|
||||||
...middleware_retry_1.NODE_RETRY_MODE_CONFIG_OPTIONS,
|
|
||||||
default: async () => (await defaultConfigProvider()).retryMode || util_retry_1.DEFAULT_RETRY_MODE,
|
|
||||||
}, config),
|
|
||||||
sha256: config?.sha256 ?? hash_node_1.Hash.bind(null, "sha256"),
|
|
||||||
streamCollector: config?.streamCollector ?? node_http_handler_1.streamCollector,
|
|
||||||
useDualstackEndpoint: config?.useDualstackEndpoint ?? (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
useFipsEndpoint: config?.useFipsEndpoint ?? (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
userAgentAppId: config?.userAgentAppId ?? (0, node_config_provider_1.loadConfig)(util_user_agent_node_1.NODE_APP_ID_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getRuntimeConfig = getRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 1546:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getRuntimeConfig = void 0;
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const protocols_1 = __webpack_require__(7288);
|
|
||||||
const core_2 = __webpack_require__(402);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const url_parser_1 = __webpack_require__(4494);
|
|
||||||
const util_base64_1 = __webpack_require__(8385);
|
|
||||||
const util_utf8_1 = __webpack_require__(1577);
|
|
||||||
const httpAuthSchemeProvider_1 = __webpack_require__(8396);
|
|
||||||
const endpointResolver_1 = __webpack_require__(546);
|
|
||||||
const getRuntimeConfig = (config) => {
|
|
||||||
return {
|
|
||||||
apiVersion: "2019-06-10",
|
|
||||||
base64Decoder: config?.base64Decoder ?? util_base64_1.fromBase64,
|
|
||||||
base64Encoder: config?.base64Encoder ?? util_base64_1.toBase64,
|
|
||||||
disableHostPrefix: config?.disableHostPrefix ?? false,
|
|
||||||
endpointProvider: config?.endpointProvider ?? endpointResolver_1.defaultEndpointResolver,
|
|
||||||
extensions: config?.extensions ?? [],
|
|
||||||
httpAuthSchemeProvider: config?.httpAuthSchemeProvider ?? httpAuthSchemeProvider_1.defaultSSOOIDCHttpAuthSchemeProvider,
|
|
||||||
httpAuthSchemes: config?.httpAuthSchemes ?? [
|
|
||||||
{
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("aws.auth#sigv4"),
|
|
||||||
signer: new core_1.AwsSdkSigV4Signer(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("smithy.api#noAuth") || (async () => ({})),
|
|
||||||
signer: new core_2.NoAuthSigner(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
logger: config?.logger ?? new smithy_client_1.NoOpLogger(),
|
|
||||||
protocol: config?.protocol ?? new protocols_1.AwsRestJsonProtocol({ defaultNamespace: "com.amazonaws.ssooidc" }),
|
|
||||||
serviceId: config?.serviceId ?? "SSO OIDC",
|
|
||||||
urlParser: config?.urlParser ?? url_parser_1.parseUrl,
|
|
||||||
utf8Decoder: config?.utf8Decoder ?? util_utf8_1.fromUtf8,
|
|
||||||
utf8Encoder: config?.utf8Encoder ?? util_utf8_1.toUtf8,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getRuntimeConfig = getRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9955:
|
|
||||||
/***/ ((module) => {
|
|
||||||
|
|
||||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@aws-sdk/nested-clients","version":"3.933.0","description":"Nested clients for AWS SDK packages.","main":"./dist-cjs/index.js","module":"./dist-es/index.js","types":"./dist-types/index.d.ts","scripts":{"build":"yarn lint && concurrently \'yarn:build:cjs\' \'yarn:build:es\' \'yarn:build:types\'","build:cjs":"node ../../scripts/compilation/inline nested-clients","build:es":"tsc -p tsconfig.es.json","build:include:deps":"lerna run --scope $npm_package_name --include-dependencies build","build:types":"tsc -p tsconfig.types.json","build:types:downlevel":"downlevel-dts dist-types dist-types/ts3.4","clean":"rimraf ./dist-* && rimraf *.tsbuildinfo","lint":"node ../../scripts/validation/submodules-linter.js --pkg nested-clients","test":"yarn g:vitest run","test:watch":"yarn g:vitest watch"},"engines":{"node":">=18.0.0"},"sideEffects":false,"author":{"name":"AWS SDK for JavaScript Team","url":"https://aws.amazon.com/javascript/"},"license":"Apache-2.0","dependencies":{"@aws-crypto/sha256-browser":"5.2.0","@aws-crypto/sha256-js":"5.2.0","@aws-sdk/core":"3.932.0","@aws-sdk/middleware-host-header":"3.930.0","@aws-sdk/middleware-logger":"3.930.0","@aws-sdk/middleware-recursion-detection":"3.933.0","@aws-sdk/middleware-user-agent":"3.932.0","@aws-sdk/region-config-resolver":"3.930.0","@aws-sdk/types":"3.930.0","@aws-sdk/util-endpoints":"3.930.0","@aws-sdk/util-user-agent-browser":"3.930.0","@aws-sdk/util-user-agent-node":"3.932.0","@smithy/config-resolver":"^4.4.3","@smithy/core":"^3.18.2","@smithy/fetch-http-handler":"^5.3.6","@smithy/hash-node":"^4.2.5","@smithy/invalid-dependency":"^4.2.5","@smithy/middleware-content-length":"^4.2.5","@smithy/middleware-endpoint":"^4.3.9","@smithy/middleware-retry":"^4.4.9","@smithy/middleware-serde":"^4.2.5","@smithy/middleware-stack":"^4.2.5","@smithy/node-config-provider":"^4.3.5","@smithy/node-http-handler":"^4.4.5","@smithy/protocol-http":"^5.3.5","@smithy/smithy-client":"^4.9.5","@smithy/types":"^4.9.0","@smithy/url-parser":"^4.2.5","@smithy/util-base64":"^4.3.0","@smithy/util-body-length-browser":"^4.2.0","@smithy/util-body-length-node":"^4.2.1","@smithy/util-defaults-mode-browser":"^4.3.8","@smithy/util-defaults-mode-node":"^4.2.11","@smithy/util-endpoints":"^3.2.5","@smithy/util-middleware":"^4.2.5","@smithy/util-retry":"^4.2.5","@smithy/util-utf8":"^4.2.0","tslib":"^2.6.2"},"devDependencies":{"concurrently":"7.0.0","downlevel-dts":"0.10.1","rimraf":"3.0.2","typescript":"~5.8.3"},"typesVersions":{"<4.0":{"dist-types/*":["dist-types/ts3.4/*"]}},"files":["./sso-oidc.d.ts","./sso-oidc.js","./sts.d.ts","./sts.js","dist-*/**"],"browser":{"./dist-es/submodules/sso-oidc/runtimeConfig":"./dist-es/submodules/sso-oidc/runtimeConfig.browser","./dist-es/submodules/sts/runtimeConfig":"./dist-es/submodules/sts/runtimeConfig.browser"},"react-native":{},"homepage":"https://github.com/aws/aws-sdk-js-v3/tree/main/packages/nested-clients","repository":{"type":"git","url":"https://github.com/aws/aws-sdk-js-v3.git","directory":"packages/nested-clients"},"exports":{"./sso-oidc":{"types":"./dist-types/submodules/sso-oidc/index.d.ts","module":"./dist-es/submodules/sso-oidc/index.js","node":"./dist-cjs/submodules/sso-oidc/index.js","import":"./dist-es/submodules/sso-oidc/index.js","require":"./dist-cjs/submodules/sso-oidc/index.js"},"./sts":{"types":"./dist-types/submodules/sts/index.d.ts","module":"./dist-es/submodules/sts/index.js","node":"./dist-cjs/submodules/sts/index.js","import":"./dist-es/submodules/sts/index.js","require":"./dist-cjs/submodules/sts/index.js"}}}');
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-387
@@ -1,387 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 566;
|
|
||||||
exports.ids = [566];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 566:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
var __webpack_unused_export__;
|
|
||||||
|
|
||||||
|
|
||||||
var propertyProvider = __webpack_require__(1238);
|
|
||||||
var url = __webpack_require__(7016);
|
|
||||||
var buffer = __webpack_require__(181);
|
|
||||||
var http = __webpack_require__(8611);
|
|
||||||
var nodeConfigProvider = __webpack_require__(5704);
|
|
||||||
var urlParser = __webpack_require__(4494);
|
|
||||||
|
|
||||||
function httpRequest(options) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const req = http.request({
|
|
||||||
method: "GET",
|
|
||||||
...options,
|
|
||||||
hostname: options.hostname?.replace(/^\[(.+)\]$/, "$1"),
|
|
||||||
});
|
|
||||||
req.on("error", (err) => {
|
|
||||||
reject(Object.assign(new propertyProvider.ProviderError("Unable to connect to instance metadata service"), err));
|
|
||||||
req.destroy();
|
|
||||||
});
|
|
||||||
req.on("timeout", () => {
|
|
||||||
reject(new propertyProvider.ProviderError("TimeoutError from instance metadata service"));
|
|
||||||
req.destroy();
|
|
||||||
});
|
|
||||||
req.on("response", (res) => {
|
|
||||||
const { statusCode = 400 } = res;
|
|
||||||
if (statusCode < 200 || 300 <= statusCode) {
|
|
||||||
reject(Object.assign(new propertyProvider.ProviderError("Error response received from instance metadata service"), { statusCode }));
|
|
||||||
req.destroy();
|
|
||||||
}
|
|
||||||
const chunks = [];
|
|
||||||
res.on("data", (chunk) => {
|
|
||||||
chunks.push(chunk);
|
|
||||||
});
|
|
||||||
res.on("end", () => {
|
|
||||||
resolve(buffer.Buffer.concat(chunks));
|
|
||||||
req.destroy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const isImdsCredentials = (arg) => Boolean(arg) &&
|
|
||||||
typeof arg === "object" &&
|
|
||||||
typeof arg.AccessKeyId === "string" &&
|
|
||||||
typeof arg.SecretAccessKey === "string" &&
|
|
||||||
typeof arg.Token === "string" &&
|
|
||||||
typeof arg.Expiration === "string";
|
|
||||||
const fromImdsCredentials = (creds) => ({
|
|
||||||
accessKeyId: creds.AccessKeyId,
|
|
||||||
secretAccessKey: creds.SecretAccessKey,
|
|
||||||
sessionToken: creds.Token,
|
|
||||||
expiration: new Date(creds.Expiration),
|
|
||||||
...(creds.AccountId && { accountId: creds.AccountId }),
|
|
||||||
});
|
|
||||||
|
|
||||||
const DEFAULT_TIMEOUT = 1000;
|
|
||||||
const DEFAULT_MAX_RETRIES = 0;
|
|
||||||
const providerConfigFromInit = ({ maxRetries = DEFAULT_MAX_RETRIES, timeout = DEFAULT_TIMEOUT, }) => ({ maxRetries, timeout });
|
|
||||||
|
|
||||||
const retry = (toRetry, maxRetries) => {
|
|
||||||
let promise = toRetry();
|
|
||||||
for (let i = 0; i < maxRetries; i++) {
|
|
||||||
promise = promise.catch(toRetry);
|
|
||||||
}
|
|
||||||
return promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ENV_CMDS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
|
|
||||||
const ENV_CMDS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
|
|
||||||
const ENV_CMDS_AUTH_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN";
|
|
||||||
const fromContainerMetadata = (init = {}) => {
|
|
||||||
const { timeout, maxRetries } = providerConfigFromInit(init);
|
|
||||||
return () => retry(async () => {
|
|
||||||
const requestOptions = await getCmdsUri({ logger: init.logger });
|
|
||||||
const credsResponse = JSON.parse(await requestFromEcsImds(timeout, requestOptions));
|
|
||||||
if (!isImdsCredentials(credsResponse)) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError("Invalid response received from instance metadata service.", {
|
|
||||||
logger: init.logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return fromImdsCredentials(credsResponse);
|
|
||||||
}, maxRetries);
|
|
||||||
};
|
|
||||||
const requestFromEcsImds = async (timeout, options) => {
|
|
||||||
if (process.env[ENV_CMDS_AUTH_TOKEN]) {
|
|
||||||
options.headers = {
|
|
||||||
...options.headers,
|
|
||||||
Authorization: process.env[ENV_CMDS_AUTH_TOKEN],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const buffer = await httpRequest({
|
|
||||||
...options,
|
|
||||||
timeout,
|
|
||||||
});
|
|
||||||
return buffer.toString();
|
|
||||||
};
|
|
||||||
const CMDS_IP = "169.254.170.2";
|
|
||||||
const GREENGRASS_HOSTS = {
|
|
||||||
localhost: true,
|
|
||||||
"127.0.0.1": true,
|
|
||||||
};
|
|
||||||
const GREENGRASS_PROTOCOLS = {
|
|
||||||
"http:": true,
|
|
||||||
"https:": true,
|
|
||||||
};
|
|
||||||
const getCmdsUri = async ({ logger }) => {
|
|
||||||
if (process.env[ENV_CMDS_RELATIVE_URI]) {
|
|
||||||
return {
|
|
||||||
hostname: CMDS_IP,
|
|
||||||
path: process.env[ENV_CMDS_RELATIVE_URI],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (process.env[ENV_CMDS_FULL_URI]) {
|
|
||||||
const parsed = url.parse(process.env[ENV_CMDS_FULL_URI]);
|
|
||||||
if (!parsed.hostname || !(parsed.hostname in GREENGRASS_HOSTS)) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`${parsed.hostname} is not a valid container metadata service hostname`, {
|
|
||||||
tryNextLink: false,
|
|
||||||
logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!parsed.protocol || !(parsed.protocol in GREENGRASS_PROTOCOLS)) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`${parsed.protocol} is not a valid container metadata service protocol`, {
|
|
||||||
tryNextLink: false,
|
|
||||||
logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...parsed,
|
|
||||||
port: parsed.port ? parseInt(parsed.port, 10) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
throw new propertyProvider.CredentialsProviderError("The container metadata credential provider cannot be used unless" +
|
|
||||||
` the ${ENV_CMDS_RELATIVE_URI} or ${ENV_CMDS_FULL_URI} environment` +
|
|
||||||
" variable is set", {
|
|
||||||
tryNextLink: false,
|
|
||||||
logger,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
class InstanceMetadataV1FallbackError extends propertyProvider.CredentialsProviderError {
|
|
||||||
tryNextLink;
|
|
||||||
name = "InstanceMetadataV1FallbackError";
|
|
||||||
constructor(message, tryNextLink = true) {
|
|
||||||
super(message, tryNextLink);
|
|
||||||
this.tryNextLink = tryNextLink;
|
|
||||||
Object.setPrototypeOf(this, InstanceMetadataV1FallbackError.prototype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.yI = void 0;
|
|
||||||
(function (Endpoint) {
|
|
||||||
Endpoint["IPv4"] = "http://169.254.169.254";
|
|
||||||
Endpoint["IPv6"] = "http://[fd00:ec2::254]";
|
|
||||||
})(exports.yI || (exports.yI = {}));
|
|
||||||
|
|
||||||
const ENV_ENDPOINT_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT";
|
|
||||||
const CONFIG_ENDPOINT_NAME = "ec2_metadata_service_endpoint";
|
|
||||||
const ENDPOINT_CONFIG_OPTIONS = {
|
|
||||||
environmentVariableSelector: (env) => env[ENV_ENDPOINT_NAME],
|
|
||||||
configFileSelector: (profile) => profile[CONFIG_ENDPOINT_NAME],
|
|
||||||
default: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
var EndpointMode;
|
|
||||||
(function (EndpointMode) {
|
|
||||||
EndpointMode["IPv4"] = "IPv4";
|
|
||||||
EndpointMode["IPv6"] = "IPv6";
|
|
||||||
})(EndpointMode || (EndpointMode = {}));
|
|
||||||
|
|
||||||
const ENV_ENDPOINT_MODE_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE";
|
|
||||||
const CONFIG_ENDPOINT_MODE_NAME = "ec2_metadata_service_endpoint_mode";
|
|
||||||
const ENDPOINT_MODE_CONFIG_OPTIONS = {
|
|
||||||
environmentVariableSelector: (env) => env[ENV_ENDPOINT_MODE_NAME],
|
|
||||||
configFileSelector: (profile) => profile[CONFIG_ENDPOINT_MODE_NAME],
|
|
||||||
default: EndpointMode.IPv4,
|
|
||||||
};
|
|
||||||
|
|
||||||
const getInstanceMetadataEndpoint = async () => urlParser.parseUrl((await getFromEndpointConfig()) || (await getFromEndpointModeConfig()));
|
|
||||||
const getFromEndpointConfig = async () => nodeConfigProvider.loadConfig(ENDPOINT_CONFIG_OPTIONS)();
|
|
||||||
const getFromEndpointModeConfig = async () => {
|
|
||||||
const endpointMode = await nodeConfigProvider.loadConfig(ENDPOINT_MODE_CONFIG_OPTIONS)();
|
|
||||||
switch (endpointMode) {
|
|
||||||
case EndpointMode.IPv4:
|
|
||||||
return exports.yI.IPv4;
|
|
||||||
case EndpointMode.IPv6:
|
|
||||||
return exports.yI.IPv6;
|
|
||||||
default:
|
|
||||||
throw new Error(`Unsupported endpoint mode: ${endpointMode}.` + ` Select from ${Object.values(EndpointMode)}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const STATIC_STABILITY_REFRESH_INTERVAL_SECONDS = 5 * 60;
|
|
||||||
const STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS = 5 * 60;
|
|
||||||
const STATIC_STABILITY_DOC_URL = "https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html";
|
|
||||||
const getExtendedInstanceMetadataCredentials = (credentials, logger) => {
|
|
||||||
const refreshInterval = STATIC_STABILITY_REFRESH_INTERVAL_SECONDS +
|
|
||||||
Math.floor(Math.random() * STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS);
|
|
||||||
const newExpiration = new Date(Date.now() + refreshInterval * 1000);
|
|
||||||
logger.warn("Attempting credential expiration extension due to a credential service availability issue. A refresh of these " +
|
|
||||||
`credentials will be attempted after ${new Date(newExpiration)}.\nFor more information, please visit: ` +
|
|
||||||
STATIC_STABILITY_DOC_URL);
|
|
||||||
const originalExpiration = credentials.originalExpiration ?? credentials.expiration;
|
|
||||||
return {
|
|
||||||
...credentials,
|
|
||||||
...(originalExpiration ? { originalExpiration } : {}),
|
|
||||||
expiration: newExpiration,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const staticStabilityProvider = (provider, options = {}) => {
|
|
||||||
const logger = options?.logger || console;
|
|
||||||
let pastCredentials;
|
|
||||||
return async () => {
|
|
||||||
let credentials;
|
|
||||||
try {
|
|
||||||
credentials = await provider();
|
|
||||||
if (credentials.expiration && credentials.expiration.getTime() < Date.now()) {
|
|
||||||
credentials = getExtendedInstanceMetadataCredentials(credentials, logger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
if (pastCredentials) {
|
|
||||||
logger.warn("Credential renew failed: ", e);
|
|
||||||
credentials = getExtendedInstanceMetadataCredentials(pastCredentials, logger);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pastCredentials = credentials;
|
|
||||||
return credentials;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const IMDS_PATH = "/latest/meta-data/iam/security-credentials/";
|
|
||||||
const IMDS_TOKEN_PATH = "/latest/api/token";
|
|
||||||
const AWS_EC2_METADATA_V1_DISABLED = "AWS_EC2_METADATA_V1_DISABLED";
|
|
||||||
const PROFILE_AWS_EC2_METADATA_V1_DISABLED = "ec2_metadata_v1_disabled";
|
|
||||||
const X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token";
|
|
||||||
const fromInstanceMetadata = (init = {}) => staticStabilityProvider(getInstanceMetadataProvider(init), { logger: init.logger });
|
|
||||||
const getInstanceMetadataProvider = (init = {}) => {
|
|
||||||
let disableFetchToken = false;
|
|
||||||
const { logger, profile } = init;
|
|
||||||
const { timeout, maxRetries } = providerConfigFromInit(init);
|
|
||||||
const getCredentials = async (maxRetries, options) => {
|
|
||||||
const isImdsV1Fallback = disableFetchToken || options.headers?.[X_AWS_EC2_METADATA_TOKEN] == null;
|
|
||||||
if (isImdsV1Fallback) {
|
|
||||||
let fallbackBlockedFromProfile = false;
|
|
||||||
let fallbackBlockedFromProcessEnv = false;
|
|
||||||
const configValue = await nodeConfigProvider.loadConfig({
|
|
||||||
environmentVariableSelector: (env) => {
|
|
||||||
const envValue = env[AWS_EC2_METADATA_V1_DISABLED];
|
|
||||||
fallbackBlockedFromProcessEnv = !!envValue && envValue !== "false";
|
|
||||||
if (envValue === undefined) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`${AWS_EC2_METADATA_V1_DISABLED} not set in env, checking config file next.`, { logger: init.logger });
|
|
||||||
}
|
|
||||||
return fallbackBlockedFromProcessEnv;
|
|
||||||
},
|
|
||||||
configFileSelector: (profile) => {
|
|
||||||
const profileValue = profile[PROFILE_AWS_EC2_METADATA_V1_DISABLED];
|
|
||||||
fallbackBlockedFromProfile = !!profileValue && profileValue !== "false";
|
|
||||||
return fallbackBlockedFromProfile;
|
|
||||||
},
|
|
||||||
default: false,
|
|
||||||
}, {
|
|
||||||
profile,
|
|
||||||
})();
|
|
||||||
if (init.ec2MetadataV1Disabled || configValue) {
|
|
||||||
const causes = [];
|
|
||||||
if (init.ec2MetadataV1Disabled)
|
|
||||||
causes.push("credential provider initialization (runtime option ec2MetadataV1Disabled)");
|
|
||||||
if (fallbackBlockedFromProfile)
|
|
||||||
causes.push(`config file profile (${PROFILE_AWS_EC2_METADATA_V1_DISABLED})`);
|
|
||||||
if (fallbackBlockedFromProcessEnv)
|
|
||||||
causes.push(`process environment variable (${AWS_EC2_METADATA_V1_DISABLED})`);
|
|
||||||
throw new InstanceMetadataV1FallbackError(`AWS EC2 Metadata v1 fallback has been blocked by AWS SDK configuration in the following: [${causes.join(", ")}].`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const imdsProfile = (await retry(async () => {
|
|
||||||
let profile;
|
|
||||||
try {
|
|
||||||
profile = await getProfile(options);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.statusCode === 401) {
|
|
||||||
disableFetchToken = false;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return profile;
|
|
||||||
}, maxRetries)).trim();
|
|
||||||
return retry(async () => {
|
|
||||||
let creds;
|
|
||||||
try {
|
|
||||||
creds = await getCredentialsFromProfile(imdsProfile, options, init);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.statusCode === 401) {
|
|
||||||
disableFetchToken = false;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return creds;
|
|
||||||
}, maxRetries);
|
|
||||||
};
|
|
||||||
return async () => {
|
|
||||||
const endpoint = await getInstanceMetadataEndpoint();
|
|
||||||
if (disableFetchToken) {
|
|
||||||
logger?.debug("AWS SDK Instance Metadata", "using v1 fallback (no token fetch)");
|
|
||||||
return getCredentials(maxRetries, { ...endpoint, timeout });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let token;
|
|
||||||
try {
|
|
||||||
token = (await getMetadataToken({ ...endpoint, timeout })).toString();
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (error?.statusCode === 400) {
|
|
||||||
throw Object.assign(error, {
|
|
||||||
message: "EC2 Metadata token request returned error",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (error.message === "TimeoutError" || [403, 404, 405].includes(error.statusCode)) {
|
|
||||||
disableFetchToken = true;
|
|
||||||
}
|
|
||||||
logger?.debug("AWS SDK Instance Metadata", "using v1 fallback (initial)");
|
|
||||||
return getCredentials(maxRetries, { ...endpoint, timeout });
|
|
||||||
}
|
|
||||||
return getCredentials(maxRetries, {
|
|
||||||
...endpoint,
|
|
||||||
headers: {
|
|
||||||
[X_AWS_EC2_METADATA_TOKEN]: token,
|
|
||||||
},
|
|
||||||
timeout,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const getMetadataToken = async (options) => httpRequest({
|
|
||||||
...options,
|
|
||||||
path: IMDS_TOKEN_PATH,
|
|
||||||
method: "PUT",
|
|
||||||
headers: {
|
|
||||||
"x-aws-ec2-metadata-token-ttl-seconds": "21600",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const getProfile = async (options) => (await httpRequest({ ...options, path: IMDS_PATH })).toString();
|
|
||||||
const getCredentialsFromProfile = async (profile, options, init) => {
|
|
||||||
const credentialsResponse = JSON.parse((await httpRequest({
|
|
||||||
...options,
|
|
||||||
path: IMDS_PATH + profile,
|
|
||||||
})).toString());
|
|
||||||
if (!isImdsCredentials(credentialsResponse)) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError("Invalid response received from instance metadata service.", {
|
|
||||||
logger: init.logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return fromImdsCredentials(credentialsResponse);
|
|
||||||
};
|
|
||||||
|
|
||||||
__webpack_unused_export__ = DEFAULT_MAX_RETRIES;
|
|
||||||
__webpack_unused_export__ = DEFAULT_TIMEOUT;
|
|
||||||
__webpack_unused_export__ = ENV_CMDS_AUTH_TOKEN;
|
|
||||||
exports.ENV_CMDS_FULL_URI = ENV_CMDS_FULL_URI;
|
|
||||||
exports.ENV_CMDS_RELATIVE_URI = ENV_CMDS_RELATIVE_URI;
|
|
||||||
exports.fromContainerMetadata = fromContainerMetadata;
|
|
||||||
exports.fromInstanceMetadata = fromInstanceMetadata;
|
|
||||||
exports.getInstanceMetadataEndpoint = getInstanceMetadataEndpoint;
|
|
||||||
exports.httpRequest = httpRequest;
|
|
||||||
__webpack_unused_export__ = providerConfigFromInit;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-266
@@ -1,266 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 579;
|
|
||||||
exports.ids = [579];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 6579:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var utilUtf8 = __webpack_require__(1577);
|
|
||||||
|
|
||||||
class EventStreamSerde {
|
|
||||||
marshaller;
|
|
||||||
serializer;
|
|
||||||
deserializer;
|
|
||||||
serdeContext;
|
|
||||||
defaultContentType;
|
|
||||||
constructor({ marshaller, serializer, deserializer, serdeContext, defaultContentType, }) {
|
|
||||||
this.marshaller = marshaller;
|
|
||||||
this.serializer = serializer;
|
|
||||||
this.deserializer = deserializer;
|
|
||||||
this.serdeContext = serdeContext;
|
|
||||||
this.defaultContentType = defaultContentType;
|
|
||||||
}
|
|
||||||
async serializeEventStream({ eventStream, requestSchema, initialRequest, }) {
|
|
||||||
const marshaller = this.marshaller;
|
|
||||||
const eventStreamMember = requestSchema.getEventStreamMember();
|
|
||||||
const unionSchema = requestSchema.getMemberSchema(eventStreamMember);
|
|
||||||
const serializer = this.serializer;
|
|
||||||
const defaultContentType = this.defaultContentType;
|
|
||||||
const initialRequestMarker = Symbol("initialRequestMarker");
|
|
||||||
const eventStreamIterable = {
|
|
||||||
async *[Symbol.asyncIterator]() {
|
|
||||||
if (initialRequest) {
|
|
||||||
const headers = {
|
|
||||||
":event-type": { type: "string", value: "initial-request" },
|
|
||||||
":message-type": { type: "string", value: "event" },
|
|
||||||
":content-type": { type: "string", value: defaultContentType },
|
|
||||||
};
|
|
||||||
serializer.write(requestSchema, initialRequest);
|
|
||||||
const body = serializer.flush();
|
|
||||||
yield {
|
|
||||||
[initialRequestMarker]: true,
|
|
||||||
headers,
|
|
||||||
body,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
for await (const page of eventStream) {
|
|
||||||
yield page;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return marshaller.serialize(eventStreamIterable, (event) => {
|
|
||||||
if (event[initialRequestMarker]) {
|
|
||||||
return {
|
|
||||||
headers: event.headers,
|
|
||||||
body: event.body,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const unionMember = Object.keys(event).find((key) => {
|
|
||||||
return key !== "__type";
|
|
||||||
}) ?? "";
|
|
||||||
const { additionalHeaders, body, eventType, explicitPayloadContentType } = this.writeEventBody(unionMember, unionSchema, event);
|
|
||||||
const headers = {
|
|
||||||
":event-type": { type: "string", value: eventType },
|
|
||||||
":message-type": { type: "string", value: "event" },
|
|
||||||
":content-type": { type: "string", value: explicitPayloadContentType ?? defaultContentType },
|
|
||||||
...additionalHeaders,
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
headers,
|
|
||||||
body,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async deserializeEventStream({ response, responseSchema, initialResponseContainer, }) {
|
|
||||||
const marshaller = this.marshaller;
|
|
||||||
const eventStreamMember = responseSchema.getEventStreamMember();
|
|
||||||
const unionSchema = responseSchema.getMemberSchema(eventStreamMember);
|
|
||||||
const memberSchemas = unionSchema.getMemberSchemas();
|
|
||||||
const initialResponseMarker = Symbol("initialResponseMarker");
|
|
||||||
const asyncIterable = marshaller.deserialize(response.body, async (event) => {
|
|
||||||
const unionMember = Object.keys(event).find((key) => {
|
|
||||||
return key !== "__type";
|
|
||||||
}) ?? "";
|
|
||||||
const body = event[unionMember].body;
|
|
||||||
if (unionMember === "initial-response") {
|
|
||||||
const dataObject = await this.deserializer.read(responseSchema, body);
|
|
||||||
delete dataObject[eventStreamMember];
|
|
||||||
return {
|
|
||||||
[initialResponseMarker]: true,
|
|
||||||
...dataObject,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (unionMember in memberSchemas) {
|
|
||||||
const eventStreamSchema = memberSchemas[unionMember];
|
|
||||||
if (eventStreamSchema.isStructSchema()) {
|
|
||||||
const out = {};
|
|
||||||
let hasBindings = false;
|
|
||||||
for (const [name, member] of eventStreamSchema.structIterator()) {
|
|
||||||
const { eventHeader, eventPayload } = member.getMergedTraits();
|
|
||||||
hasBindings = hasBindings || Boolean(eventHeader || eventPayload);
|
|
||||||
if (eventPayload) {
|
|
||||||
if (member.isBlobSchema()) {
|
|
||||||
out[name] = body;
|
|
||||||
}
|
|
||||||
else if (member.isStringSchema()) {
|
|
||||||
out[name] = (this.serdeContext?.utf8Encoder ?? utilUtf8.toUtf8)(body);
|
|
||||||
}
|
|
||||||
else if (member.isStructSchema()) {
|
|
||||||
out[name] = await this.deserializer.read(member, body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (eventHeader) {
|
|
||||||
const value = event[unionMember].headers[name]?.value;
|
|
||||||
if (value != null) {
|
|
||||||
if (member.isNumericSchema()) {
|
|
||||||
if (value && typeof value === "object" && "bytes" in value) {
|
|
||||||
out[name] = BigInt(value.toString());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
out[name] = Number(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
out[name] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasBindings) {
|
|
||||||
return {
|
|
||||||
[unionMember]: out,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
[unionMember]: await this.deserializer.read(eventStreamSchema, body),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return {
|
|
||||||
$unknown: event,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const asyncIterator = asyncIterable[Symbol.asyncIterator]();
|
|
||||||
const firstEvent = await asyncIterator.next();
|
|
||||||
if (firstEvent.done) {
|
|
||||||
return asyncIterable;
|
|
||||||
}
|
|
||||||
if (firstEvent.value?.[initialResponseMarker]) {
|
|
||||||
if (!responseSchema) {
|
|
||||||
throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");
|
|
||||||
}
|
|
||||||
for (const [key, value] of Object.entries(firstEvent.value)) {
|
|
||||||
initialResponseContainer[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
async *[Symbol.asyncIterator]() {
|
|
||||||
if (!firstEvent?.value?.[initialResponseMarker]) {
|
|
||||||
yield firstEvent.value;
|
|
||||||
}
|
|
||||||
while (true) {
|
|
||||||
const { done, value } = await asyncIterator.next();
|
|
||||||
if (done) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
yield value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
writeEventBody(unionMember, unionSchema, event) {
|
|
||||||
const serializer = this.serializer;
|
|
||||||
let eventType = unionMember;
|
|
||||||
let explicitPayloadMember = null;
|
|
||||||
let explicitPayloadContentType;
|
|
||||||
const isKnownSchema = (() => {
|
|
||||||
const struct = unionSchema.getSchema();
|
|
||||||
return struct[4].includes(unionMember);
|
|
||||||
})();
|
|
||||||
const additionalHeaders = {};
|
|
||||||
if (!isKnownSchema) {
|
|
||||||
const [type, value] = event[unionMember];
|
|
||||||
eventType = type;
|
|
||||||
serializer.write(15, value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const eventSchema = unionSchema.getMemberSchema(unionMember);
|
|
||||||
if (eventSchema.isStructSchema()) {
|
|
||||||
for (const [memberName, memberSchema] of eventSchema.structIterator()) {
|
|
||||||
const { eventHeader, eventPayload } = memberSchema.getMergedTraits();
|
|
||||||
if (eventPayload) {
|
|
||||||
explicitPayloadMember = memberName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (eventHeader) {
|
|
||||||
const value = event[unionMember][memberName];
|
|
||||||
let type = "binary";
|
|
||||||
if (memberSchema.isNumericSchema()) {
|
|
||||||
if ((-2) ** 31 <= value && value <= 2 ** 31 - 1) {
|
|
||||||
type = "integer";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
type = "long";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (memberSchema.isTimestampSchema()) {
|
|
||||||
type = "timestamp";
|
|
||||||
}
|
|
||||||
else if (memberSchema.isStringSchema()) {
|
|
||||||
type = "string";
|
|
||||||
}
|
|
||||||
else if (memberSchema.isBooleanSchema()) {
|
|
||||||
type = "boolean";
|
|
||||||
}
|
|
||||||
if (value != null) {
|
|
||||||
additionalHeaders[memberName] = {
|
|
||||||
type,
|
|
||||||
value,
|
|
||||||
};
|
|
||||||
delete event[unionMember][memberName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (explicitPayloadMember !== null) {
|
|
||||||
const payloadSchema = eventSchema.getMemberSchema(explicitPayloadMember);
|
|
||||||
if (payloadSchema.isBlobSchema()) {
|
|
||||||
explicitPayloadContentType = "application/octet-stream";
|
|
||||||
}
|
|
||||||
else if (payloadSchema.isStringSchema()) {
|
|
||||||
explicitPayloadContentType = "text/plain";
|
|
||||||
}
|
|
||||||
serializer.write(payloadSchema, event[unionMember][explicitPayloadMember]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
serializer.write(eventSchema, event[unionMember]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const messageSerialization = serializer.flush();
|
|
||||||
const body = typeof messageSerialization === "string"
|
|
||||||
? (this.serdeContext?.utf8Decoder ?? utilUtf8.fromUtf8)(messageSerialization)
|
|
||||||
: messageSerialization;
|
|
||||||
return {
|
|
||||||
body,
|
|
||||||
eventType,
|
|
||||||
explicitPayloadContentType,
|
|
||||||
additionalHeaders,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.EventStreamSerde = EventStreamSerde;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-234
@@ -1,234 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 605;
|
|
||||||
exports.ids = [605];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 1509:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.checkUrl = void 0;
|
|
||||||
const property_provider_1 = __webpack_require__(1238);
|
|
||||||
const LOOPBACK_CIDR_IPv4 = "127.0.0.0/8";
|
|
||||||
const LOOPBACK_CIDR_IPv6 = "::1/128";
|
|
||||||
const ECS_CONTAINER_HOST = "169.254.170.2";
|
|
||||||
const EKS_CONTAINER_HOST_IPv4 = "169.254.170.23";
|
|
||||||
const EKS_CONTAINER_HOST_IPv6 = "[fd00:ec2::23]";
|
|
||||||
const checkUrl = (url, logger) => {
|
|
||||||
if (url.protocol === "https:") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (url.hostname === ECS_CONTAINER_HOST ||
|
|
||||||
url.hostname === EKS_CONTAINER_HOST_IPv4 ||
|
|
||||||
url.hostname === EKS_CONTAINER_HOST_IPv6) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (url.hostname.includes("[")) {
|
|
||||||
if (url.hostname === "[::1]" || url.hostname === "[0000:0000:0000:0000:0000:0000:0000:0001]") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (url.hostname === "localhost") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const ipComponents = url.hostname.split(".");
|
|
||||||
const inRange = (component) => {
|
|
||||||
const num = parseInt(component, 10);
|
|
||||||
return 0 <= num && num <= 255;
|
|
||||||
};
|
|
||||||
if (ipComponents[0] === "127" &&
|
|
||||||
inRange(ipComponents[1]) &&
|
|
||||||
inRange(ipComponents[2]) &&
|
|
||||||
inRange(ipComponents[3]) &&
|
|
||||||
ipComponents.length === 4) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new property_provider_1.CredentialsProviderError(`URL not accepted. It must either be HTTPS or match one of the following:
|
|
||||||
- loopback CIDR 127.0.0.0/8 or [::1/128]
|
|
||||||
- ECS container host 169.254.170.2
|
|
||||||
- EKS container host 169.254.170.23 or [fd00:ec2::23]`, { logger });
|
|
||||||
};
|
|
||||||
exports.checkUrl = checkUrl;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 6331:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.fromHttp = void 0;
|
|
||||||
const tslib_1 = __webpack_require__(1860);
|
|
||||||
const client_1 = __webpack_require__(5152);
|
|
||||||
const node_http_handler_1 = __webpack_require__(1279);
|
|
||||||
const property_provider_1 = __webpack_require__(1238);
|
|
||||||
const promises_1 = tslib_1.__importDefault(__webpack_require__(1943));
|
|
||||||
const checkUrl_1 = __webpack_require__(1509);
|
|
||||||
const requestHelpers_1 = __webpack_require__(8914);
|
|
||||||
const retry_wrapper_1 = __webpack_require__(1122);
|
|
||||||
const AWS_CONTAINER_CREDENTIALS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
|
|
||||||
const DEFAULT_LINK_LOCAL_HOST = "http://169.254.170.2";
|
|
||||||
const AWS_CONTAINER_CREDENTIALS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
|
|
||||||
const AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE";
|
|
||||||
const AWS_CONTAINER_AUTHORIZATION_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN";
|
|
||||||
const fromHttp = (options = {}) => {
|
|
||||||
options.logger?.debug("@aws-sdk/credential-provider-http - fromHttp");
|
|
||||||
let host;
|
|
||||||
const relative = options.awsContainerCredentialsRelativeUri ?? process.env[AWS_CONTAINER_CREDENTIALS_RELATIVE_URI];
|
|
||||||
const full = options.awsContainerCredentialsFullUri ?? process.env[AWS_CONTAINER_CREDENTIALS_FULL_URI];
|
|
||||||
const token = options.awsContainerAuthorizationToken ?? process.env[AWS_CONTAINER_AUTHORIZATION_TOKEN];
|
|
||||||
const tokenFile = options.awsContainerAuthorizationTokenFile ?? process.env[AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE];
|
|
||||||
const warn = options.logger?.constructor?.name === "NoOpLogger" || !options.logger?.warn
|
|
||||||
? console.warn
|
|
||||||
: options.logger.warn.bind(options.logger);
|
|
||||||
if (relative && full) {
|
|
||||||
warn("@aws-sdk/credential-provider-http: " +
|
|
||||||
"you have set both awsContainerCredentialsRelativeUri and awsContainerCredentialsFullUri.");
|
|
||||||
warn("awsContainerCredentialsFullUri will take precedence.");
|
|
||||||
}
|
|
||||||
if (token && tokenFile) {
|
|
||||||
warn("@aws-sdk/credential-provider-http: " +
|
|
||||||
"you have set both awsContainerAuthorizationToken and awsContainerAuthorizationTokenFile.");
|
|
||||||
warn("awsContainerAuthorizationToken will take precedence.");
|
|
||||||
}
|
|
||||||
if (full) {
|
|
||||||
host = full;
|
|
||||||
}
|
|
||||||
else if (relative) {
|
|
||||||
host = `${DEFAULT_LINK_LOCAL_HOST}${relative}`;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new property_provider_1.CredentialsProviderError(`No HTTP credential provider host provided.
|
|
||||||
Set AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI.`, { logger: options.logger });
|
|
||||||
}
|
|
||||||
const url = new URL(host);
|
|
||||||
(0, checkUrl_1.checkUrl)(url, options.logger);
|
|
||||||
const requestHandler = node_http_handler_1.NodeHttpHandler.create({
|
|
||||||
requestTimeout: options.timeout ?? 1000,
|
|
||||||
connectionTimeout: options.timeout ?? 1000,
|
|
||||||
});
|
|
||||||
return (0, retry_wrapper_1.retryWrapper)(async () => {
|
|
||||||
const request = (0, requestHelpers_1.createGetRequest)(url);
|
|
||||||
if (token) {
|
|
||||||
request.headers.Authorization = token;
|
|
||||||
}
|
|
||||||
else if (tokenFile) {
|
|
||||||
request.headers.Authorization = (await promises_1.default.readFile(tokenFile)).toString();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const result = await requestHandler.handle(request);
|
|
||||||
return (0, requestHelpers_1.getCredentials)(result.response).then((creds) => (0, client_1.setCredentialFeature)(creds, "CREDENTIALS_HTTP", "z"));
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new property_provider_1.CredentialsProviderError(String(e), { logger: options.logger });
|
|
||||||
}
|
|
||||||
}, options.maxRetries ?? 3, options.timeout ?? 1000);
|
|
||||||
};
|
|
||||||
exports.fromHttp = fromHttp;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 8914:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.createGetRequest = createGetRequest;
|
|
||||||
exports.getCredentials = getCredentials;
|
|
||||||
const property_provider_1 = __webpack_require__(1238);
|
|
||||||
const protocol_http_1 = __webpack_require__(2356);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const util_stream_1 = __webpack_require__(4252);
|
|
||||||
function createGetRequest(url) {
|
|
||||||
return new protocol_http_1.HttpRequest({
|
|
||||||
protocol: url.protocol,
|
|
||||||
hostname: url.hostname,
|
|
||||||
port: Number(url.port),
|
|
||||||
path: url.pathname,
|
|
||||||
query: Array.from(url.searchParams.entries()).reduce((acc, [k, v]) => {
|
|
||||||
acc[k] = v;
|
|
||||||
return acc;
|
|
||||||
}, {}),
|
|
||||||
fragment: url.hash,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async function getCredentials(response, logger) {
|
|
||||||
const stream = (0, util_stream_1.sdkStreamMixin)(response.body);
|
|
||||||
const str = await stream.transformToString();
|
|
||||||
if (response.statusCode === 200) {
|
|
||||||
const parsed = JSON.parse(str);
|
|
||||||
if (typeof parsed.AccessKeyId !== "string" ||
|
|
||||||
typeof parsed.SecretAccessKey !== "string" ||
|
|
||||||
typeof parsed.Token !== "string" ||
|
|
||||||
typeof parsed.Expiration !== "string") {
|
|
||||||
throw new property_provider_1.CredentialsProviderError("HTTP credential provider response not of the required format, an object matching: " +
|
|
||||||
"{ AccessKeyId: string, SecretAccessKey: string, Token: string, Expiration: string(rfc3339) }", { logger });
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
accessKeyId: parsed.AccessKeyId,
|
|
||||||
secretAccessKey: parsed.SecretAccessKey,
|
|
||||||
sessionToken: parsed.Token,
|
|
||||||
expiration: (0, smithy_client_1.parseRfc3339DateTime)(parsed.Expiration),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (response.statusCode >= 400 && response.statusCode < 500) {
|
|
||||||
let parsedBody = {};
|
|
||||||
try {
|
|
||||||
parsedBody = JSON.parse(str);
|
|
||||||
}
|
|
||||||
catch (e) { }
|
|
||||||
throw Object.assign(new property_provider_1.CredentialsProviderError(`Server responded with status: ${response.statusCode}`, { logger }), {
|
|
||||||
Code: parsedBody.Code,
|
|
||||||
Message: parsedBody.Message,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
throw new property_provider_1.CredentialsProviderError(`Server responded with status: ${response.statusCode}`, { logger });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 1122:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.retryWrapper = void 0;
|
|
||||||
const retryWrapper = (toRetry, maxRetries, delayMs) => {
|
|
||||||
return async () => {
|
|
||||||
for (let i = 0; i < maxRetries; ++i) {
|
|
||||||
try {
|
|
||||||
return await toRetry();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return await toRetry();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.retryWrapper = retryWrapper;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 8605:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
var __webpack_unused_export__;
|
|
||||||
|
|
||||||
__webpack_unused_export__ = ({ value: true });
|
|
||||||
exports.fromHttp = void 0;
|
|
||||||
var fromHttp_1 = __webpack_require__(6331);
|
|
||||||
Object.defineProperty(exports, "fromHttp", ({ enumerable: true, get: function () { return fromHttp_1.fromHttp; } }));
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-225
@@ -1,225 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 869;
|
|
||||||
exports.ids = [869];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 5869:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var sharedIniFileLoader = __webpack_require__(4964);
|
|
||||||
var propertyProvider = __webpack_require__(1238);
|
|
||||||
var client = __webpack_require__(5152);
|
|
||||||
|
|
||||||
const resolveCredentialSource = (credentialSource, profileName, logger) => {
|
|
||||||
const sourceProvidersMap = {
|
|
||||||
EcsContainer: async (options) => {
|
|
||||||
const { fromHttp } = await __webpack_require__.e(/* import() */ 605).then(__webpack_require__.bind(__webpack_require__, 8605));
|
|
||||||
const { fromContainerMetadata } = await __webpack_require__.e(/* import() */ 566).then(__webpack_require__.t.bind(__webpack_require__, 566, 19));
|
|
||||||
logger?.debug("@aws-sdk/credential-provider-ini - credential_source is EcsContainer");
|
|
||||||
return async () => propertyProvider.chain(fromHttp(options ?? {}), fromContainerMetadata(options))().then(setNamedProvider);
|
|
||||||
},
|
|
||||||
Ec2InstanceMetadata: async (options) => {
|
|
||||||
logger?.debug("@aws-sdk/credential-provider-ini - credential_source is Ec2InstanceMetadata");
|
|
||||||
const { fromInstanceMetadata } = await __webpack_require__.e(/* import() */ 566).then(__webpack_require__.t.bind(__webpack_require__, 566, 19));
|
|
||||||
return async () => fromInstanceMetadata(options)().then(setNamedProvider);
|
|
||||||
},
|
|
||||||
Environment: async (options) => {
|
|
||||||
logger?.debug("@aws-sdk/credential-provider-ini - credential_source is Environment");
|
|
||||||
const { fromEnv } = await Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 5606, 19));
|
|
||||||
return async () => fromEnv(options)().then(setNamedProvider);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (credentialSource in sourceProvidersMap) {
|
|
||||||
return sourceProvidersMap[credentialSource];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Unsupported credential source in profile ${profileName}. Got ${credentialSource}, ` +
|
|
||||||
`expected EcsContainer or Ec2InstanceMetadata or Environment.`, { logger });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const setNamedProvider = (creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_NAMED_PROVIDER", "p");
|
|
||||||
|
|
||||||
const isAssumeRoleProfile = (arg, { profile = "default", logger } = {}) => {
|
|
||||||
return (Boolean(arg) &&
|
|
||||||
typeof arg === "object" &&
|
|
||||||
typeof arg.role_arn === "string" &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.role_session_name) > -1 &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.external_id) > -1 &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.mfa_serial) > -1 &&
|
|
||||||
(isAssumeRoleWithSourceProfile(arg, { profile, logger }) || isCredentialSourceProfile(arg, { profile, logger })));
|
|
||||||
};
|
|
||||||
const isAssumeRoleWithSourceProfile = (arg, { profile, logger }) => {
|
|
||||||
const withSourceProfile = typeof arg.source_profile === "string" && typeof arg.credential_source === "undefined";
|
|
||||||
if (withSourceProfile) {
|
|
||||||
logger?.debug?.(` ${profile} isAssumeRoleWithSourceProfile source_profile=${arg.source_profile}`);
|
|
||||||
}
|
|
||||||
return withSourceProfile;
|
|
||||||
};
|
|
||||||
const isCredentialSourceProfile = (arg, { profile, logger }) => {
|
|
||||||
const withProviderProfile = typeof arg.credential_source === "string" && typeof arg.source_profile === "undefined";
|
|
||||||
if (withProviderProfile) {
|
|
||||||
logger?.debug?.(` ${profile} isCredentialSourceProfile credential_source=${arg.credential_source}`);
|
|
||||||
}
|
|
||||||
return withProviderProfile;
|
|
||||||
};
|
|
||||||
const resolveAssumeRoleCredentials = async (profileName, profiles, options, visitedProfiles = {}, resolveProfileData) => {
|
|
||||||
options.logger?.debug("@aws-sdk/credential-provider-ini - resolveAssumeRoleCredentials (STS)");
|
|
||||||
const profileData = profiles[profileName];
|
|
||||||
const { source_profile, region } = profileData;
|
|
||||||
if (!options.roleAssumer) {
|
|
||||||
const { getDefaultRoleAssumer } = await __webpack_require__.e(/* import() */ 136).then(__webpack_require__.t.bind(__webpack_require__, 1136, 23));
|
|
||||||
options.roleAssumer = getDefaultRoleAssumer({
|
|
||||||
...options.clientConfig,
|
|
||||||
credentialProviderLogger: options.logger,
|
|
||||||
parentClientConfig: {
|
|
||||||
...options?.parentClientConfig,
|
|
||||||
region: region ?? options?.parentClientConfig?.region,
|
|
||||||
},
|
|
||||||
}, options.clientPlugins);
|
|
||||||
}
|
|
||||||
if (source_profile && source_profile in visitedProfiles) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Detected a cycle attempting to resolve credentials for profile` +
|
|
||||||
` ${sharedIniFileLoader.getProfileName(options)}. Profiles visited: ` +
|
|
||||||
Object.keys(visitedProfiles).join(", "), { logger: options.logger });
|
|
||||||
}
|
|
||||||
options.logger?.debug(`@aws-sdk/credential-provider-ini - finding credential resolver using ${source_profile ? `source_profile=[${source_profile}]` : `profile=[${profileName}]`}`);
|
|
||||||
const sourceCredsProvider = source_profile
|
|
||||||
? resolveProfileData(source_profile, profiles, options, {
|
|
||||||
...visitedProfiles,
|
|
||||||
[source_profile]: true,
|
|
||||||
}, isCredentialSourceWithoutRoleArn(profiles[source_profile] ?? {}))
|
|
||||||
: (await resolveCredentialSource(profileData.credential_source, profileName, options.logger)(options))();
|
|
||||||
if (isCredentialSourceWithoutRoleArn(profileData)) {
|
|
||||||
return sourceCredsProvider.then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const params = {
|
|
||||||
RoleArn: profileData.role_arn,
|
|
||||||
RoleSessionName: profileData.role_session_name || `aws-sdk-js-${Date.now()}`,
|
|
||||||
ExternalId: profileData.external_id,
|
|
||||||
DurationSeconds: parseInt(profileData.duration_seconds || "3600", 10),
|
|
||||||
};
|
|
||||||
const { mfa_serial } = profileData;
|
|
||||||
if (mfa_serial) {
|
|
||||||
if (!options.mfaCodeProvider) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Profile ${profileName} requires multi-factor authentication, but no MFA code callback was provided.`, { logger: options.logger, tryNextLink: false });
|
|
||||||
}
|
|
||||||
params.SerialNumber = mfa_serial;
|
|
||||||
params.TokenCode = await options.mfaCodeProvider(mfa_serial);
|
|
||||||
}
|
|
||||||
const sourceCreds = await sourceCredsProvider;
|
|
||||||
return options.roleAssumer(sourceCreds, params).then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const isCredentialSourceWithoutRoleArn = (section) => {
|
|
||||||
return !section.role_arn && !!section.credential_source;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isProcessProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.credential_process === "string";
|
|
||||||
const resolveProcessCredentials = async (options, profile) => __webpack_require__.e(/* import() */ 360).then(__webpack_require__.t.bind(__webpack_require__, 5360, 19)).then(({ fromProcess }) => fromProcess({
|
|
||||||
...options,
|
|
||||||
profile,
|
|
||||||
})().then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_PROCESS", "v")));
|
|
||||||
|
|
||||||
const resolveSsoCredentials = async (profile, profileData, options = {}) => {
|
|
||||||
const { fromSSO } = await __webpack_require__.e(/* import() */ 998).then(__webpack_require__.t.bind(__webpack_require__, 998, 19));
|
|
||||||
return fromSSO({
|
|
||||||
profile,
|
|
||||||
logger: options.logger,
|
|
||||||
parentClientConfig: options.parentClientConfig,
|
|
||||||
clientConfig: options.clientConfig,
|
|
||||||
})().then((creds) => {
|
|
||||||
if (profileData.sso_session) {
|
|
||||||
return client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO", "r");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO_LEGACY", "t");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const isSsoProfile = (arg) => arg &&
|
|
||||||
(typeof arg.sso_start_url === "string" ||
|
|
||||||
typeof arg.sso_account_id === "string" ||
|
|
||||||
typeof arg.sso_session === "string" ||
|
|
||||||
typeof arg.sso_region === "string" ||
|
|
||||||
typeof arg.sso_role_name === "string");
|
|
||||||
|
|
||||||
const isStaticCredsProfile = (arg) => Boolean(arg) &&
|
|
||||||
typeof arg === "object" &&
|
|
||||||
typeof arg.aws_access_key_id === "string" &&
|
|
||||||
typeof arg.aws_secret_access_key === "string" &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.aws_session_token) > -1 &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.aws_account_id) > -1;
|
|
||||||
const resolveStaticCredentials = async (profile, options) => {
|
|
||||||
options?.logger?.debug("@aws-sdk/credential-provider-ini - resolveStaticCredentials");
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId: profile.aws_access_key_id,
|
|
||||||
secretAccessKey: profile.aws_secret_access_key,
|
|
||||||
sessionToken: profile.aws_session_token,
|
|
||||||
...(profile.aws_credential_scope && { credentialScope: profile.aws_credential_scope }),
|
|
||||||
...(profile.aws_account_id && { accountId: profile.aws_account_id }),
|
|
||||||
};
|
|
||||||
return client.setCredentialFeature(credentials, "CREDENTIALS_PROFILE", "n");
|
|
||||||
};
|
|
||||||
|
|
||||||
const isWebIdentityProfile = (arg) => Boolean(arg) &&
|
|
||||||
typeof arg === "object" &&
|
|
||||||
typeof arg.web_identity_token_file === "string" &&
|
|
||||||
typeof arg.role_arn === "string" &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.role_session_name) > -1;
|
|
||||||
const resolveWebIdentityCredentials = async (profile, options) => __webpack_require__.e(/* import() */ 956).then(__webpack_require__.t.bind(__webpack_require__, 9956, 23)).then(({ fromTokenFile }) => fromTokenFile({
|
|
||||||
webIdentityTokenFile: profile.web_identity_token_file,
|
|
||||||
roleArn: profile.role_arn,
|
|
||||||
roleSessionName: profile.role_session_name,
|
|
||||||
roleAssumerWithWebIdentity: options.roleAssumerWithWebIdentity,
|
|
||||||
logger: options.logger,
|
|
||||||
parentClientConfig: options.parentClientConfig,
|
|
||||||
})().then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN", "q")));
|
|
||||||
|
|
||||||
const resolveProfileData = async (profileName, profiles, options, visitedProfiles = {}, isAssumeRoleRecursiveCall = false) => {
|
|
||||||
const data = profiles[profileName];
|
|
||||||
if (Object.keys(visitedProfiles).length > 0 && isStaticCredsProfile(data)) {
|
|
||||||
return resolveStaticCredentials(data, options);
|
|
||||||
}
|
|
||||||
if (isAssumeRoleRecursiveCall || isAssumeRoleProfile(data, { profile: profileName, logger: options.logger })) {
|
|
||||||
return resolveAssumeRoleCredentials(profileName, profiles, options, visitedProfiles, resolveProfileData);
|
|
||||||
}
|
|
||||||
if (isStaticCredsProfile(data)) {
|
|
||||||
return resolveStaticCredentials(data, options);
|
|
||||||
}
|
|
||||||
if (isWebIdentityProfile(data)) {
|
|
||||||
return resolveWebIdentityCredentials(data, options);
|
|
||||||
}
|
|
||||||
if (isProcessProfile(data)) {
|
|
||||||
return resolveProcessCredentials(options, profileName);
|
|
||||||
}
|
|
||||||
if (isSsoProfile(data)) {
|
|
||||||
return await resolveSsoCredentials(profileName, data, options);
|
|
||||||
}
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Could not resolve credentials using profile: [${profileName}] in configuration/credentials file(s).`, { logger: options.logger });
|
|
||||||
};
|
|
||||||
|
|
||||||
const fromIni = (_init = {}) => async ({ callerClientConfig } = {}) => {
|
|
||||||
const init = {
|
|
||||||
..._init,
|
|
||||||
parentClientConfig: {
|
|
||||||
...callerClientConfig,
|
|
||||||
..._init.parentClientConfig,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
init.logger?.debug("@aws-sdk/credential-provider-ini - fromIni");
|
|
||||||
const profiles = await sharedIniFileLoader.parseKnownFiles(init);
|
|
||||||
return resolveProfileData(sharedIniFileLoader.getProfileName({
|
|
||||||
profile: _init.profile ?? callerClientConfig?.profile,
|
|
||||||
}), profiles, init);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.fromIni = fromIni;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-1039
File diff suppressed because it is too large
Load Diff
-1455
File diff suppressed because it is too large
Load Diff
-56
@@ -1,56 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 121;
|
|
||||||
exports.ids = [121];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 7121:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
var __webpack_unused_export__;
|
|
||||||
|
|
||||||
|
|
||||||
var client = __webpack_require__(5152);
|
|
||||||
var propertyProvider = __webpack_require__(1238);
|
|
||||||
|
|
||||||
const ENV_KEY = "AWS_ACCESS_KEY_ID";
|
|
||||||
const ENV_SECRET = "AWS_SECRET_ACCESS_KEY";
|
|
||||||
const ENV_SESSION = "AWS_SESSION_TOKEN";
|
|
||||||
const ENV_EXPIRATION = "AWS_CREDENTIAL_EXPIRATION";
|
|
||||||
const ENV_CREDENTIAL_SCOPE = "AWS_CREDENTIAL_SCOPE";
|
|
||||||
const ENV_ACCOUNT_ID = "AWS_ACCOUNT_ID";
|
|
||||||
const fromEnv = (init) => async () => {
|
|
||||||
init?.logger?.debug("@aws-sdk/credential-provider-env - fromEnv");
|
|
||||||
const accessKeyId = process.env[ENV_KEY];
|
|
||||||
const secretAccessKey = process.env[ENV_SECRET];
|
|
||||||
const sessionToken = process.env[ENV_SESSION];
|
|
||||||
const expiry = process.env[ENV_EXPIRATION];
|
|
||||||
const credentialScope = process.env[ENV_CREDENTIAL_SCOPE];
|
|
||||||
const accountId = process.env[ENV_ACCOUNT_ID];
|
|
||||||
if (accessKeyId && secretAccessKey) {
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId,
|
|
||||||
secretAccessKey,
|
|
||||||
...(sessionToken && { sessionToken }),
|
|
||||||
...(expiry && { expiration: new Date(expiry) }),
|
|
||||||
...(credentialScope && { credentialScope }),
|
|
||||||
...(accountId && { accountId }),
|
|
||||||
};
|
|
||||||
client.setCredentialFeature(credentials, "CREDENTIALS_ENV_VARS", "g");
|
|
||||||
return credentials;
|
|
||||||
}
|
|
||||||
throw new propertyProvider.CredentialsProviderError("Unable to find environment variable credentials.", { logger: init?.logger });
|
|
||||||
};
|
|
||||||
|
|
||||||
__webpack_unused_export__ = ENV_ACCOUNT_ID;
|
|
||||||
__webpack_unused_export__ = ENV_CREDENTIAL_SCOPE;
|
|
||||||
__webpack_unused_export__ = ENV_EXPIRATION;
|
|
||||||
__webpack_unused_export__ = ENV_KEY;
|
|
||||||
__webpack_unused_export__ = ENV_SECRET;
|
|
||||||
__webpack_unused_export__ = ENV_SESSION;
|
|
||||||
exports.fromEnv = fromEnv;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-903
@@ -1,903 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 136;
|
|
||||||
exports.ids = [136];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 3723:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.STSClient = exports.__Client = void 0;
|
|
||||||
const middleware_host_header_1 = __webpack_require__(2590);
|
|
||||||
const middleware_logger_1 = __webpack_require__(5242);
|
|
||||||
const middleware_recursion_detection_1 = __webpack_require__(1568);
|
|
||||||
const middleware_user_agent_1 = __webpack_require__(2959);
|
|
||||||
const config_resolver_1 = __webpack_require__(9316);
|
|
||||||
const core_1 = __webpack_require__(402);
|
|
||||||
const schema_1 = __webpack_require__(6890);
|
|
||||||
const middleware_content_length_1 = __webpack_require__(7212);
|
|
||||||
const middleware_endpoint_1 = __webpack_require__(99);
|
|
||||||
const middleware_retry_1 = __webpack_require__(9618);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
Object.defineProperty(exports, "__Client", ({ enumerable: true, get: function () { return smithy_client_1.Client; } }));
|
|
||||||
const httpAuthSchemeProvider_1 = __webpack_require__(7851);
|
|
||||||
const EndpointParameters_1 = __webpack_require__(6811);
|
|
||||||
const runtimeConfig_1 = __webpack_require__(6578);
|
|
||||||
const runtimeExtensions_1 = __webpack_require__(7742);
|
|
||||||
class STSClient extends smithy_client_1.Client {
|
|
||||||
config;
|
|
||||||
constructor(...[configuration]) {
|
|
||||||
const _config_0 = (0, runtimeConfig_1.getRuntimeConfig)(configuration || {});
|
|
||||||
super(_config_0);
|
|
||||||
this.initConfig = _config_0;
|
|
||||||
const _config_1 = (0, EndpointParameters_1.resolveClientEndpointParameters)(_config_0);
|
|
||||||
const _config_2 = (0, middleware_user_agent_1.resolveUserAgentConfig)(_config_1);
|
|
||||||
const _config_3 = (0, middleware_retry_1.resolveRetryConfig)(_config_2);
|
|
||||||
const _config_4 = (0, config_resolver_1.resolveRegionConfig)(_config_3);
|
|
||||||
const _config_5 = (0, middleware_host_header_1.resolveHostHeaderConfig)(_config_4);
|
|
||||||
const _config_6 = (0, middleware_endpoint_1.resolveEndpointConfig)(_config_5);
|
|
||||||
const _config_7 = (0, httpAuthSchemeProvider_1.resolveHttpAuthSchemeConfig)(_config_6);
|
|
||||||
const _config_8 = (0, runtimeExtensions_1.resolveRuntimeExtensions)(_config_7, configuration?.extensions || []);
|
|
||||||
this.config = _config_8;
|
|
||||||
this.middlewareStack.use((0, schema_1.getSchemaSerdePlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_user_agent_1.getUserAgentPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_retry_1.getRetryPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_content_length_1.getContentLengthPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_host_header_1.getHostHeaderPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_logger_1.getLoggerPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, middleware_recursion_detection_1.getRecursionDetectionPlugin)(this.config));
|
|
||||||
this.middlewareStack.use((0, core_1.getHttpAuthSchemeEndpointRuleSetPlugin)(this.config, {
|
|
||||||
httpAuthSchemeParametersProvider: httpAuthSchemeProvider_1.defaultSTSHttpAuthSchemeParametersProvider,
|
|
||||||
identityProviderConfigProvider: async (config) => new core_1.DefaultIdentityProviderConfig({
|
|
||||||
"aws.auth#sigv4": config.credentials,
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
this.middlewareStack.use((0, core_1.getHttpSigningPlugin)(this.config));
|
|
||||||
}
|
|
||||||
destroy() {
|
|
||||||
super.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.STSClient = STSClient;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 4532:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.resolveHttpAuthRuntimeConfig = exports.getHttpAuthExtensionConfiguration = void 0;
|
|
||||||
const getHttpAuthExtensionConfiguration = (runtimeConfig) => {
|
|
||||||
const _httpAuthSchemes = runtimeConfig.httpAuthSchemes;
|
|
||||||
let _httpAuthSchemeProvider = runtimeConfig.httpAuthSchemeProvider;
|
|
||||||
let _credentials = runtimeConfig.credentials;
|
|
||||||
return {
|
|
||||||
setHttpAuthScheme(httpAuthScheme) {
|
|
||||||
const index = _httpAuthSchemes.findIndex((scheme) => scheme.schemeId === httpAuthScheme.schemeId);
|
|
||||||
if (index === -1) {
|
|
||||||
_httpAuthSchemes.push(httpAuthScheme);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_httpAuthSchemes.splice(index, 1, httpAuthScheme);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
httpAuthSchemes() {
|
|
||||||
return _httpAuthSchemes;
|
|
||||||
},
|
|
||||||
setHttpAuthSchemeProvider(httpAuthSchemeProvider) {
|
|
||||||
_httpAuthSchemeProvider = httpAuthSchemeProvider;
|
|
||||||
},
|
|
||||||
httpAuthSchemeProvider() {
|
|
||||||
return _httpAuthSchemeProvider;
|
|
||||||
},
|
|
||||||
setCredentials(credentials) {
|
|
||||||
_credentials = credentials;
|
|
||||||
},
|
|
||||||
credentials() {
|
|
||||||
return _credentials;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getHttpAuthExtensionConfiguration = getHttpAuthExtensionConfiguration;
|
|
||||||
const resolveHttpAuthRuntimeConfig = (config) => {
|
|
||||||
return {
|
|
||||||
httpAuthSchemes: config.httpAuthSchemes(),
|
|
||||||
httpAuthSchemeProvider: config.httpAuthSchemeProvider(),
|
|
||||||
credentials: config.credentials(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.resolveHttpAuthRuntimeConfig = resolveHttpAuthRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 7851:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.resolveHttpAuthSchemeConfig = exports.resolveStsAuthConfig = exports.defaultSTSHttpAuthSchemeProvider = exports.defaultSTSHttpAuthSchemeParametersProvider = void 0;
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const util_middleware_1 = __webpack_require__(6324);
|
|
||||||
const STSClient_1 = __webpack_require__(3723);
|
|
||||||
const defaultSTSHttpAuthSchemeParametersProvider = async (config, context, input) => {
|
|
||||||
return {
|
|
||||||
operation: (0, util_middleware_1.getSmithyContext)(context).operation,
|
|
||||||
region: (await (0, util_middleware_1.normalizeProvider)(config.region)()) ||
|
|
||||||
(() => {
|
|
||||||
throw new Error("expected `region` to be configured for `aws.auth#sigv4`");
|
|
||||||
})(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.defaultSTSHttpAuthSchemeParametersProvider = defaultSTSHttpAuthSchemeParametersProvider;
|
|
||||||
function createAwsAuthSigv4HttpAuthOption(authParameters) {
|
|
||||||
return {
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
signingProperties: {
|
|
||||||
name: "sts",
|
|
||||||
region: authParameters.region,
|
|
||||||
},
|
|
||||||
propertiesExtractor: (config, context) => ({
|
|
||||||
signingProperties: {
|
|
||||||
config,
|
|
||||||
context,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function createSmithyApiNoAuthHttpAuthOption(authParameters) {
|
|
||||||
return {
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const defaultSTSHttpAuthSchemeProvider = (authParameters) => {
|
|
||||||
const options = [];
|
|
||||||
switch (authParameters.operation) {
|
|
||||||
case "AssumeRoleWithWebIdentity": {
|
|
||||||
options.push(createSmithyApiNoAuthHttpAuthOption(authParameters));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
options.push(createAwsAuthSigv4HttpAuthOption(authParameters));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
exports.defaultSTSHttpAuthSchemeProvider = defaultSTSHttpAuthSchemeProvider;
|
|
||||||
const resolveStsAuthConfig = (input) => Object.assign(input, {
|
|
||||||
stsClientCtor: STSClient_1.STSClient,
|
|
||||||
});
|
|
||||||
exports.resolveStsAuthConfig = resolveStsAuthConfig;
|
|
||||||
const resolveHttpAuthSchemeConfig = (config) => {
|
|
||||||
const config_0 = (0, exports.resolveStsAuthConfig)(config);
|
|
||||||
const config_1 = (0, core_1.resolveAwsSdkSigV4Config)(config_0);
|
|
||||||
return Object.assign(config_1, {
|
|
||||||
authSchemePreference: (0, util_middleware_1.normalizeProvider)(config.authSchemePreference ?? []),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
exports.resolveHttpAuthSchemeConfig = resolveHttpAuthSchemeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 6811:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.commonParams = exports.resolveClientEndpointParameters = void 0;
|
|
||||||
const resolveClientEndpointParameters = (options) => {
|
|
||||||
return Object.assign(options, {
|
|
||||||
useDualstackEndpoint: options.useDualstackEndpoint ?? false,
|
|
||||||
useFipsEndpoint: options.useFipsEndpoint ?? false,
|
|
||||||
useGlobalEndpoint: options.useGlobalEndpoint ?? false,
|
|
||||||
defaultSigningName: "sts",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
exports.resolveClientEndpointParameters = resolveClientEndpointParameters;
|
|
||||||
exports.commonParams = {
|
|
||||||
UseGlobalEndpoint: { type: "builtInParams", name: "useGlobalEndpoint" },
|
|
||||||
UseFIPS: { type: "builtInParams", name: "useFipsEndpoint" },
|
|
||||||
Endpoint: { type: "builtInParams", name: "endpoint" },
|
|
||||||
Region: { type: "builtInParams", name: "region" },
|
|
||||||
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9765:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.defaultEndpointResolver = void 0;
|
|
||||||
const util_endpoints_1 = __webpack_require__(3068);
|
|
||||||
const util_endpoints_2 = __webpack_require__(9674);
|
|
||||||
const ruleset_1 = __webpack_require__(1670);
|
|
||||||
const cache = new util_endpoints_2.EndpointCache({
|
|
||||||
size: 50,
|
|
||||||
params: ["Endpoint", "Region", "UseDualStack", "UseFIPS", "UseGlobalEndpoint"],
|
|
||||||
});
|
|
||||||
const defaultEndpointResolver = (endpointParams, context = {}) => {
|
|
||||||
return cache.get(endpointParams, () => (0, util_endpoints_2.resolveEndpoint)(ruleset_1.ruleSet, {
|
|
||||||
endpointParams: endpointParams,
|
|
||||||
logger: context.logger,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
exports.defaultEndpointResolver = defaultEndpointResolver;
|
|
||||||
util_endpoints_2.customEndpointFunctions.aws = util_endpoints_1.awsEndpointFunctions;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 1670:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.ruleSet = void 0;
|
|
||||||
const F = "required", G = "type", H = "fn", I = "argv", J = "ref";
|
|
||||||
const a = false, b = true, c = "booleanEquals", d = "stringEquals", e = "sigv4", f = "sts", g = "us-east-1", h = "endpoint", i = "https://sts.{Region}.{PartitionResult#dnsSuffix}", j = "tree", k = "error", l = "getAttr", m = { [F]: false, [G]: "string" }, n = { [F]: true, "default": false, [G]: "boolean" }, o = { [J]: "Endpoint" }, p = { [H]: "isSet", [I]: [{ [J]: "Region" }] }, q = { [J]: "Region" }, r = { [H]: "aws.partition", [I]: [q], "assign": "PartitionResult" }, s = { [J]: "UseFIPS" }, t = { [J]: "UseDualStack" }, u = { "url": "https://sts.amazonaws.com", "properties": { "authSchemes": [{ "name": e, "signingName": f, "signingRegion": g }] }, "headers": {} }, v = {}, w = { "conditions": [{ [H]: d, [I]: [q, "aws-global"] }], [h]: u, [G]: h }, x = { [H]: c, [I]: [s, true] }, y = { [H]: c, [I]: [t, true] }, z = { [H]: l, [I]: [{ [J]: "PartitionResult" }, "supportsFIPS"] }, A = { [J]: "PartitionResult" }, B = { [H]: c, [I]: [true, { [H]: l, [I]: [A, "supportsDualStack"] }] }, C = [{ [H]: "isSet", [I]: [o] }], D = [x], E = [y];
|
|
||||||
const _data = { version: "1.0", parameters: { Region: m, UseDualStack: n, UseFIPS: n, Endpoint: m, UseGlobalEndpoint: n }, rules: [{ conditions: [{ [H]: c, [I]: [{ [J]: "UseGlobalEndpoint" }, b] }, { [H]: "not", [I]: C }, p, r, { [H]: c, [I]: [s, a] }, { [H]: c, [I]: [t, a] }], rules: [{ conditions: [{ [H]: d, [I]: [q, "ap-northeast-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "ap-south-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "ap-southeast-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "ap-southeast-2"] }], endpoint: u, [G]: h }, w, { conditions: [{ [H]: d, [I]: [q, "ca-central-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-central-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-north-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-west-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-west-2"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "eu-west-3"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "sa-east-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, g] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "us-east-2"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "us-west-1"] }], endpoint: u, [G]: h }, { conditions: [{ [H]: d, [I]: [q, "us-west-2"] }], endpoint: u, [G]: h }, { endpoint: { url: i, properties: { authSchemes: [{ name: e, signingName: f, signingRegion: "{Region}" }] }, headers: v }, [G]: h }], [G]: j }, { conditions: C, rules: [{ conditions: D, error: "Invalid Configuration: FIPS and custom endpoint are not supported", [G]: k }, { conditions: E, error: "Invalid Configuration: Dualstack and custom endpoint are not supported", [G]: k }, { endpoint: { url: o, properties: v, headers: v }, [G]: h }], [G]: j }, { conditions: [p], rules: [{ conditions: [r], rules: [{ conditions: [x, y], rules: [{ conditions: [{ [H]: c, [I]: [b, z] }, B], rules: [{ endpoint: { url: "https://sts-fips.{Region}.{PartitionResult#dualStackDnsSuffix}", properties: v, headers: v }, [G]: h }], [G]: j }, { error: "FIPS and DualStack are enabled, but this partition does not support one or both", [G]: k }], [G]: j }, { conditions: D, rules: [{ conditions: [{ [H]: c, [I]: [z, b] }], rules: [{ conditions: [{ [H]: d, [I]: [{ [H]: l, [I]: [A, "name"] }, "aws-us-gov"] }], endpoint: { url: "https://sts.{Region}.amazonaws.com", properties: v, headers: v }, [G]: h }, { endpoint: { url: "https://sts-fips.{Region}.{PartitionResult#dnsSuffix}", properties: v, headers: v }, [G]: h }], [G]: j }, { error: "FIPS is enabled but this partition does not support FIPS", [G]: k }], [G]: j }, { conditions: E, rules: [{ conditions: [B], rules: [{ endpoint: { url: "https://sts.{Region}.{PartitionResult#dualStackDnsSuffix}", properties: v, headers: v }, [G]: h }], [G]: j }, { error: "DualStack is enabled but this partition does not support DualStack", [G]: k }], [G]: j }, w, { endpoint: { url: i, properties: v, headers: v }, [G]: h }], [G]: j }], [G]: j }, { error: "Invalid Configuration: Missing Region", [G]: k }] };
|
|
||||||
exports.ruleSet = _data;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 1136:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var STSClient = __webpack_require__(3723);
|
|
||||||
var smithyClient = __webpack_require__(1411);
|
|
||||||
var middlewareEndpoint = __webpack_require__(99);
|
|
||||||
var EndpointParameters = __webpack_require__(6811);
|
|
||||||
var schema = __webpack_require__(6890);
|
|
||||||
var client = __webpack_require__(5152);
|
|
||||||
var regionConfigResolver = __webpack_require__(6463);
|
|
||||||
|
|
||||||
let STSServiceException$1 = class STSServiceException extends smithyClient.ServiceException {
|
|
||||||
constructor(options) {
|
|
||||||
super(options);
|
|
||||||
Object.setPrototypeOf(this, STSServiceException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let ExpiredTokenException$1 = class ExpiredTokenException extends STSServiceException$1 {
|
|
||||||
name = "ExpiredTokenException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "ExpiredTokenException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, ExpiredTokenException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let MalformedPolicyDocumentException$1 = class MalformedPolicyDocumentException extends STSServiceException$1 {
|
|
||||||
name = "MalformedPolicyDocumentException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "MalformedPolicyDocumentException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, MalformedPolicyDocumentException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let PackedPolicyTooLargeException$1 = class PackedPolicyTooLargeException extends STSServiceException$1 {
|
|
||||||
name = "PackedPolicyTooLargeException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "PackedPolicyTooLargeException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, PackedPolicyTooLargeException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let RegionDisabledException$1 = class RegionDisabledException extends STSServiceException$1 {
|
|
||||||
name = "RegionDisabledException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "RegionDisabledException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, RegionDisabledException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let IDPRejectedClaimException$1 = class IDPRejectedClaimException extends STSServiceException$1 {
|
|
||||||
name = "IDPRejectedClaimException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "IDPRejectedClaimException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, IDPRejectedClaimException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InvalidIdentityTokenException$1 = class InvalidIdentityTokenException extends STSServiceException$1 {
|
|
||||||
name = "InvalidIdentityTokenException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidIdentityTokenException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidIdentityTokenException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let IDPCommunicationErrorException$1 = class IDPCommunicationErrorException extends STSServiceException$1 {
|
|
||||||
name = "IDPCommunicationErrorException";
|
|
||||||
$fault = "client";
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "IDPCommunicationErrorException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, IDPCommunicationErrorException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const _A = "Arn";
|
|
||||||
const _AKI = "AccessKeyId";
|
|
||||||
const _AR = "AssumeRole";
|
|
||||||
const _ARI = "AssumedRoleId";
|
|
||||||
const _ARR = "AssumeRoleRequest";
|
|
||||||
const _ARRs = "AssumeRoleResponse";
|
|
||||||
const _ARU = "AssumedRoleUser";
|
|
||||||
const _ARWWI = "AssumeRoleWithWebIdentity";
|
|
||||||
const _ARWWIR = "AssumeRoleWithWebIdentityRequest";
|
|
||||||
const _ARWWIRs = "AssumeRoleWithWebIdentityResponse";
|
|
||||||
const _Au = "Audience";
|
|
||||||
const _C = "Credentials";
|
|
||||||
const _CA = "ContextAssertion";
|
|
||||||
const _DS = "DurationSeconds";
|
|
||||||
const _E = "Expiration";
|
|
||||||
const _EI = "ExternalId";
|
|
||||||
const _ETE = "ExpiredTokenException";
|
|
||||||
const _IDPCEE = "IDPCommunicationErrorException";
|
|
||||||
const _IDPRCE = "IDPRejectedClaimException";
|
|
||||||
const _IITE = "InvalidIdentityTokenException";
|
|
||||||
const _K = "Key";
|
|
||||||
const _MPDE = "MalformedPolicyDocumentException";
|
|
||||||
const _P = "Policy";
|
|
||||||
const _PA = "PolicyArns";
|
|
||||||
const _PAr = "ProviderArn";
|
|
||||||
const _PC = "ProvidedContexts";
|
|
||||||
const _PCLT = "ProvidedContextsListType";
|
|
||||||
const _PCr = "ProvidedContext";
|
|
||||||
const _PDT = "PolicyDescriptorType";
|
|
||||||
const _PI = "ProviderId";
|
|
||||||
const _PPS = "PackedPolicySize";
|
|
||||||
const _PPTLE = "PackedPolicyTooLargeException";
|
|
||||||
const _Pr = "Provider";
|
|
||||||
const _RA = "RoleArn";
|
|
||||||
const _RDE = "RegionDisabledException";
|
|
||||||
const _RSN = "RoleSessionName";
|
|
||||||
const _SAK = "SecretAccessKey";
|
|
||||||
const _SFWIT = "SubjectFromWebIdentityToken";
|
|
||||||
const _SI = "SourceIdentity";
|
|
||||||
const _SN = "SerialNumber";
|
|
||||||
const _ST = "SessionToken";
|
|
||||||
const _T = "Tags";
|
|
||||||
const _TC = "TokenCode";
|
|
||||||
const _TTK = "TransitiveTagKeys";
|
|
||||||
const _Ta = "Tag";
|
|
||||||
const _V = "Value";
|
|
||||||
const _WIT = "WebIdentityToken";
|
|
||||||
const _a = "arn";
|
|
||||||
const _aKST = "accessKeySecretType";
|
|
||||||
const _aQE = "awsQueryError";
|
|
||||||
const _c = "client";
|
|
||||||
const _cTT = "clientTokenType";
|
|
||||||
const _e = "error";
|
|
||||||
const _hE = "httpError";
|
|
||||||
const _m = "message";
|
|
||||||
const _pDLT = "policyDescriptorListType";
|
|
||||||
const _s = "smithy.ts.sdk.synthetic.com.amazonaws.sts";
|
|
||||||
const _tLT = "tagListType";
|
|
||||||
const n0 = "com.amazonaws.sts";
|
|
||||||
var accessKeySecretType = [0, n0, _aKST, 8, 0];
|
|
||||||
var clientTokenType = [0, n0, _cTT, 8, 0];
|
|
||||||
var AssumedRoleUser = [3, n0, _ARU, 0, [_ARI, _A], [0, 0]];
|
|
||||||
var AssumeRoleRequest = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_ARR,
|
|
||||||
0,
|
|
||||||
[_RA, _RSN, _PA, _P, _DS, _T, _TTK, _EI, _SN, _TC, _SI, _PC],
|
|
||||||
[0, 0, () => policyDescriptorListType, 0, 1, () => tagListType, 64 | 0, 0, 0, 0, 0, () => ProvidedContextsListType],
|
|
||||||
];
|
|
||||||
var AssumeRoleResponse = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_ARRs,
|
|
||||||
0,
|
|
||||||
[_C, _ARU, _PPS, _SI],
|
|
||||||
[[() => Credentials, 0], () => AssumedRoleUser, 1, 0],
|
|
||||||
];
|
|
||||||
var AssumeRoleWithWebIdentityRequest = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_ARWWIR,
|
|
||||||
0,
|
|
||||||
[_RA, _RSN, _WIT, _PI, _PA, _P, _DS],
|
|
||||||
[0, 0, [() => clientTokenType, 0], 0, () => policyDescriptorListType, 0, 1],
|
|
||||||
];
|
|
||||||
var AssumeRoleWithWebIdentityResponse = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_ARWWIRs,
|
|
||||||
0,
|
|
||||||
[_C, _SFWIT, _ARU, _PPS, _Pr, _Au, _SI],
|
|
||||||
[[() => Credentials, 0], 0, () => AssumedRoleUser, 1, 0, 0, 0],
|
|
||||||
];
|
|
||||||
var Credentials = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_C,
|
|
||||||
0,
|
|
||||||
[_AKI, _SAK, _ST, _E],
|
|
||||||
[0, [() => accessKeySecretType, 0], 0, 4],
|
|
||||||
];
|
|
||||||
var ExpiredTokenException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ETE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`ExpiredTokenException`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(ExpiredTokenException, ExpiredTokenException$1);
|
|
||||||
var IDPCommunicationErrorException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IDPCEE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`IDPCommunicationError`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(IDPCommunicationErrorException, IDPCommunicationErrorException$1);
|
|
||||||
var IDPRejectedClaimException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IDPRCE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 403,
|
|
||||||
[_aQE]: [`IDPRejectedClaim`, 403],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(IDPRejectedClaimException, IDPRejectedClaimException$1);
|
|
||||||
var InvalidIdentityTokenException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IITE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`InvalidIdentityToken`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidIdentityTokenException, InvalidIdentityTokenException$1);
|
|
||||||
var MalformedPolicyDocumentException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_MPDE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`MalformedPolicyDocument`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(MalformedPolicyDocumentException, MalformedPolicyDocumentException$1);
|
|
||||||
var PackedPolicyTooLargeException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_PPTLE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
[_aQE]: [`PackedPolicyTooLarge`, 400],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(PackedPolicyTooLargeException, PackedPolicyTooLargeException$1);
|
|
||||||
var PolicyDescriptorType = [3, n0, _PDT, 0, [_a], [0]];
|
|
||||||
var ProvidedContext = [3, n0, _PCr, 0, [_PAr, _CA], [0, 0]];
|
|
||||||
var RegionDisabledException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_RDE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 403,
|
|
||||||
[_aQE]: [`RegionDisabledException`, 403],
|
|
||||||
},
|
|
||||||
[_m],
|
|
||||||
[0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(RegionDisabledException, RegionDisabledException$1);
|
|
||||||
var Tag = [3, n0, _Ta, 0, [_K, _V], [0, 0]];
|
|
||||||
var STSServiceException = [-3, _s, "STSServiceException", 0, [], []];
|
|
||||||
schema.TypeRegistry.for(_s).registerError(STSServiceException, STSServiceException$1);
|
|
||||||
var policyDescriptorListType = [1, n0, _pDLT, 0, () => PolicyDescriptorType];
|
|
||||||
var ProvidedContextsListType = [1, n0, _PCLT, 0, () => ProvidedContext];
|
|
||||||
var tagListType = [1, n0, _tLT, 0, () => Tag];
|
|
||||||
var AssumeRole = [9, n0, _AR, 0, () => AssumeRoleRequest, () => AssumeRoleResponse];
|
|
||||||
var AssumeRoleWithWebIdentity = [
|
|
||||||
9,
|
|
||||||
n0,
|
|
||||||
_ARWWI,
|
|
||||||
0,
|
|
||||||
() => AssumeRoleWithWebIdentityRequest,
|
|
||||||
() => AssumeRoleWithWebIdentityResponse,
|
|
||||||
];
|
|
||||||
|
|
||||||
class AssumeRoleCommand extends smithyClient.Command
|
|
||||||
.classBuilder()
|
|
||||||
.ep(EndpointParameters.commonParams)
|
|
||||||
.m(function (Command, cs, config, o) {
|
|
||||||
return [middlewareEndpoint.getEndpointPlugin(config, Command.getEndpointParameterInstructions())];
|
|
||||||
})
|
|
||||||
.s("AWSSecurityTokenServiceV20110615", "AssumeRole", {})
|
|
||||||
.n("STSClient", "AssumeRoleCommand")
|
|
||||||
.sc(AssumeRole)
|
|
||||||
.build() {
|
|
||||||
}
|
|
||||||
|
|
||||||
class AssumeRoleWithWebIdentityCommand extends smithyClient.Command
|
|
||||||
.classBuilder()
|
|
||||||
.ep(EndpointParameters.commonParams)
|
|
||||||
.m(function (Command, cs, config, o) {
|
|
||||||
return [middlewareEndpoint.getEndpointPlugin(config, Command.getEndpointParameterInstructions())];
|
|
||||||
})
|
|
||||||
.s("AWSSecurityTokenServiceV20110615", "AssumeRoleWithWebIdentity", {})
|
|
||||||
.n("STSClient", "AssumeRoleWithWebIdentityCommand")
|
|
||||||
.sc(AssumeRoleWithWebIdentity)
|
|
||||||
.build() {
|
|
||||||
}
|
|
||||||
|
|
||||||
const commands = {
|
|
||||||
AssumeRoleCommand,
|
|
||||||
AssumeRoleWithWebIdentityCommand,
|
|
||||||
};
|
|
||||||
class STS extends STSClient.STSClient {
|
|
||||||
}
|
|
||||||
smithyClient.createAggregatedClient(commands, STS);
|
|
||||||
|
|
||||||
const getAccountIdFromAssumedRoleUser = (assumedRoleUser) => {
|
|
||||||
if (typeof assumedRoleUser?.Arn === "string") {
|
|
||||||
const arnComponents = assumedRoleUser.Arn.split(":");
|
|
||||||
if (arnComponents.length > 4 && arnComponents[4] !== "") {
|
|
||||||
return arnComponents[4];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
const resolveRegion = async (_region, _parentRegion, credentialProviderLogger, loaderConfig = {}) => {
|
|
||||||
const region = typeof _region === "function" ? await _region() : _region;
|
|
||||||
const parentRegion = typeof _parentRegion === "function" ? await _parentRegion() : _parentRegion;
|
|
||||||
const stsDefaultRegion = await regionConfigResolver.stsRegionDefaultResolver(loaderConfig)();
|
|
||||||
credentialProviderLogger?.debug?.("@aws-sdk/client-sts::resolveRegion", "accepting first of:", `${region} (credential provider clientConfig)`, `${parentRegion} (contextual client)`, `${stsDefaultRegion} (STS default: AWS_REGION, profile region, or us-east-1)`);
|
|
||||||
return region ?? parentRegion ?? stsDefaultRegion;
|
|
||||||
};
|
|
||||||
const getDefaultRoleAssumer$1 = (stsOptions, STSClient) => {
|
|
||||||
let stsClient;
|
|
||||||
let closureSourceCreds;
|
|
||||||
return async (sourceCreds, params) => {
|
|
||||||
closureSourceCreds = sourceCreds;
|
|
||||||
if (!stsClient) {
|
|
||||||
const { logger = stsOptions?.parentClientConfig?.logger, profile = stsOptions?.parentClientConfig?.profile, region, requestHandler = stsOptions?.parentClientConfig?.requestHandler, credentialProviderLogger, userAgentAppId = stsOptions?.parentClientConfig?.userAgentAppId, } = stsOptions;
|
|
||||||
const resolvedRegion = await resolveRegion(region, stsOptions?.parentClientConfig?.region, credentialProviderLogger, {
|
|
||||||
logger,
|
|
||||||
profile,
|
|
||||||
});
|
|
||||||
const isCompatibleRequestHandler = !isH2(requestHandler);
|
|
||||||
stsClient = new STSClient({
|
|
||||||
...stsOptions,
|
|
||||||
userAgentAppId,
|
|
||||||
profile,
|
|
||||||
credentialDefaultProvider: () => async () => closureSourceCreds,
|
|
||||||
region: resolvedRegion,
|
|
||||||
requestHandler: isCompatibleRequestHandler ? requestHandler : undefined,
|
|
||||||
logger: logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const { Credentials, AssumedRoleUser } = await stsClient.send(new AssumeRoleCommand(params));
|
|
||||||
if (!Credentials || !Credentials.AccessKeyId || !Credentials.SecretAccessKey) {
|
|
||||||
throw new Error(`Invalid response from STS.assumeRole call with role ${params.RoleArn}`);
|
|
||||||
}
|
|
||||||
const accountId = getAccountIdFromAssumedRoleUser(AssumedRoleUser);
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId: Credentials.AccessKeyId,
|
|
||||||
secretAccessKey: Credentials.SecretAccessKey,
|
|
||||||
sessionToken: Credentials.SessionToken,
|
|
||||||
expiration: Credentials.Expiration,
|
|
||||||
...(Credentials.CredentialScope && { credentialScope: Credentials.CredentialScope }),
|
|
||||||
...(accountId && { accountId }),
|
|
||||||
};
|
|
||||||
client.setCredentialFeature(credentials, "CREDENTIALS_STS_ASSUME_ROLE", "i");
|
|
||||||
return credentials;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const getDefaultRoleAssumerWithWebIdentity$1 = (stsOptions, STSClient) => {
|
|
||||||
let stsClient;
|
|
||||||
return async (params) => {
|
|
||||||
if (!stsClient) {
|
|
||||||
const { logger = stsOptions?.parentClientConfig?.logger, profile = stsOptions?.parentClientConfig?.profile, region, requestHandler = stsOptions?.parentClientConfig?.requestHandler, credentialProviderLogger, userAgentAppId = stsOptions?.parentClientConfig?.userAgentAppId, } = stsOptions;
|
|
||||||
const resolvedRegion = await resolveRegion(region, stsOptions?.parentClientConfig?.region, credentialProviderLogger, {
|
|
||||||
logger,
|
|
||||||
profile,
|
|
||||||
});
|
|
||||||
const isCompatibleRequestHandler = !isH2(requestHandler);
|
|
||||||
stsClient = new STSClient({
|
|
||||||
...stsOptions,
|
|
||||||
userAgentAppId,
|
|
||||||
profile,
|
|
||||||
region: resolvedRegion,
|
|
||||||
requestHandler: isCompatibleRequestHandler ? requestHandler : undefined,
|
|
||||||
logger: logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const { Credentials, AssumedRoleUser } = await stsClient.send(new AssumeRoleWithWebIdentityCommand(params));
|
|
||||||
if (!Credentials || !Credentials.AccessKeyId || !Credentials.SecretAccessKey) {
|
|
||||||
throw new Error(`Invalid response from STS.assumeRoleWithWebIdentity call with role ${params.RoleArn}`);
|
|
||||||
}
|
|
||||||
const accountId = getAccountIdFromAssumedRoleUser(AssumedRoleUser);
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId: Credentials.AccessKeyId,
|
|
||||||
secretAccessKey: Credentials.SecretAccessKey,
|
|
||||||
sessionToken: Credentials.SessionToken,
|
|
||||||
expiration: Credentials.Expiration,
|
|
||||||
...(Credentials.CredentialScope && { credentialScope: Credentials.CredentialScope }),
|
|
||||||
...(accountId && { accountId }),
|
|
||||||
};
|
|
||||||
if (accountId) {
|
|
||||||
client.setCredentialFeature(credentials, "RESOLVED_ACCOUNT_ID", "T");
|
|
||||||
}
|
|
||||||
client.setCredentialFeature(credentials, "CREDENTIALS_STS_ASSUME_ROLE_WEB_ID", "k");
|
|
||||||
return credentials;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const isH2 = (requestHandler) => {
|
|
||||||
return requestHandler?.metadata?.handlerProtocol === "h2";
|
|
||||||
};
|
|
||||||
|
|
||||||
const getCustomizableStsClientCtor = (baseCtor, customizations) => {
|
|
||||||
if (!customizations)
|
|
||||||
return baseCtor;
|
|
||||||
else
|
|
||||||
return class CustomizableSTSClient extends baseCtor {
|
|
||||||
constructor(config) {
|
|
||||||
super(config);
|
|
||||||
for (const customization of customizations) {
|
|
||||||
this.middlewareStack.use(customization);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const getDefaultRoleAssumer = (stsOptions = {}, stsPlugins) => getDefaultRoleAssumer$1(stsOptions, getCustomizableStsClientCtor(STSClient.STSClient, stsPlugins));
|
|
||||||
const getDefaultRoleAssumerWithWebIdentity = (stsOptions = {}, stsPlugins) => getDefaultRoleAssumerWithWebIdentity$1(stsOptions, getCustomizableStsClientCtor(STSClient.STSClient, stsPlugins));
|
|
||||||
const decorateDefaultCredentialProvider = (provider) => (input) => provider({
|
|
||||||
roleAssumer: getDefaultRoleAssumer(input),
|
|
||||||
roleAssumerWithWebIdentity: getDefaultRoleAssumerWithWebIdentity(input),
|
|
||||||
...input,
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "$Command", ({
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return smithyClient.Command; }
|
|
||||||
}));
|
|
||||||
exports.AssumeRoleCommand = AssumeRoleCommand;
|
|
||||||
exports.AssumeRoleWithWebIdentityCommand = AssumeRoleWithWebIdentityCommand;
|
|
||||||
exports.ExpiredTokenException = ExpiredTokenException$1;
|
|
||||||
exports.IDPCommunicationErrorException = IDPCommunicationErrorException$1;
|
|
||||||
exports.IDPRejectedClaimException = IDPRejectedClaimException$1;
|
|
||||||
exports.InvalidIdentityTokenException = InvalidIdentityTokenException$1;
|
|
||||||
exports.MalformedPolicyDocumentException = MalformedPolicyDocumentException$1;
|
|
||||||
exports.PackedPolicyTooLargeException = PackedPolicyTooLargeException$1;
|
|
||||||
exports.RegionDisabledException = RegionDisabledException$1;
|
|
||||||
exports.STS = STS;
|
|
||||||
exports.STSServiceException = STSServiceException$1;
|
|
||||||
exports.decorateDefaultCredentialProvider = decorateDefaultCredentialProvider;
|
|
||||||
exports.getDefaultRoleAssumer = getDefaultRoleAssumer;
|
|
||||||
exports.getDefaultRoleAssumerWithWebIdentity = getDefaultRoleAssumerWithWebIdentity;
|
|
||||||
Object.keys(STSClient).forEach(function (k) {
|
|
||||||
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return STSClient[k]; }
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 6578:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getRuntimeConfig = void 0;
|
|
||||||
const tslib_1 = __webpack_require__(1860);
|
|
||||||
const package_json_1 = tslib_1.__importDefault(__webpack_require__(9955));
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const util_user_agent_node_1 = __webpack_require__(1656);
|
|
||||||
const config_resolver_1 = __webpack_require__(9316);
|
|
||||||
const core_2 = __webpack_require__(402);
|
|
||||||
const hash_node_1 = __webpack_require__(5092);
|
|
||||||
const middleware_retry_1 = __webpack_require__(9618);
|
|
||||||
const node_config_provider_1 = __webpack_require__(5704);
|
|
||||||
const node_http_handler_1 = __webpack_require__(1279);
|
|
||||||
const util_body_length_node_1 = __webpack_require__(3638);
|
|
||||||
const util_retry_1 = __webpack_require__(5518);
|
|
||||||
const runtimeConfig_shared_1 = __webpack_require__(4443);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const util_defaults_mode_node_1 = __webpack_require__(5435);
|
|
||||||
const smithy_client_2 = __webpack_require__(1411);
|
|
||||||
const getRuntimeConfig = (config) => {
|
|
||||||
(0, smithy_client_2.emitWarningIfUnsupportedVersion)(process.version);
|
|
||||||
const defaultsMode = (0, util_defaults_mode_node_1.resolveDefaultsModeConfig)(config);
|
|
||||||
const defaultConfigProvider = () => defaultsMode().then(smithy_client_1.loadConfigsForDefaultMode);
|
|
||||||
const clientSharedValues = (0, runtimeConfig_shared_1.getRuntimeConfig)(config);
|
|
||||||
(0, core_1.emitWarningIfUnsupportedVersion)(process.version);
|
|
||||||
const loaderConfig = {
|
|
||||||
profile: config?.profile,
|
|
||||||
logger: clientSharedValues.logger,
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
...clientSharedValues,
|
|
||||||
...config,
|
|
||||||
runtime: "node",
|
|
||||||
defaultsMode,
|
|
||||||
authSchemePreference: config?.authSchemePreference ?? (0, node_config_provider_1.loadConfig)(core_1.NODE_AUTH_SCHEME_PREFERENCE_OPTIONS, loaderConfig),
|
|
||||||
bodyLengthChecker: config?.bodyLengthChecker ?? util_body_length_node_1.calculateBodyLength,
|
|
||||||
defaultUserAgentProvider: config?.defaultUserAgentProvider ??
|
|
||||||
(0, util_user_agent_node_1.createDefaultUserAgentProvider)({ serviceId: clientSharedValues.serviceId, clientVersion: package_json_1.default.version }),
|
|
||||||
httpAuthSchemes: config?.httpAuthSchemes ?? [
|
|
||||||
{
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("aws.auth#sigv4") ||
|
|
||||||
(async (idProps) => await config.credentialDefaultProvider(idProps?.__config || {})()),
|
|
||||||
signer: new core_1.AwsSdkSigV4Signer(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("smithy.api#noAuth") || (async () => ({})),
|
|
||||||
signer: new core_2.NoAuthSigner(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
maxAttempts: config?.maxAttempts ?? (0, node_config_provider_1.loadConfig)(middleware_retry_1.NODE_MAX_ATTEMPT_CONFIG_OPTIONS, config),
|
|
||||||
region: config?.region ??
|
|
||||||
(0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_REGION_CONFIG_OPTIONS, { ...config_resolver_1.NODE_REGION_CONFIG_FILE_OPTIONS, ...loaderConfig }),
|
|
||||||
requestHandler: node_http_handler_1.NodeHttpHandler.create(config?.requestHandler ?? defaultConfigProvider),
|
|
||||||
retryMode: config?.retryMode ??
|
|
||||||
(0, node_config_provider_1.loadConfig)({
|
|
||||||
...middleware_retry_1.NODE_RETRY_MODE_CONFIG_OPTIONS,
|
|
||||||
default: async () => (await defaultConfigProvider()).retryMode || util_retry_1.DEFAULT_RETRY_MODE,
|
|
||||||
}, config),
|
|
||||||
sha256: config?.sha256 ?? hash_node_1.Hash.bind(null, "sha256"),
|
|
||||||
streamCollector: config?.streamCollector ?? node_http_handler_1.streamCollector,
|
|
||||||
useDualstackEndpoint: config?.useDualstackEndpoint ?? (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
useFipsEndpoint: config?.useFipsEndpoint ?? (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
userAgentAppId: config?.userAgentAppId ?? (0, node_config_provider_1.loadConfig)(util_user_agent_node_1.NODE_APP_ID_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getRuntimeConfig = getRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 4443:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getRuntimeConfig = void 0;
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const protocols_1 = __webpack_require__(7288);
|
|
||||||
const core_2 = __webpack_require__(402);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const url_parser_1 = __webpack_require__(4494);
|
|
||||||
const util_base64_1 = __webpack_require__(8385);
|
|
||||||
const util_utf8_1 = __webpack_require__(1577);
|
|
||||||
const httpAuthSchemeProvider_1 = __webpack_require__(7851);
|
|
||||||
const endpointResolver_1 = __webpack_require__(9765);
|
|
||||||
const getRuntimeConfig = (config) => {
|
|
||||||
return {
|
|
||||||
apiVersion: "2011-06-15",
|
|
||||||
base64Decoder: config?.base64Decoder ?? util_base64_1.fromBase64,
|
|
||||||
base64Encoder: config?.base64Encoder ?? util_base64_1.toBase64,
|
|
||||||
disableHostPrefix: config?.disableHostPrefix ?? false,
|
|
||||||
endpointProvider: config?.endpointProvider ?? endpointResolver_1.defaultEndpointResolver,
|
|
||||||
extensions: config?.extensions ?? [],
|
|
||||||
httpAuthSchemeProvider: config?.httpAuthSchemeProvider ?? httpAuthSchemeProvider_1.defaultSTSHttpAuthSchemeProvider,
|
|
||||||
httpAuthSchemes: config?.httpAuthSchemes ?? [
|
|
||||||
{
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("aws.auth#sigv4"),
|
|
||||||
signer: new core_1.AwsSdkSigV4Signer(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("smithy.api#noAuth") || (async () => ({})),
|
|
||||||
signer: new core_2.NoAuthSigner(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
logger: config?.logger ?? new smithy_client_1.NoOpLogger(),
|
|
||||||
protocol: config?.protocol ??
|
|
||||||
new protocols_1.AwsQueryProtocol({
|
|
||||||
defaultNamespace: "com.amazonaws.sts",
|
|
||||||
xmlNamespace: "https://sts.amazonaws.com/doc/2011-06-15/",
|
|
||||||
version: "2011-06-15",
|
|
||||||
}),
|
|
||||||
serviceId: config?.serviceId ?? "STS",
|
|
||||||
urlParser: config?.urlParser ?? url_parser_1.parseUrl,
|
|
||||||
utf8Decoder: config?.utf8Decoder ?? util_utf8_1.fromUtf8,
|
|
||||||
utf8Encoder: config?.utf8Encoder ?? util_utf8_1.toUtf8,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getRuntimeConfig = getRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 7742:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.resolveRuntimeExtensions = void 0;
|
|
||||||
const region_config_resolver_1 = __webpack_require__(6463);
|
|
||||||
const protocol_http_1 = __webpack_require__(2356);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const httpAuthExtensionConfiguration_1 = __webpack_require__(4532);
|
|
||||||
const resolveRuntimeExtensions = (runtimeConfig, extensions) => {
|
|
||||||
const extensionConfiguration = Object.assign((0, region_config_resolver_1.getAwsRegionExtensionConfiguration)(runtimeConfig), (0, smithy_client_1.getDefaultExtensionConfiguration)(runtimeConfig), (0, protocol_http_1.getHttpHandlerExtensionConfiguration)(runtimeConfig), (0, httpAuthExtensionConfiguration_1.getHttpAuthExtensionConfiguration)(runtimeConfig));
|
|
||||||
extensions.forEach((extension) => extension.configure(extensionConfiguration));
|
|
||||||
return Object.assign(runtimeConfig, (0, region_config_resolver_1.resolveAwsRegionExtensionConfiguration)(extensionConfiguration), (0, smithy_client_1.resolveDefaultRuntimeConfig)(extensionConfiguration), (0, protocol_http_1.resolveHttpHandlerRuntimeConfig)(extensionConfiguration), (0, httpAuthExtensionConfiguration_1.resolveHttpAuthRuntimeConfig)(extensionConfiguration));
|
|
||||||
};
|
|
||||||
exports.resolveRuntimeExtensions = resolveRuntimeExtensions;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9955:
|
|
||||||
/***/ ((module) => {
|
|
||||||
|
|
||||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@aws-sdk/nested-clients","version":"3.933.0","description":"Nested clients for AWS SDK packages.","main":"./dist-cjs/index.js","module":"./dist-es/index.js","types":"./dist-types/index.d.ts","scripts":{"build":"yarn lint && concurrently \'yarn:build:cjs\' \'yarn:build:es\' \'yarn:build:types\'","build:cjs":"node ../../scripts/compilation/inline nested-clients","build:es":"tsc -p tsconfig.es.json","build:include:deps":"lerna run --scope $npm_package_name --include-dependencies build","build:types":"tsc -p tsconfig.types.json","build:types:downlevel":"downlevel-dts dist-types dist-types/ts3.4","clean":"rimraf ./dist-* && rimraf *.tsbuildinfo","lint":"node ../../scripts/validation/submodules-linter.js --pkg nested-clients","test":"yarn g:vitest run","test:watch":"yarn g:vitest watch"},"engines":{"node":">=18.0.0"},"sideEffects":false,"author":{"name":"AWS SDK for JavaScript Team","url":"https://aws.amazon.com/javascript/"},"license":"Apache-2.0","dependencies":{"@aws-crypto/sha256-browser":"5.2.0","@aws-crypto/sha256-js":"5.2.0","@aws-sdk/core":"3.932.0","@aws-sdk/middleware-host-header":"3.930.0","@aws-sdk/middleware-logger":"3.930.0","@aws-sdk/middleware-recursion-detection":"3.933.0","@aws-sdk/middleware-user-agent":"3.932.0","@aws-sdk/region-config-resolver":"3.930.0","@aws-sdk/types":"3.930.0","@aws-sdk/util-endpoints":"3.930.0","@aws-sdk/util-user-agent-browser":"3.930.0","@aws-sdk/util-user-agent-node":"3.932.0","@smithy/config-resolver":"^4.4.3","@smithy/core":"^3.18.2","@smithy/fetch-http-handler":"^5.3.6","@smithy/hash-node":"^4.2.5","@smithy/invalid-dependency":"^4.2.5","@smithy/middleware-content-length":"^4.2.5","@smithy/middleware-endpoint":"^4.3.9","@smithy/middleware-retry":"^4.4.9","@smithy/middleware-serde":"^4.2.5","@smithy/middleware-stack":"^4.2.5","@smithy/node-config-provider":"^4.3.5","@smithy/node-http-handler":"^4.4.5","@smithy/protocol-http":"^5.3.5","@smithy/smithy-client":"^4.9.5","@smithy/types":"^4.9.0","@smithy/url-parser":"^4.2.5","@smithy/util-base64":"^4.3.0","@smithy/util-body-length-browser":"^4.2.0","@smithy/util-body-length-node":"^4.2.1","@smithy/util-defaults-mode-browser":"^4.3.8","@smithy/util-defaults-mode-node":"^4.2.11","@smithy/util-endpoints":"^3.2.5","@smithy/util-middleware":"^4.2.5","@smithy/util-retry":"^4.2.5","@smithy/util-utf8":"^4.2.0","tslib":"^2.6.2"},"devDependencies":{"concurrently":"7.0.0","downlevel-dts":"0.10.1","rimraf":"3.0.2","typescript":"~5.8.3"},"typesVersions":{"<4.0":{"dist-types/*":["dist-types/ts3.4/*"]}},"files":["./sso-oidc.d.ts","./sso-oidc.js","./sts.d.ts","./sts.js","dist-*/**"],"browser":{"./dist-es/submodules/sso-oidc/runtimeConfig":"./dist-es/submodules/sso-oidc/runtimeConfig.browser","./dist-es/submodules/sts/runtimeConfig":"./dist-es/submodules/sts/runtimeConfig.browser"},"react-native":{},"homepage":"https://github.com/aws/aws-sdk-js-v3/tree/main/packages/nested-clients","repository":{"type":"git","url":"https://github.com/aws/aws-sdk-js-v3.git","directory":"packages/nested-clients"},"exports":{"./sso-oidc":{"types":"./dist-types/submodules/sso-oidc/index.d.ts","module":"./dist-es/submodules/sso-oidc/index.js","node":"./dist-cjs/submodules/sso-oidc/index.js","import":"./dist-es/submodules/sso-oidc/index.js","require":"./dist-cjs/submodules/sso-oidc/index.js"},"./sts":{"types":"./dist-types/submodules/sts/index.d.ts","module":"./dist-es/submodules/sts/index.js","node":"./dist-cjs/submodules/sts/index.js","import":"./dist-es/submodules/sts/index.js","require":"./dist-cjs/submodules/sts/index.js"}}}');
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-93
@@ -1,93 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 360;
|
|
||||||
exports.ids = [360];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 5360:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var sharedIniFileLoader = __webpack_require__(4964);
|
|
||||||
var propertyProvider = __webpack_require__(1238);
|
|
||||||
var child_process = __webpack_require__(5317);
|
|
||||||
var util = __webpack_require__(9023);
|
|
||||||
var client = __webpack_require__(5152);
|
|
||||||
|
|
||||||
const getValidatedProcessCredentials = (profileName, data, profiles) => {
|
|
||||||
if (data.Version !== 1) {
|
|
||||||
throw Error(`Profile ${profileName} credential_process did not return Version 1.`);
|
|
||||||
}
|
|
||||||
if (data.AccessKeyId === undefined || data.SecretAccessKey === undefined) {
|
|
||||||
throw Error(`Profile ${profileName} credential_process returned invalid credentials.`);
|
|
||||||
}
|
|
||||||
if (data.Expiration) {
|
|
||||||
const currentTime = new Date();
|
|
||||||
const expireTime = new Date(data.Expiration);
|
|
||||||
if (expireTime < currentTime) {
|
|
||||||
throw Error(`Profile ${profileName} credential_process returned expired credentials.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let accountId = data.AccountId;
|
|
||||||
if (!accountId && profiles?.[profileName]?.aws_account_id) {
|
|
||||||
accountId = profiles[profileName].aws_account_id;
|
|
||||||
}
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId: data.AccessKeyId,
|
|
||||||
secretAccessKey: data.SecretAccessKey,
|
|
||||||
...(data.SessionToken && { sessionToken: data.SessionToken }),
|
|
||||||
...(data.Expiration && { expiration: new Date(data.Expiration) }),
|
|
||||||
...(data.CredentialScope && { credentialScope: data.CredentialScope }),
|
|
||||||
...(accountId && { accountId }),
|
|
||||||
};
|
|
||||||
client.setCredentialFeature(credentials, "CREDENTIALS_PROCESS", "w");
|
|
||||||
return credentials;
|
|
||||||
};
|
|
||||||
|
|
||||||
const resolveProcessCredentials = async (profileName, profiles, logger) => {
|
|
||||||
const profile = profiles[profileName];
|
|
||||||
if (profiles[profileName]) {
|
|
||||||
const credentialProcess = profile["credential_process"];
|
|
||||||
if (credentialProcess !== undefined) {
|
|
||||||
const execPromise = util.promisify(sharedIniFileLoader.externalDataInterceptor?.getTokenRecord?.().exec ?? child_process.exec);
|
|
||||||
try {
|
|
||||||
const { stdout } = await execPromise(credentialProcess);
|
|
||||||
let data;
|
|
||||||
try {
|
|
||||||
data = JSON.parse(stdout.trim());
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
throw Error(`Profile ${profileName} credential_process returned invalid JSON.`);
|
|
||||||
}
|
|
||||||
return getValidatedProcessCredentials(profileName, data, profiles);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(error.message, { logger });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Profile ${profileName} did not contain credential_process.`, { logger });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Profile ${profileName} could not be found in shared credentials file.`, {
|
|
||||||
logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const fromProcess = (init = {}) => async ({ callerClientConfig } = {}) => {
|
|
||||||
init.logger?.debug("@aws-sdk/credential-provider-process - fromProcess");
|
|
||||||
const profiles = await sharedIniFileLoader.parseKnownFiles(init);
|
|
||||||
return resolveProcessCredentials(sharedIniFileLoader.getProfileName({
|
|
||||||
profile: init.profile ?? callerClientConfig?.profile,
|
|
||||||
}), profiles, init.logger);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.fromProcess = fromProcess;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-794
@@ -1,794 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 443;
|
|
||||||
exports.ids = [443];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 8396:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.resolveHttpAuthSchemeConfig = exports.defaultSSOOIDCHttpAuthSchemeProvider = exports.defaultSSOOIDCHttpAuthSchemeParametersProvider = void 0;
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const util_middleware_1 = __webpack_require__(6324);
|
|
||||||
const defaultSSOOIDCHttpAuthSchemeParametersProvider = async (config, context, input) => {
|
|
||||||
return {
|
|
||||||
operation: (0, util_middleware_1.getSmithyContext)(context).operation,
|
|
||||||
region: (await (0, util_middleware_1.normalizeProvider)(config.region)()) ||
|
|
||||||
(() => {
|
|
||||||
throw new Error("expected `region` to be configured for `aws.auth#sigv4`");
|
|
||||||
})(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.defaultSSOOIDCHttpAuthSchemeParametersProvider = defaultSSOOIDCHttpAuthSchemeParametersProvider;
|
|
||||||
function createAwsAuthSigv4HttpAuthOption(authParameters) {
|
|
||||||
return {
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
signingProperties: {
|
|
||||||
name: "sso-oauth",
|
|
||||||
region: authParameters.region,
|
|
||||||
},
|
|
||||||
propertiesExtractor: (config, context) => ({
|
|
||||||
signingProperties: {
|
|
||||||
config,
|
|
||||||
context,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function createSmithyApiNoAuthHttpAuthOption(authParameters) {
|
|
||||||
return {
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const defaultSSOOIDCHttpAuthSchemeProvider = (authParameters) => {
|
|
||||||
const options = [];
|
|
||||||
switch (authParameters.operation) {
|
|
||||||
case "CreateToken": {
|
|
||||||
options.push(createSmithyApiNoAuthHttpAuthOption(authParameters));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
options.push(createAwsAuthSigv4HttpAuthOption(authParameters));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
};
|
|
||||||
exports.defaultSSOOIDCHttpAuthSchemeProvider = defaultSSOOIDCHttpAuthSchemeProvider;
|
|
||||||
const resolveHttpAuthSchemeConfig = (config) => {
|
|
||||||
const config_0 = (0, core_1.resolveAwsSdkSigV4Config)(config);
|
|
||||||
return Object.assign(config_0, {
|
|
||||||
authSchemePreference: (0, util_middleware_1.normalizeProvider)(config.authSchemePreference ?? []),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
exports.resolveHttpAuthSchemeConfig = resolveHttpAuthSchemeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 546:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.defaultEndpointResolver = void 0;
|
|
||||||
const util_endpoints_1 = __webpack_require__(3068);
|
|
||||||
const util_endpoints_2 = __webpack_require__(9674);
|
|
||||||
const ruleset_1 = __webpack_require__(9947);
|
|
||||||
const cache = new util_endpoints_2.EndpointCache({
|
|
||||||
size: 50,
|
|
||||||
params: ["Endpoint", "Region", "UseDualStack", "UseFIPS"],
|
|
||||||
});
|
|
||||||
const defaultEndpointResolver = (endpointParams, context = {}) => {
|
|
||||||
return cache.get(endpointParams, () => (0, util_endpoints_2.resolveEndpoint)(ruleset_1.ruleSet, {
|
|
||||||
endpointParams: endpointParams,
|
|
||||||
logger: context.logger,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
exports.defaultEndpointResolver = defaultEndpointResolver;
|
|
||||||
util_endpoints_2.customEndpointFunctions.aws = util_endpoints_1.awsEndpointFunctions;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9947:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.ruleSet = void 0;
|
|
||||||
const u = "required", v = "fn", w = "argv", x = "ref";
|
|
||||||
const a = true, b = "isSet", c = "booleanEquals", d = "error", e = "endpoint", f = "tree", g = "PartitionResult", h = "getAttr", i = { [u]: false, "type": "string" }, j = { [u]: true, "default": false, "type": "boolean" }, k = { [x]: "Endpoint" }, l = { [v]: c, [w]: [{ [x]: "UseFIPS" }, true] }, m = { [v]: c, [w]: [{ [x]: "UseDualStack" }, true] }, n = {}, o = { [v]: h, [w]: [{ [x]: g }, "supportsFIPS"] }, p = { [x]: g }, q = { [v]: c, [w]: [true, { [v]: h, [w]: [p, "supportsDualStack"] }] }, r = [l], s = [m], t = [{ [x]: "Region" }];
|
|
||||||
const _data = { version: "1.0", parameters: { Region: i, UseDualStack: j, UseFIPS: j, Endpoint: i }, rules: [{ conditions: [{ [v]: b, [w]: [k] }], rules: [{ conditions: r, error: "Invalid Configuration: FIPS and custom endpoint are not supported", type: d }, { conditions: s, error: "Invalid Configuration: Dualstack and custom endpoint are not supported", type: d }, { endpoint: { url: k, properties: n, headers: n }, type: e }], type: f }, { conditions: [{ [v]: b, [w]: t }], rules: [{ conditions: [{ [v]: "aws.partition", [w]: t, assign: g }], rules: [{ conditions: [l, m], rules: [{ conditions: [{ [v]: c, [w]: [a, o] }, q], rules: [{ endpoint: { url: "https://oidc-fips.{Region}.{PartitionResult#dualStackDnsSuffix}", properties: n, headers: n }, type: e }], type: f }, { error: "FIPS and DualStack are enabled, but this partition does not support one or both", type: d }], type: f }, { conditions: r, rules: [{ conditions: [{ [v]: c, [w]: [o, a] }], rules: [{ conditions: [{ [v]: "stringEquals", [w]: [{ [v]: h, [w]: [p, "name"] }, "aws-us-gov"] }], endpoint: { url: "https://oidc.{Region}.amazonaws.com", properties: n, headers: n }, type: e }, { endpoint: { url: "https://oidc-fips.{Region}.{PartitionResult#dnsSuffix}", properties: n, headers: n }, type: e }], type: f }, { error: "FIPS is enabled but this partition does not support FIPS", type: d }], type: f }, { conditions: s, rules: [{ conditions: [q], rules: [{ endpoint: { url: "https://oidc.{Region}.{PartitionResult#dualStackDnsSuffix}", properties: n, headers: n }, type: e }], type: f }, { error: "DualStack is enabled but this partition does not support DualStack", type: d }], type: f }, { endpoint: { url: "https://oidc.{Region}.{PartitionResult#dnsSuffix}", properties: n, headers: n }, type: e }], type: f }], type: f }, { error: "Invalid Configuration: Missing Region", type: d }] };
|
|
||||||
exports.ruleSet = _data;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9443:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
var __webpack_unused_export__;
|
|
||||||
|
|
||||||
|
|
||||||
var middlewareHostHeader = __webpack_require__(2590);
|
|
||||||
var middlewareLogger = __webpack_require__(5242);
|
|
||||||
var middlewareRecursionDetection = __webpack_require__(1568);
|
|
||||||
var middlewareUserAgent = __webpack_require__(2959);
|
|
||||||
var configResolver = __webpack_require__(9316);
|
|
||||||
var core = __webpack_require__(402);
|
|
||||||
var schema = __webpack_require__(6890);
|
|
||||||
var middlewareContentLength = __webpack_require__(7212);
|
|
||||||
var middlewareEndpoint = __webpack_require__(99);
|
|
||||||
var middlewareRetry = __webpack_require__(9618);
|
|
||||||
var smithyClient = __webpack_require__(1411);
|
|
||||||
var httpAuthSchemeProvider = __webpack_require__(8396);
|
|
||||||
var runtimeConfig = __webpack_require__(6901);
|
|
||||||
var regionConfigResolver = __webpack_require__(6463);
|
|
||||||
var protocolHttp = __webpack_require__(2356);
|
|
||||||
|
|
||||||
const resolveClientEndpointParameters = (options) => {
|
|
||||||
return Object.assign(options, {
|
|
||||||
useDualstackEndpoint: options.useDualstackEndpoint ?? false,
|
|
||||||
useFipsEndpoint: options.useFipsEndpoint ?? false,
|
|
||||||
defaultSigningName: "sso-oauth",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const commonParams = {
|
|
||||||
UseFIPS: { type: "builtInParams", name: "useFipsEndpoint" },
|
|
||||||
Endpoint: { type: "builtInParams", name: "endpoint" },
|
|
||||||
Region: { type: "builtInParams", name: "region" },
|
|
||||||
UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" },
|
|
||||||
};
|
|
||||||
|
|
||||||
const getHttpAuthExtensionConfiguration = (runtimeConfig) => {
|
|
||||||
const _httpAuthSchemes = runtimeConfig.httpAuthSchemes;
|
|
||||||
let _httpAuthSchemeProvider = runtimeConfig.httpAuthSchemeProvider;
|
|
||||||
let _credentials = runtimeConfig.credentials;
|
|
||||||
return {
|
|
||||||
setHttpAuthScheme(httpAuthScheme) {
|
|
||||||
const index = _httpAuthSchemes.findIndex((scheme) => scheme.schemeId === httpAuthScheme.schemeId);
|
|
||||||
if (index === -1) {
|
|
||||||
_httpAuthSchemes.push(httpAuthScheme);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_httpAuthSchemes.splice(index, 1, httpAuthScheme);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
httpAuthSchemes() {
|
|
||||||
return _httpAuthSchemes;
|
|
||||||
},
|
|
||||||
setHttpAuthSchemeProvider(httpAuthSchemeProvider) {
|
|
||||||
_httpAuthSchemeProvider = httpAuthSchemeProvider;
|
|
||||||
},
|
|
||||||
httpAuthSchemeProvider() {
|
|
||||||
return _httpAuthSchemeProvider;
|
|
||||||
},
|
|
||||||
setCredentials(credentials) {
|
|
||||||
_credentials = credentials;
|
|
||||||
},
|
|
||||||
credentials() {
|
|
||||||
return _credentials;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const resolveHttpAuthRuntimeConfig = (config) => {
|
|
||||||
return {
|
|
||||||
httpAuthSchemes: config.httpAuthSchemes(),
|
|
||||||
httpAuthSchemeProvider: config.httpAuthSchemeProvider(),
|
|
||||||
credentials: config.credentials(),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const resolveRuntimeExtensions = (runtimeConfig, extensions) => {
|
|
||||||
const extensionConfiguration = Object.assign(regionConfigResolver.getAwsRegionExtensionConfiguration(runtimeConfig), smithyClient.getDefaultExtensionConfiguration(runtimeConfig), protocolHttp.getHttpHandlerExtensionConfiguration(runtimeConfig), getHttpAuthExtensionConfiguration(runtimeConfig));
|
|
||||||
extensions.forEach((extension) => extension.configure(extensionConfiguration));
|
|
||||||
return Object.assign(runtimeConfig, regionConfigResolver.resolveAwsRegionExtensionConfiguration(extensionConfiguration), smithyClient.resolveDefaultRuntimeConfig(extensionConfiguration), protocolHttp.resolveHttpHandlerRuntimeConfig(extensionConfiguration), resolveHttpAuthRuntimeConfig(extensionConfiguration));
|
|
||||||
};
|
|
||||||
|
|
||||||
class SSOOIDCClient extends smithyClient.Client {
|
|
||||||
config;
|
|
||||||
constructor(...[configuration]) {
|
|
||||||
const _config_0 = runtimeConfig.getRuntimeConfig(configuration || {});
|
|
||||||
super(_config_0);
|
|
||||||
this.initConfig = _config_0;
|
|
||||||
const _config_1 = resolveClientEndpointParameters(_config_0);
|
|
||||||
const _config_2 = middlewareUserAgent.resolveUserAgentConfig(_config_1);
|
|
||||||
const _config_3 = middlewareRetry.resolveRetryConfig(_config_2);
|
|
||||||
const _config_4 = configResolver.resolveRegionConfig(_config_3);
|
|
||||||
const _config_5 = middlewareHostHeader.resolveHostHeaderConfig(_config_4);
|
|
||||||
const _config_6 = middlewareEndpoint.resolveEndpointConfig(_config_5);
|
|
||||||
const _config_7 = httpAuthSchemeProvider.resolveHttpAuthSchemeConfig(_config_6);
|
|
||||||
const _config_8 = resolveRuntimeExtensions(_config_7, configuration?.extensions || []);
|
|
||||||
this.config = _config_8;
|
|
||||||
this.middlewareStack.use(schema.getSchemaSerdePlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareUserAgent.getUserAgentPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareRetry.getRetryPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareContentLength.getContentLengthPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareHostHeader.getHostHeaderPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareLogger.getLoggerPlugin(this.config));
|
|
||||||
this.middlewareStack.use(middlewareRecursionDetection.getRecursionDetectionPlugin(this.config));
|
|
||||||
this.middlewareStack.use(core.getHttpAuthSchemeEndpointRuleSetPlugin(this.config, {
|
|
||||||
httpAuthSchemeParametersProvider: httpAuthSchemeProvider.defaultSSOOIDCHttpAuthSchemeParametersProvider,
|
|
||||||
identityProviderConfigProvider: async (config) => new core.DefaultIdentityProviderConfig({
|
|
||||||
"aws.auth#sigv4": config.credentials,
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
this.middlewareStack.use(core.getHttpSigningPlugin(this.config));
|
|
||||||
}
|
|
||||||
destroy() {
|
|
||||||
super.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let SSOOIDCServiceException$1 = class SSOOIDCServiceException extends smithyClient.ServiceException {
|
|
||||||
constructor(options) {
|
|
||||||
super(options);
|
|
||||||
Object.setPrototypeOf(this, SSOOIDCServiceException.prototype);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const AccessDeniedExceptionReason = {
|
|
||||||
KMS_ACCESS_DENIED: "KMS_AccessDeniedException",
|
|
||||||
};
|
|
||||||
let AccessDeniedException$1 = class AccessDeniedException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "AccessDeniedException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
reason;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "AccessDeniedException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, AccessDeniedException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.reason = opts.reason;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let AuthorizationPendingException$1 = class AuthorizationPendingException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "AuthorizationPendingException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "AuthorizationPendingException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, AuthorizationPendingException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let ExpiredTokenException$1 = class ExpiredTokenException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "ExpiredTokenException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "ExpiredTokenException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, ExpiredTokenException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InternalServerException$1 = class InternalServerException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InternalServerException";
|
|
||||||
$fault = "server";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InternalServerException",
|
|
||||||
$fault: "server",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InternalServerException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InvalidClientException$1 = class InvalidClientException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InvalidClientException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidClientException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidClientException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InvalidGrantException$1 = class InvalidGrantException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InvalidGrantException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidGrantException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidGrantException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const InvalidRequestExceptionReason = {
|
|
||||||
KMS_DISABLED_KEY: "KMS_DisabledException",
|
|
||||||
KMS_INVALID_KEY_USAGE: "KMS_InvalidKeyUsageException",
|
|
||||||
KMS_INVALID_STATE: "KMS_InvalidStateException",
|
|
||||||
KMS_KEY_NOT_FOUND: "KMS_NotFoundException",
|
|
||||||
};
|
|
||||||
let InvalidRequestException$1 = class InvalidRequestException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InvalidRequestException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
reason;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidRequestException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidRequestException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.reason = opts.reason;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let InvalidScopeException$1 = class InvalidScopeException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "InvalidScopeException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "InvalidScopeException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, InvalidScopeException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let SlowDownException$1 = class SlowDownException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "SlowDownException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "SlowDownException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, SlowDownException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let UnauthorizedClientException$1 = class UnauthorizedClientException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "UnauthorizedClientException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "UnauthorizedClientException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, UnauthorizedClientException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let UnsupportedGrantTypeException$1 = class UnsupportedGrantTypeException extends SSOOIDCServiceException$1 {
|
|
||||||
name = "UnsupportedGrantTypeException";
|
|
||||||
$fault = "client";
|
|
||||||
error;
|
|
||||||
error_description;
|
|
||||||
constructor(opts) {
|
|
||||||
super({
|
|
||||||
name: "UnsupportedGrantTypeException",
|
|
||||||
$fault: "client",
|
|
||||||
...opts,
|
|
||||||
});
|
|
||||||
Object.setPrototypeOf(this, UnsupportedGrantTypeException.prototype);
|
|
||||||
this.error = opts.error;
|
|
||||||
this.error_description = opts.error_description;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const _ADE = "AccessDeniedException";
|
|
||||||
const _APE = "AuthorizationPendingException";
|
|
||||||
const _AT = "AccessToken";
|
|
||||||
const _CS = "ClientSecret";
|
|
||||||
const _CT = "CreateToken";
|
|
||||||
const _CTR = "CreateTokenRequest";
|
|
||||||
const _CTRr = "CreateTokenResponse";
|
|
||||||
const _CV = "CodeVerifier";
|
|
||||||
const _ETE = "ExpiredTokenException";
|
|
||||||
const _ICE = "InvalidClientException";
|
|
||||||
const _IGE = "InvalidGrantException";
|
|
||||||
const _IRE = "InvalidRequestException";
|
|
||||||
const _ISE = "InternalServerException";
|
|
||||||
const _ISEn = "InvalidScopeException";
|
|
||||||
const _IT = "IdToken";
|
|
||||||
const _RT = "RefreshToken";
|
|
||||||
const _SDE = "SlowDownException";
|
|
||||||
const _UCE = "UnauthorizedClientException";
|
|
||||||
const _UGTE = "UnsupportedGrantTypeException";
|
|
||||||
const _aT = "accessToken";
|
|
||||||
const _c = "client";
|
|
||||||
const _cI = "clientId";
|
|
||||||
const _cS = "clientSecret";
|
|
||||||
const _cV = "codeVerifier";
|
|
||||||
const _co = "code";
|
|
||||||
const _dC = "deviceCode";
|
|
||||||
const _e = "error";
|
|
||||||
const _eI = "expiresIn";
|
|
||||||
const _ed = "error_description";
|
|
||||||
const _gT = "grantType";
|
|
||||||
const _h = "http";
|
|
||||||
const _hE = "httpError";
|
|
||||||
const _iT = "idToken";
|
|
||||||
const _r = "reason";
|
|
||||||
const _rT = "refreshToken";
|
|
||||||
const _rU = "redirectUri";
|
|
||||||
const _s = "scope";
|
|
||||||
const _se = "server";
|
|
||||||
const _sm = "smithy.ts.sdk.synthetic.com.amazonaws.ssooidc";
|
|
||||||
const _tT = "tokenType";
|
|
||||||
const n0 = "com.amazonaws.ssooidc";
|
|
||||||
var AccessToken = [0, n0, _AT, 8, 0];
|
|
||||||
var ClientSecret = [0, n0, _CS, 8, 0];
|
|
||||||
var CodeVerifier = [0, n0, _CV, 8, 0];
|
|
||||||
var IdToken = [0, n0, _IT, 8, 0];
|
|
||||||
var RefreshToken = [0, n0, _RT, 8, 0];
|
|
||||||
var AccessDeniedException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ADE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _r, _ed],
|
|
||||||
[0, 0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(AccessDeniedException, AccessDeniedException$1);
|
|
||||||
var AuthorizationPendingException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_APE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(AuthorizationPendingException, AuthorizationPendingException$1);
|
|
||||||
var CreateTokenRequest = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_CTR,
|
|
||||||
0,
|
|
||||||
[_cI, _cS, _gT, _dC, _co, _rT, _s, _rU, _cV],
|
|
||||||
[0, [() => ClientSecret, 0], 0, 0, 0, [() => RefreshToken, 0], 64 | 0, 0, [() => CodeVerifier, 0]],
|
|
||||||
];
|
|
||||||
var CreateTokenResponse = [
|
|
||||||
3,
|
|
||||||
n0,
|
|
||||||
_CTRr,
|
|
||||||
0,
|
|
||||||
[_aT, _tT, _eI, _rT, _iT],
|
|
||||||
[[() => AccessToken, 0], 0, 1, [() => RefreshToken, 0], [() => IdToken, 0]],
|
|
||||||
];
|
|
||||||
var ExpiredTokenException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ETE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(ExpiredTokenException, ExpiredTokenException$1);
|
|
||||||
var InternalServerException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ISE,
|
|
||||||
{
|
|
||||||
[_e]: _se,
|
|
||||||
[_hE]: 500,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InternalServerException, InternalServerException$1);
|
|
||||||
var InvalidClientException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ICE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 401,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidClientException, InvalidClientException$1);
|
|
||||||
var InvalidGrantException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IGE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidGrantException, InvalidGrantException$1);
|
|
||||||
var InvalidRequestException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_IRE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _r, _ed],
|
|
||||||
[0, 0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidRequestException, InvalidRequestException$1);
|
|
||||||
var InvalidScopeException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_ISEn,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(InvalidScopeException, InvalidScopeException$1);
|
|
||||||
var SlowDownException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_SDE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(SlowDownException, SlowDownException$1);
|
|
||||||
var UnauthorizedClientException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_UCE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(UnauthorizedClientException, UnauthorizedClientException$1);
|
|
||||||
var UnsupportedGrantTypeException = [
|
|
||||||
-3,
|
|
||||||
n0,
|
|
||||||
_UGTE,
|
|
||||||
{
|
|
||||||
[_e]: _c,
|
|
||||||
[_hE]: 400,
|
|
||||||
},
|
|
||||||
[_e, _ed],
|
|
||||||
[0, 0],
|
|
||||||
];
|
|
||||||
schema.TypeRegistry.for(n0).registerError(UnsupportedGrantTypeException, UnsupportedGrantTypeException$1);
|
|
||||||
var SSOOIDCServiceException = [-3, _sm, "SSOOIDCServiceException", 0, [], []];
|
|
||||||
schema.TypeRegistry.for(_sm).registerError(SSOOIDCServiceException, SSOOIDCServiceException$1);
|
|
||||||
var CreateToken = [
|
|
||||||
9,
|
|
||||||
n0,
|
|
||||||
_CT,
|
|
||||||
{
|
|
||||||
[_h]: ["POST", "/token", 200],
|
|
||||||
},
|
|
||||||
() => CreateTokenRequest,
|
|
||||||
() => CreateTokenResponse,
|
|
||||||
];
|
|
||||||
|
|
||||||
class CreateTokenCommand extends smithyClient.Command
|
|
||||||
.classBuilder()
|
|
||||||
.ep(commonParams)
|
|
||||||
.m(function (Command, cs, config, o) {
|
|
||||||
return [middlewareEndpoint.getEndpointPlugin(config, Command.getEndpointParameterInstructions())];
|
|
||||||
})
|
|
||||||
.s("AWSSSOOIDCService", "CreateToken", {})
|
|
||||||
.n("SSOOIDCClient", "CreateTokenCommand")
|
|
||||||
.sc(CreateToken)
|
|
||||||
.build() {
|
|
||||||
}
|
|
||||||
|
|
||||||
const commands = {
|
|
||||||
CreateTokenCommand,
|
|
||||||
};
|
|
||||||
class SSOOIDC extends SSOOIDCClient {
|
|
||||||
}
|
|
||||||
smithyClient.createAggregatedClient(commands, SSOOIDC);
|
|
||||||
|
|
||||||
__webpack_unused_export__ = ({
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return smithyClient.Command; }
|
|
||||||
});
|
|
||||||
__webpack_unused_export__ = ({
|
|
||||||
enumerable: true,
|
|
||||||
get: function () { return smithyClient.Client; }
|
|
||||||
});
|
|
||||||
__webpack_unused_export__ = AccessDeniedException$1;
|
|
||||||
__webpack_unused_export__ = AccessDeniedExceptionReason;
|
|
||||||
__webpack_unused_export__ = AuthorizationPendingException$1;
|
|
||||||
exports.CreateTokenCommand = CreateTokenCommand;
|
|
||||||
__webpack_unused_export__ = ExpiredTokenException$1;
|
|
||||||
__webpack_unused_export__ = InternalServerException$1;
|
|
||||||
__webpack_unused_export__ = InvalidClientException$1;
|
|
||||||
__webpack_unused_export__ = InvalidGrantException$1;
|
|
||||||
__webpack_unused_export__ = InvalidRequestException$1;
|
|
||||||
__webpack_unused_export__ = InvalidRequestExceptionReason;
|
|
||||||
__webpack_unused_export__ = InvalidScopeException$1;
|
|
||||||
__webpack_unused_export__ = SSOOIDC;
|
|
||||||
exports.SSOOIDCClient = SSOOIDCClient;
|
|
||||||
__webpack_unused_export__ = SSOOIDCServiceException$1;
|
|
||||||
__webpack_unused_export__ = SlowDownException$1;
|
|
||||||
__webpack_unused_export__ = UnauthorizedClientException$1;
|
|
||||||
__webpack_unused_export__ = UnsupportedGrantTypeException$1;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 6901:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getRuntimeConfig = void 0;
|
|
||||||
const tslib_1 = __webpack_require__(1860);
|
|
||||||
const package_json_1 = tslib_1.__importDefault(__webpack_require__(9955));
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const util_user_agent_node_1 = __webpack_require__(1656);
|
|
||||||
const config_resolver_1 = __webpack_require__(9316);
|
|
||||||
const hash_node_1 = __webpack_require__(5092);
|
|
||||||
const middleware_retry_1 = __webpack_require__(9618);
|
|
||||||
const node_config_provider_1 = __webpack_require__(5704);
|
|
||||||
const node_http_handler_1 = __webpack_require__(1279);
|
|
||||||
const util_body_length_node_1 = __webpack_require__(3638);
|
|
||||||
const util_retry_1 = __webpack_require__(5518);
|
|
||||||
const runtimeConfig_shared_1 = __webpack_require__(1546);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const util_defaults_mode_node_1 = __webpack_require__(5435);
|
|
||||||
const smithy_client_2 = __webpack_require__(1411);
|
|
||||||
const getRuntimeConfig = (config) => {
|
|
||||||
(0, smithy_client_2.emitWarningIfUnsupportedVersion)(process.version);
|
|
||||||
const defaultsMode = (0, util_defaults_mode_node_1.resolveDefaultsModeConfig)(config);
|
|
||||||
const defaultConfigProvider = () => defaultsMode().then(smithy_client_1.loadConfigsForDefaultMode);
|
|
||||||
const clientSharedValues = (0, runtimeConfig_shared_1.getRuntimeConfig)(config);
|
|
||||||
(0, core_1.emitWarningIfUnsupportedVersion)(process.version);
|
|
||||||
const loaderConfig = {
|
|
||||||
profile: config?.profile,
|
|
||||||
logger: clientSharedValues.logger,
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
...clientSharedValues,
|
|
||||||
...config,
|
|
||||||
runtime: "node",
|
|
||||||
defaultsMode,
|
|
||||||
authSchemePreference: config?.authSchemePreference ?? (0, node_config_provider_1.loadConfig)(core_1.NODE_AUTH_SCHEME_PREFERENCE_OPTIONS, loaderConfig),
|
|
||||||
bodyLengthChecker: config?.bodyLengthChecker ?? util_body_length_node_1.calculateBodyLength,
|
|
||||||
defaultUserAgentProvider: config?.defaultUserAgentProvider ??
|
|
||||||
(0, util_user_agent_node_1.createDefaultUserAgentProvider)({ serviceId: clientSharedValues.serviceId, clientVersion: package_json_1.default.version }),
|
|
||||||
maxAttempts: config?.maxAttempts ?? (0, node_config_provider_1.loadConfig)(middleware_retry_1.NODE_MAX_ATTEMPT_CONFIG_OPTIONS, config),
|
|
||||||
region: config?.region ??
|
|
||||||
(0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_REGION_CONFIG_OPTIONS, { ...config_resolver_1.NODE_REGION_CONFIG_FILE_OPTIONS, ...loaderConfig }),
|
|
||||||
requestHandler: node_http_handler_1.NodeHttpHandler.create(config?.requestHandler ?? defaultConfigProvider),
|
|
||||||
retryMode: config?.retryMode ??
|
|
||||||
(0, node_config_provider_1.loadConfig)({
|
|
||||||
...middleware_retry_1.NODE_RETRY_MODE_CONFIG_OPTIONS,
|
|
||||||
default: async () => (await defaultConfigProvider()).retryMode || util_retry_1.DEFAULT_RETRY_MODE,
|
|
||||||
}, config),
|
|
||||||
sha256: config?.sha256 ?? hash_node_1.Hash.bind(null, "sha256"),
|
|
||||||
streamCollector: config?.streamCollector ?? node_http_handler_1.streamCollector,
|
|
||||||
useDualstackEndpoint: config?.useDualstackEndpoint ?? (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
useFipsEndpoint: config?.useFipsEndpoint ?? (0, node_config_provider_1.loadConfig)(config_resolver_1.NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
userAgentAppId: config?.userAgentAppId ?? (0, node_config_provider_1.loadConfig)(util_user_agent_node_1.NODE_APP_ID_CONFIG_OPTIONS, loaderConfig),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getRuntimeConfig = getRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 1546:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.getRuntimeConfig = void 0;
|
|
||||||
const core_1 = __webpack_require__(8704);
|
|
||||||
const protocols_1 = __webpack_require__(7288);
|
|
||||||
const core_2 = __webpack_require__(402);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const url_parser_1 = __webpack_require__(4494);
|
|
||||||
const util_base64_1 = __webpack_require__(8385);
|
|
||||||
const util_utf8_1 = __webpack_require__(1577);
|
|
||||||
const httpAuthSchemeProvider_1 = __webpack_require__(8396);
|
|
||||||
const endpointResolver_1 = __webpack_require__(546);
|
|
||||||
const getRuntimeConfig = (config) => {
|
|
||||||
return {
|
|
||||||
apiVersion: "2019-06-10",
|
|
||||||
base64Decoder: config?.base64Decoder ?? util_base64_1.fromBase64,
|
|
||||||
base64Encoder: config?.base64Encoder ?? util_base64_1.toBase64,
|
|
||||||
disableHostPrefix: config?.disableHostPrefix ?? false,
|
|
||||||
endpointProvider: config?.endpointProvider ?? endpointResolver_1.defaultEndpointResolver,
|
|
||||||
extensions: config?.extensions ?? [],
|
|
||||||
httpAuthSchemeProvider: config?.httpAuthSchemeProvider ?? httpAuthSchemeProvider_1.defaultSSOOIDCHttpAuthSchemeProvider,
|
|
||||||
httpAuthSchemes: config?.httpAuthSchemes ?? [
|
|
||||||
{
|
|
||||||
schemeId: "aws.auth#sigv4",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("aws.auth#sigv4"),
|
|
||||||
signer: new core_1.AwsSdkSigV4Signer(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
schemeId: "smithy.api#noAuth",
|
|
||||||
identityProvider: (ipc) => ipc.getIdentityProvider("smithy.api#noAuth") || (async () => ({})),
|
|
||||||
signer: new core_2.NoAuthSigner(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
logger: config?.logger ?? new smithy_client_1.NoOpLogger(),
|
|
||||||
protocol: config?.protocol ?? new protocols_1.AwsRestJsonProtocol({ defaultNamespace: "com.amazonaws.ssooidc" }),
|
|
||||||
serviceId: config?.serviceId ?? "SSO OIDC",
|
|
||||||
urlParser: config?.urlParser ?? url_parser_1.parseUrl,
|
|
||||||
utf8Decoder: config?.utf8Decoder ?? util_utf8_1.fromUtf8,
|
|
||||||
utf8Encoder: config?.utf8Encoder ?? util_utf8_1.toUtf8,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.getRuntimeConfig = getRuntimeConfig;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 9955:
|
|
||||||
/***/ ((module) => {
|
|
||||||
|
|
||||||
module.exports = /*#__PURE__*/JSON.parse('{"name":"@aws-sdk/nested-clients","version":"3.933.0","description":"Nested clients for AWS SDK packages.","main":"./dist-cjs/index.js","module":"./dist-es/index.js","types":"./dist-types/index.d.ts","scripts":{"build":"yarn lint && concurrently \'yarn:build:cjs\' \'yarn:build:es\' \'yarn:build:types\'","build:cjs":"node ../../scripts/compilation/inline nested-clients","build:es":"tsc -p tsconfig.es.json","build:include:deps":"lerna run --scope $npm_package_name --include-dependencies build","build:types":"tsc -p tsconfig.types.json","build:types:downlevel":"downlevel-dts dist-types dist-types/ts3.4","clean":"rimraf ./dist-* && rimraf *.tsbuildinfo","lint":"node ../../scripts/validation/submodules-linter.js --pkg nested-clients","test":"yarn g:vitest run","test:watch":"yarn g:vitest watch"},"engines":{"node":">=18.0.0"},"sideEffects":false,"author":{"name":"AWS SDK for JavaScript Team","url":"https://aws.amazon.com/javascript/"},"license":"Apache-2.0","dependencies":{"@aws-crypto/sha256-browser":"5.2.0","@aws-crypto/sha256-js":"5.2.0","@aws-sdk/core":"3.932.0","@aws-sdk/middleware-host-header":"3.930.0","@aws-sdk/middleware-logger":"3.930.0","@aws-sdk/middleware-recursion-detection":"3.933.0","@aws-sdk/middleware-user-agent":"3.932.0","@aws-sdk/region-config-resolver":"3.930.0","@aws-sdk/types":"3.930.0","@aws-sdk/util-endpoints":"3.930.0","@aws-sdk/util-user-agent-browser":"3.930.0","@aws-sdk/util-user-agent-node":"3.932.0","@smithy/config-resolver":"^4.4.3","@smithy/core":"^3.18.2","@smithy/fetch-http-handler":"^5.3.6","@smithy/hash-node":"^4.2.5","@smithy/invalid-dependency":"^4.2.5","@smithy/middleware-content-length":"^4.2.5","@smithy/middleware-endpoint":"^4.3.9","@smithy/middleware-retry":"^4.4.9","@smithy/middleware-serde":"^4.2.5","@smithy/middleware-stack":"^4.2.5","@smithy/node-config-provider":"^4.3.5","@smithy/node-http-handler":"^4.4.5","@smithy/protocol-http":"^5.3.5","@smithy/smithy-client":"^4.9.5","@smithy/types":"^4.9.0","@smithy/url-parser":"^4.2.5","@smithy/util-base64":"^4.3.0","@smithy/util-body-length-browser":"^4.2.0","@smithy/util-body-length-node":"^4.2.1","@smithy/util-defaults-mode-browser":"^4.3.8","@smithy/util-defaults-mode-node":"^4.2.11","@smithy/util-endpoints":"^3.2.5","@smithy/util-middleware":"^4.2.5","@smithy/util-retry":"^4.2.5","@smithy/util-utf8":"^4.2.0","tslib":"^2.6.2"},"devDependencies":{"concurrently":"7.0.0","downlevel-dts":"0.10.1","rimraf":"3.0.2","typescript":"~5.8.3"},"typesVersions":{"<4.0":{"dist-types/*":["dist-types/ts3.4/*"]}},"files":["./sso-oidc.d.ts","./sso-oidc.js","./sts.d.ts","./sts.js","dist-*/**"],"browser":{"./dist-es/submodules/sso-oidc/runtimeConfig":"./dist-es/submodules/sso-oidc/runtimeConfig.browser","./dist-es/submodules/sts/runtimeConfig":"./dist-es/submodules/sts/runtimeConfig.browser"},"react-native":{},"homepage":"https://github.com/aws/aws-sdk-js-v3/tree/main/packages/nested-clients","repository":{"type":"git","url":"https://github.com/aws/aws-sdk-js-v3.git","directory":"packages/nested-clients"},"exports":{"./sso-oidc":{"types":"./dist-types/submodules/sso-oidc/index.d.ts","module":"./dist-es/submodules/sso-oidc/index.js","node":"./dist-cjs/submodules/sso-oidc/index.js","import":"./dist-es/submodules/sso-oidc/index.js","require":"./dist-cjs/submodules/sso-oidc/index.js"},"./sts":{"types":"./dist-types/submodules/sts/index.d.ts","module":"./dist-es/submodules/sts/index.js","node":"./dist-cjs/submodules/sts/index.js","import":"./dist-es/submodules/sts/index.js","require":"./dist-cjs/submodules/sts/index.js"}}}');
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-387
@@ -1,387 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 566;
|
|
||||||
exports.ids = [566];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 566:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
var __webpack_unused_export__;
|
|
||||||
|
|
||||||
|
|
||||||
var propertyProvider = __webpack_require__(1238);
|
|
||||||
var url = __webpack_require__(7016);
|
|
||||||
var buffer = __webpack_require__(181);
|
|
||||||
var http = __webpack_require__(8611);
|
|
||||||
var nodeConfigProvider = __webpack_require__(5704);
|
|
||||||
var urlParser = __webpack_require__(4494);
|
|
||||||
|
|
||||||
function httpRequest(options) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const req = http.request({
|
|
||||||
method: "GET",
|
|
||||||
...options,
|
|
||||||
hostname: options.hostname?.replace(/^\[(.+)\]$/, "$1"),
|
|
||||||
});
|
|
||||||
req.on("error", (err) => {
|
|
||||||
reject(Object.assign(new propertyProvider.ProviderError("Unable to connect to instance metadata service"), err));
|
|
||||||
req.destroy();
|
|
||||||
});
|
|
||||||
req.on("timeout", () => {
|
|
||||||
reject(new propertyProvider.ProviderError("TimeoutError from instance metadata service"));
|
|
||||||
req.destroy();
|
|
||||||
});
|
|
||||||
req.on("response", (res) => {
|
|
||||||
const { statusCode = 400 } = res;
|
|
||||||
if (statusCode < 200 || 300 <= statusCode) {
|
|
||||||
reject(Object.assign(new propertyProvider.ProviderError("Error response received from instance metadata service"), { statusCode }));
|
|
||||||
req.destroy();
|
|
||||||
}
|
|
||||||
const chunks = [];
|
|
||||||
res.on("data", (chunk) => {
|
|
||||||
chunks.push(chunk);
|
|
||||||
});
|
|
||||||
res.on("end", () => {
|
|
||||||
resolve(buffer.Buffer.concat(chunks));
|
|
||||||
req.destroy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const isImdsCredentials = (arg) => Boolean(arg) &&
|
|
||||||
typeof arg === "object" &&
|
|
||||||
typeof arg.AccessKeyId === "string" &&
|
|
||||||
typeof arg.SecretAccessKey === "string" &&
|
|
||||||
typeof arg.Token === "string" &&
|
|
||||||
typeof arg.Expiration === "string";
|
|
||||||
const fromImdsCredentials = (creds) => ({
|
|
||||||
accessKeyId: creds.AccessKeyId,
|
|
||||||
secretAccessKey: creds.SecretAccessKey,
|
|
||||||
sessionToken: creds.Token,
|
|
||||||
expiration: new Date(creds.Expiration),
|
|
||||||
...(creds.AccountId && { accountId: creds.AccountId }),
|
|
||||||
});
|
|
||||||
|
|
||||||
const DEFAULT_TIMEOUT = 1000;
|
|
||||||
const DEFAULT_MAX_RETRIES = 0;
|
|
||||||
const providerConfigFromInit = ({ maxRetries = DEFAULT_MAX_RETRIES, timeout = DEFAULT_TIMEOUT, }) => ({ maxRetries, timeout });
|
|
||||||
|
|
||||||
const retry = (toRetry, maxRetries) => {
|
|
||||||
let promise = toRetry();
|
|
||||||
for (let i = 0; i < maxRetries; i++) {
|
|
||||||
promise = promise.catch(toRetry);
|
|
||||||
}
|
|
||||||
return promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ENV_CMDS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
|
|
||||||
const ENV_CMDS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
|
|
||||||
const ENV_CMDS_AUTH_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN";
|
|
||||||
const fromContainerMetadata = (init = {}) => {
|
|
||||||
const { timeout, maxRetries } = providerConfigFromInit(init);
|
|
||||||
return () => retry(async () => {
|
|
||||||
const requestOptions = await getCmdsUri({ logger: init.logger });
|
|
||||||
const credsResponse = JSON.parse(await requestFromEcsImds(timeout, requestOptions));
|
|
||||||
if (!isImdsCredentials(credsResponse)) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError("Invalid response received from instance metadata service.", {
|
|
||||||
logger: init.logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return fromImdsCredentials(credsResponse);
|
|
||||||
}, maxRetries);
|
|
||||||
};
|
|
||||||
const requestFromEcsImds = async (timeout, options) => {
|
|
||||||
if (process.env[ENV_CMDS_AUTH_TOKEN]) {
|
|
||||||
options.headers = {
|
|
||||||
...options.headers,
|
|
||||||
Authorization: process.env[ENV_CMDS_AUTH_TOKEN],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const buffer = await httpRequest({
|
|
||||||
...options,
|
|
||||||
timeout,
|
|
||||||
});
|
|
||||||
return buffer.toString();
|
|
||||||
};
|
|
||||||
const CMDS_IP = "169.254.170.2";
|
|
||||||
const GREENGRASS_HOSTS = {
|
|
||||||
localhost: true,
|
|
||||||
"127.0.0.1": true,
|
|
||||||
};
|
|
||||||
const GREENGRASS_PROTOCOLS = {
|
|
||||||
"http:": true,
|
|
||||||
"https:": true,
|
|
||||||
};
|
|
||||||
const getCmdsUri = async ({ logger }) => {
|
|
||||||
if (process.env[ENV_CMDS_RELATIVE_URI]) {
|
|
||||||
return {
|
|
||||||
hostname: CMDS_IP,
|
|
||||||
path: process.env[ENV_CMDS_RELATIVE_URI],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (process.env[ENV_CMDS_FULL_URI]) {
|
|
||||||
const parsed = url.parse(process.env[ENV_CMDS_FULL_URI]);
|
|
||||||
if (!parsed.hostname || !(parsed.hostname in GREENGRASS_HOSTS)) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`${parsed.hostname} is not a valid container metadata service hostname`, {
|
|
||||||
tryNextLink: false,
|
|
||||||
logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!parsed.protocol || !(parsed.protocol in GREENGRASS_PROTOCOLS)) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`${parsed.protocol} is not a valid container metadata service protocol`, {
|
|
||||||
tryNextLink: false,
|
|
||||||
logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...parsed,
|
|
||||||
port: parsed.port ? parseInt(parsed.port, 10) : undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
throw new propertyProvider.CredentialsProviderError("The container metadata credential provider cannot be used unless" +
|
|
||||||
` the ${ENV_CMDS_RELATIVE_URI} or ${ENV_CMDS_FULL_URI} environment` +
|
|
||||||
" variable is set", {
|
|
||||||
tryNextLink: false,
|
|
||||||
logger,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
class InstanceMetadataV1FallbackError extends propertyProvider.CredentialsProviderError {
|
|
||||||
tryNextLink;
|
|
||||||
name = "InstanceMetadataV1FallbackError";
|
|
||||||
constructor(message, tryNextLink = true) {
|
|
||||||
super(message, tryNextLink);
|
|
||||||
this.tryNextLink = tryNextLink;
|
|
||||||
Object.setPrototypeOf(this, InstanceMetadataV1FallbackError.prototype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.yI = void 0;
|
|
||||||
(function (Endpoint) {
|
|
||||||
Endpoint["IPv4"] = "http://169.254.169.254";
|
|
||||||
Endpoint["IPv6"] = "http://[fd00:ec2::254]";
|
|
||||||
})(exports.yI || (exports.yI = {}));
|
|
||||||
|
|
||||||
const ENV_ENDPOINT_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT";
|
|
||||||
const CONFIG_ENDPOINT_NAME = "ec2_metadata_service_endpoint";
|
|
||||||
const ENDPOINT_CONFIG_OPTIONS = {
|
|
||||||
environmentVariableSelector: (env) => env[ENV_ENDPOINT_NAME],
|
|
||||||
configFileSelector: (profile) => profile[CONFIG_ENDPOINT_NAME],
|
|
||||||
default: undefined,
|
|
||||||
};
|
|
||||||
|
|
||||||
var EndpointMode;
|
|
||||||
(function (EndpointMode) {
|
|
||||||
EndpointMode["IPv4"] = "IPv4";
|
|
||||||
EndpointMode["IPv6"] = "IPv6";
|
|
||||||
})(EndpointMode || (EndpointMode = {}));
|
|
||||||
|
|
||||||
const ENV_ENDPOINT_MODE_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE";
|
|
||||||
const CONFIG_ENDPOINT_MODE_NAME = "ec2_metadata_service_endpoint_mode";
|
|
||||||
const ENDPOINT_MODE_CONFIG_OPTIONS = {
|
|
||||||
environmentVariableSelector: (env) => env[ENV_ENDPOINT_MODE_NAME],
|
|
||||||
configFileSelector: (profile) => profile[CONFIG_ENDPOINT_MODE_NAME],
|
|
||||||
default: EndpointMode.IPv4,
|
|
||||||
};
|
|
||||||
|
|
||||||
const getInstanceMetadataEndpoint = async () => urlParser.parseUrl((await getFromEndpointConfig()) || (await getFromEndpointModeConfig()));
|
|
||||||
const getFromEndpointConfig = async () => nodeConfigProvider.loadConfig(ENDPOINT_CONFIG_OPTIONS)();
|
|
||||||
const getFromEndpointModeConfig = async () => {
|
|
||||||
const endpointMode = await nodeConfigProvider.loadConfig(ENDPOINT_MODE_CONFIG_OPTIONS)();
|
|
||||||
switch (endpointMode) {
|
|
||||||
case EndpointMode.IPv4:
|
|
||||||
return exports.yI.IPv4;
|
|
||||||
case EndpointMode.IPv6:
|
|
||||||
return exports.yI.IPv6;
|
|
||||||
default:
|
|
||||||
throw new Error(`Unsupported endpoint mode: ${endpointMode}.` + ` Select from ${Object.values(EndpointMode)}`);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const STATIC_STABILITY_REFRESH_INTERVAL_SECONDS = 5 * 60;
|
|
||||||
const STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS = 5 * 60;
|
|
||||||
const STATIC_STABILITY_DOC_URL = "https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html";
|
|
||||||
const getExtendedInstanceMetadataCredentials = (credentials, logger) => {
|
|
||||||
const refreshInterval = STATIC_STABILITY_REFRESH_INTERVAL_SECONDS +
|
|
||||||
Math.floor(Math.random() * STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS);
|
|
||||||
const newExpiration = new Date(Date.now() + refreshInterval * 1000);
|
|
||||||
logger.warn("Attempting credential expiration extension due to a credential service availability issue. A refresh of these " +
|
|
||||||
`credentials will be attempted after ${new Date(newExpiration)}.\nFor more information, please visit: ` +
|
|
||||||
STATIC_STABILITY_DOC_URL);
|
|
||||||
const originalExpiration = credentials.originalExpiration ?? credentials.expiration;
|
|
||||||
return {
|
|
||||||
...credentials,
|
|
||||||
...(originalExpiration ? { originalExpiration } : {}),
|
|
||||||
expiration: newExpiration,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const staticStabilityProvider = (provider, options = {}) => {
|
|
||||||
const logger = options?.logger || console;
|
|
||||||
let pastCredentials;
|
|
||||||
return async () => {
|
|
||||||
let credentials;
|
|
||||||
try {
|
|
||||||
credentials = await provider();
|
|
||||||
if (credentials.expiration && credentials.expiration.getTime() < Date.now()) {
|
|
||||||
credentials = getExtendedInstanceMetadataCredentials(credentials, logger);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
if (pastCredentials) {
|
|
||||||
logger.warn("Credential renew failed: ", e);
|
|
||||||
credentials = getExtendedInstanceMetadataCredentials(pastCredentials, logger);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pastCredentials = credentials;
|
|
||||||
return credentials;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const IMDS_PATH = "/latest/meta-data/iam/security-credentials/";
|
|
||||||
const IMDS_TOKEN_PATH = "/latest/api/token";
|
|
||||||
const AWS_EC2_METADATA_V1_DISABLED = "AWS_EC2_METADATA_V1_DISABLED";
|
|
||||||
const PROFILE_AWS_EC2_METADATA_V1_DISABLED = "ec2_metadata_v1_disabled";
|
|
||||||
const X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token";
|
|
||||||
const fromInstanceMetadata = (init = {}) => staticStabilityProvider(getInstanceMetadataProvider(init), { logger: init.logger });
|
|
||||||
const getInstanceMetadataProvider = (init = {}) => {
|
|
||||||
let disableFetchToken = false;
|
|
||||||
const { logger, profile } = init;
|
|
||||||
const { timeout, maxRetries } = providerConfigFromInit(init);
|
|
||||||
const getCredentials = async (maxRetries, options) => {
|
|
||||||
const isImdsV1Fallback = disableFetchToken || options.headers?.[X_AWS_EC2_METADATA_TOKEN] == null;
|
|
||||||
if (isImdsV1Fallback) {
|
|
||||||
let fallbackBlockedFromProfile = false;
|
|
||||||
let fallbackBlockedFromProcessEnv = false;
|
|
||||||
const configValue = await nodeConfigProvider.loadConfig({
|
|
||||||
environmentVariableSelector: (env) => {
|
|
||||||
const envValue = env[AWS_EC2_METADATA_V1_DISABLED];
|
|
||||||
fallbackBlockedFromProcessEnv = !!envValue && envValue !== "false";
|
|
||||||
if (envValue === undefined) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`${AWS_EC2_METADATA_V1_DISABLED} not set in env, checking config file next.`, { logger: init.logger });
|
|
||||||
}
|
|
||||||
return fallbackBlockedFromProcessEnv;
|
|
||||||
},
|
|
||||||
configFileSelector: (profile) => {
|
|
||||||
const profileValue = profile[PROFILE_AWS_EC2_METADATA_V1_DISABLED];
|
|
||||||
fallbackBlockedFromProfile = !!profileValue && profileValue !== "false";
|
|
||||||
return fallbackBlockedFromProfile;
|
|
||||||
},
|
|
||||||
default: false,
|
|
||||||
}, {
|
|
||||||
profile,
|
|
||||||
})();
|
|
||||||
if (init.ec2MetadataV1Disabled || configValue) {
|
|
||||||
const causes = [];
|
|
||||||
if (init.ec2MetadataV1Disabled)
|
|
||||||
causes.push("credential provider initialization (runtime option ec2MetadataV1Disabled)");
|
|
||||||
if (fallbackBlockedFromProfile)
|
|
||||||
causes.push(`config file profile (${PROFILE_AWS_EC2_METADATA_V1_DISABLED})`);
|
|
||||||
if (fallbackBlockedFromProcessEnv)
|
|
||||||
causes.push(`process environment variable (${AWS_EC2_METADATA_V1_DISABLED})`);
|
|
||||||
throw new InstanceMetadataV1FallbackError(`AWS EC2 Metadata v1 fallback has been blocked by AWS SDK configuration in the following: [${causes.join(", ")}].`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const imdsProfile = (await retry(async () => {
|
|
||||||
let profile;
|
|
||||||
try {
|
|
||||||
profile = await getProfile(options);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.statusCode === 401) {
|
|
||||||
disableFetchToken = false;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return profile;
|
|
||||||
}, maxRetries)).trim();
|
|
||||||
return retry(async () => {
|
|
||||||
let creds;
|
|
||||||
try {
|
|
||||||
creds = await getCredentialsFromProfile(imdsProfile, options, init);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (err.statusCode === 401) {
|
|
||||||
disableFetchToken = false;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
return creds;
|
|
||||||
}, maxRetries);
|
|
||||||
};
|
|
||||||
return async () => {
|
|
||||||
const endpoint = await getInstanceMetadataEndpoint();
|
|
||||||
if (disableFetchToken) {
|
|
||||||
logger?.debug("AWS SDK Instance Metadata", "using v1 fallback (no token fetch)");
|
|
||||||
return getCredentials(maxRetries, { ...endpoint, timeout });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let token;
|
|
||||||
try {
|
|
||||||
token = (await getMetadataToken({ ...endpoint, timeout })).toString();
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (error?.statusCode === 400) {
|
|
||||||
throw Object.assign(error, {
|
|
||||||
message: "EC2 Metadata token request returned error",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (error.message === "TimeoutError" || [403, 404, 405].includes(error.statusCode)) {
|
|
||||||
disableFetchToken = true;
|
|
||||||
}
|
|
||||||
logger?.debug("AWS SDK Instance Metadata", "using v1 fallback (initial)");
|
|
||||||
return getCredentials(maxRetries, { ...endpoint, timeout });
|
|
||||||
}
|
|
||||||
return getCredentials(maxRetries, {
|
|
||||||
...endpoint,
|
|
||||||
headers: {
|
|
||||||
[X_AWS_EC2_METADATA_TOKEN]: token,
|
|
||||||
},
|
|
||||||
timeout,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const getMetadataToken = async (options) => httpRequest({
|
|
||||||
...options,
|
|
||||||
path: IMDS_TOKEN_PATH,
|
|
||||||
method: "PUT",
|
|
||||||
headers: {
|
|
||||||
"x-aws-ec2-metadata-token-ttl-seconds": "21600",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const getProfile = async (options) => (await httpRequest({ ...options, path: IMDS_PATH })).toString();
|
|
||||||
const getCredentialsFromProfile = async (profile, options, init) => {
|
|
||||||
const credentialsResponse = JSON.parse((await httpRequest({
|
|
||||||
...options,
|
|
||||||
path: IMDS_PATH + profile,
|
|
||||||
})).toString());
|
|
||||||
if (!isImdsCredentials(credentialsResponse)) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError("Invalid response received from instance metadata service.", {
|
|
||||||
logger: init.logger,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return fromImdsCredentials(credentialsResponse);
|
|
||||||
};
|
|
||||||
|
|
||||||
__webpack_unused_export__ = DEFAULT_MAX_RETRIES;
|
|
||||||
__webpack_unused_export__ = DEFAULT_TIMEOUT;
|
|
||||||
__webpack_unused_export__ = ENV_CMDS_AUTH_TOKEN;
|
|
||||||
exports.ENV_CMDS_FULL_URI = ENV_CMDS_FULL_URI;
|
|
||||||
exports.ENV_CMDS_RELATIVE_URI = ENV_CMDS_RELATIVE_URI;
|
|
||||||
exports.fromContainerMetadata = fromContainerMetadata;
|
|
||||||
exports.fromInstanceMetadata = fromInstanceMetadata;
|
|
||||||
exports.getInstanceMetadataEndpoint = getInstanceMetadataEndpoint;
|
|
||||||
exports.httpRequest = httpRequest;
|
|
||||||
__webpack_unused_export__ = providerConfigFromInit;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-266
@@ -1,266 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 579;
|
|
||||||
exports.ids = [579];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 6579:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var utilUtf8 = __webpack_require__(1577);
|
|
||||||
|
|
||||||
class EventStreamSerde {
|
|
||||||
marshaller;
|
|
||||||
serializer;
|
|
||||||
deserializer;
|
|
||||||
serdeContext;
|
|
||||||
defaultContentType;
|
|
||||||
constructor({ marshaller, serializer, deserializer, serdeContext, defaultContentType, }) {
|
|
||||||
this.marshaller = marshaller;
|
|
||||||
this.serializer = serializer;
|
|
||||||
this.deserializer = deserializer;
|
|
||||||
this.serdeContext = serdeContext;
|
|
||||||
this.defaultContentType = defaultContentType;
|
|
||||||
}
|
|
||||||
async serializeEventStream({ eventStream, requestSchema, initialRequest, }) {
|
|
||||||
const marshaller = this.marshaller;
|
|
||||||
const eventStreamMember = requestSchema.getEventStreamMember();
|
|
||||||
const unionSchema = requestSchema.getMemberSchema(eventStreamMember);
|
|
||||||
const serializer = this.serializer;
|
|
||||||
const defaultContentType = this.defaultContentType;
|
|
||||||
const initialRequestMarker = Symbol("initialRequestMarker");
|
|
||||||
const eventStreamIterable = {
|
|
||||||
async *[Symbol.asyncIterator]() {
|
|
||||||
if (initialRequest) {
|
|
||||||
const headers = {
|
|
||||||
":event-type": { type: "string", value: "initial-request" },
|
|
||||||
":message-type": { type: "string", value: "event" },
|
|
||||||
":content-type": { type: "string", value: defaultContentType },
|
|
||||||
};
|
|
||||||
serializer.write(requestSchema, initialRequest);
|
|
||||||
const body = serializer.flush();
|
|
||||||
yield {
|
|
||||||
[initialRequestMarker]: true,
|
|
||||||
headers,
|
|
||||||
body,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
for await (const page of eventStream) {
|
|
||||||
yield page;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
return marshaller.serialize(eventStreamIterable, (event) => {
|
|
||||||
if (event[initialRequestMarker]) {
|
|
||||||
return {
|
|
||||||
headers: event.headers,
|
|
||||||
body: event.body,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const unionMember = Object.keys(event).find((key) => {
|
|
||||||
return key !== "__type";
|
|
||||||
}) ?? "";
|
|
||||||
const { additionalHeaders, body, eventType, explicitPayloadContentType } = this.writeEventBody(unionMember, unionSchema, event);
|
|
||||||
const headers = {
|
|
||||||
":event-type": { type: "string", value: eventType },
|
|
||||||
":message-type": { type: "string", value: "event" },
|
|
||||||
":content-type": { type: "string", value: explicitPayloadContentType ?? defaultContentType },
|
|
||||||
...additionalHeaders,
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
headers,
|
|
||||||
body,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async deserializeEventStream({ response, responseSchema, initialResponseContainer, }) {
|
|
||||||
const marshaller = this.marshaller;
|
|
||||||
const eventStreamMember = responseSchema.getEventStreamMember();
|
|
||||||
const unionSchema = responseSchema.getMemberSchema(eventStreamMember);
|
|
||||||
const memberSchemas = unionSchema.getMemberSchemas();
|
|
||||||
const initialResponseMarker = Symbol("initialResponseMarker");
|
|
||||||
const asyncIterable = marshaller.deserialize(response.body, async (event) => {
|
|
||||||
const unionMember = Object.keys(event).find((key) => {
|
|
||||||
return key !== "__type";
|
|
||||||
}) ?? "";
|
|
||||||
const body = event[unionMember].body;
|
|
||||||
if (unionMember === "initial-response") {
|
|
||||||
const dataObject = await this.deserializer.read(responseSchema, body);
|
|
||||||
delete dataObject[eventStreamMember];
|
|
||||||
return {
|
|
||||||
[initialResponseMarker]: true,
|
|
||||||
...dataObject,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (unionMember in memberSchemas) {
|
|
||||||
const eventStreamSchema = memberSchemas[unionMember];
|
|
||||||
if (eventStreamSchema.isStructSchema()) {
|
|
||||||
const out = {};
|
|
||||||
let hasBindings = false;
|
|
||||||
for (const [name, member] of eventStreamSchema.structIterator()) {
|
|
||||||
const { eventHeader, eventPayload } = member.getMergedTraits();
|
|
||||||
hasBindings = hasBindings || Boolean(eventHeader || eventPayload);
|
|
||||||
if (eventPayload) {
|
|
||||||
if (member.isBlobSchema()) {
|
|
||||||
out[name] = body;
|
|
||||||
}
|
|
||||||
else if (member.isStringSchema()) {
|
|
||||||
out[name] = (this.serdeContext?.utf8Encoder ?? utilUtf8.toUtf8)(body);
|
|
||||||
}
|
|
||||||
else if (member.isStructSchema()) {
|
|
||||||
out[name] = await this.deserializer.read(member, body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (eventHeader) {
|
|
||||||
const value = event[unionMember].headers[name]?.value;
|
|
||||||
if (value != null) {
|
|
||||||
if (member.isNumericSchema()) {
|
|
||||||
if (value && typeof value === "object" && "bytes" in value) {
|
|
||||||
out[name] = BigInt(value.toString());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
out[name] = Number(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
out[name] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasBindings) {
|
|
||||||
return {
|
|
||||||
[unionMember]: out,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
[unionMember]: await this.deserializer.read(eventStreamSchema, body),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return {
|
|
||||||
$unknown: event,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const asyncIterator = asyncIterable[Symbol.asyncIterator]();
|
|
||||||
const firstEvent = await asyncIterator.next();
|
|
||||||
if (firstEvent.done) {
|
|
||||||
return asyncIterable;
|
|
||||||
}
|
|
||||||
if (firstEvent.value?.[initialResponseMarker]) {
|
|
||||||
if (!responseSchema) {
|
|
||||||
throw new Error("@smithy::core/protocols - initial-response event encountered in event stream but no response schema given.");
|
|
||||||
}
|
|
||||||
for (const [key, value] of Object.entries(firstEvent.value)) {
|
|
||||||
initialResponseContainer[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
async *[Symbol.asyncIterator]() {
|
|
||||||
if (!firstEvent?.value?.[initialResponseMarker]) {
|
|
||||||
yield firstEvent.value;
|
|
||||||
}
|
|
||||||
while (true) {
|
|
||||||
const { done, value } = await asyncIterator.next();
|
|
||||||
if (done) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
yield value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
writeEventBody(unionMember, unionSchema, event) {
|
|
||||||
const serializer = this.serializer;
|
|
||||||
let eventType = unionMember;
|
|
||||||
let explicitPayloadMember = null;
|
|
||||||
let explicitPayloadContentType;
|
|
||||||
const isKnownSchema = (() => {
|
|
||||||
const struct = unionSchema.getSchema();
|
|
||||||
return struct[4].includes(unionMember);
|
|
||||||
})();
|
|
||||||
const additionalHeaders = {};
|
|
||||||
if (!isKnownSchema) {
|
|
||||||
const [type, value] = event[unionMember];
|
|
||||||
eventType = type;
|
|
||||||
serializer.write(15, value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const eventSchema = unionSchema.getMemberSchema(unionMember);
|
|
||||||
if (eventSchema.isStructSchema()) {
|
|
||||||
for (const [memberName, memberSchema] of eventSchema.structIterator()) {
|
|
||||||
const { eventHeader, eventPayload } = memberSchema.getMergedTraits();
|
|
||||||
if (eventPayload) {
|
|
||||||
explicitPayloadMember = memberName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (eventHeader) {
|
|
||||||
const value = event[unionMember][memberName];
|
|
||||||
let type = "binary";
|
|
||||||
if (memberSchema.isNumericSchema()) {
|
|
||||||
if ((-2) ** 31 <= value && value <= 2 ** 31 - 1) {
|
|
||||||
type = "integer";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
type = "long";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (memberSchema.isTimestampSchema()) {
|
|
||||||
type = "timestamp";
|
|
||||||
}
|
|
||||||
else if (memberSchema.isStringSchema()) {
|
|
||||||
type = "string";
|
|
||||||
}
|
|
||||||
else if (memberSchema.isBooleanSchema()) {
|
|
||||||
type = "boolean";
|
|
||||||
}
|
|
||||||
if (value != null) {
|
|
||||||
additionalHeaders[memberName] = {
|
|
||||||
type,
|
|
||||||
value,
|
|
||||||
};
|
|
||||||
delete event[unionMember][memberName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (explicitPayloadMember !== null) {
|
|
||||||
const payloadSchema = eventSchema.getMemberSchema(explicitPayloadMember);
|
|
||||||
if (payloadSchema.isBlobSchema()) {
|
|
||||||
explicitPayloadContentType = "application/octet-stream";
|
|
||||||
}
|
|
||||||
else if (payloadSchema.isStringSchema()) {
|
|
||||||
explicitPayloadContentType = "text/plain";
|
|
||||||
}
|
|
||||||
serializer.write(payloadSchema, event[unionMember][explicitPayloadMember]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
serializer.write(eventSchema, event[unionMember]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error("@smithy/core/event-streams - non-struct member not supported in event stream union.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const messageSerialization = serializer.flush();
|
|
||||||
const body = typeof messageSerialization === "string"
|
|
||||||
? (this.serdeContext?.utf8Decoder ?? utilUtf8.fromUtf8)(messageSerialization)
|
|
||||||
: messageSerialization;
|
|
||||||
return {
|
|
||||||
body,
|
|
||||||
eventType,
|
|
||||||
explicitPayloadContentType,
|
|
||||||
additionalHeaders,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.EventStreamSerde = EventStreamSerde;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-234
@@ -1,234 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 605;
|
|
||||||
exports.ids = [605];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 1509:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.checkUrl = void 0;
|
|
||||||
const property_provider_1 = __webpack_require__(1238);
|
|
||||||
const LOOPBACK_CIDR_IPv4 = "127.0.0.0/8";
|
|
||||||
const LOOPBACK_CIDR_IPv6 = "::1/128";
|
|
||||||
const ECS_CONTAINER_HOST = "169.254.170.2";
|
|
||||||
const EKS_CONTAINER_HOST_IPv4 = "169.254.170.23";
|
|
||||||
const EKS_CONTAINER_HOST_IPv6 = "[fd00:ec2::23]";
|
|
||||||
const checkUrl = (url, logger) => {
|
|
||||||
if (url.protocol === "https:") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (url.hostname === ECS_CONTAINER_HOST ||
|
|
||||||
url.hostname === EKS_CONTAINER_HOST_IPv4 ||
|
|
||||||
url.hostname === EKS_CONTAINER_HOST_IPv6) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (url.hostname.includes("[")) {
|
|
||||||
if (url.hostname === "[::1]" || url.hostname === "[0000:0000:0000:0000:0000:0000:0000:0001]") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (url.hostname === "localhost") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const ipComponents = url.hostname.split(".");
|
|
||||||
const inRange = (component) => {
|
|
||||||
const num = parseInt(component, 10);
|
|
||||||
return 0 <= num && num <= 255;
|
|
||||||
};
|
|
||||||
if (ipComponents[0] === "127" &&
|
|
||||||
inRange(ipComponents[1]) &&
|
|
||||||
inRange(ipComponents[2]) &&
|
|
||||||
inRange(ipComponents[3]) &&
|
|
||||||
ipComponents.length === 4) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new property_provider_1.CredentialsProviderError(`URL not accepted. It must either be HTTPS or match one of the following:
|
|
||||||
- loopback CIDR 127.0.0.0/8 or [::1/128]
|
|
||||||
- ECS container host 169.254.170.2
|
|
||||||
- EKS container host 169.254.170.23 or [fd00:ec2::23]`, { logger });
|
|
||||||
};
|
|
||||||
exports.checkUrl = checkUrl;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 8712:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.fromHttp = void 0;
|
|
||||||
const tslib_1 = __webpack_require__(1860);
|
|
||||||
const client_1 = __webpack_require__(5152);
|
|
||||||
const node_http_handler_1 = __webpack_require__(1279);
|
|
||||||
const property_provider_1 = __webpack_require__(1238);
|
|
||||||
const promises_1 = tslib_1.__importDefault(__webpack_require__(1943));
|
|
||||||
const checkUrl_1 = __webpack_require__(1509);
|
|
||||||
const requestHelpers_1 = __webpack_require__(8914);
|
|
||||||
const retry_wrapper_1 = __webpack_require__(1122);
|
|
||||||
const AWS_CONTAINER_CREDENTIALS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI";
|
|
||||||
const DEFAULT_LINK_LOCAL_HOST = "http://169.254.170.2";
|
|
||||||
const AWS_CONTAINER_CREDENTIALS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI";
|
|
||||||
const AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE";
|
|
||||||
const AWS_CONTAINER_AUTHORIZATION_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN";
|
|
||||||
const fromHttp = (options = {}) => {
|
|
||||||
options.logger?.debug("@aws-sdk/credential-provider-http - fromHttp");
|
|
||||||
let host;
|
|
||||||
const relative = options.awsContainerCredentialsRelativeUri ?? process.env[AWS_CONTAINER_CREDENTIALS_RELATIVE_URI];
|
|
||||||
const full = options.awsContainerCredentialsFullUri ?? process.env[AWS_CONTAINER_CREDENTIALS_FULL_URI];
|
|
||||||
const token = options.awsContainerAuthorizationToken ?? process.env[AWS_CONTAINER_AUTHORIZATION_TOKEN];
|
|
||||||
const tokenFile = options.awsContainerAuthorizationTokenFile ?? process.env[AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE];
|
|
||||||
const warn = options.logger?.constructor?.name === "NoOpLogger" || !options.logger?.warn
|
|
||||||
? console.warn
|
|
||||||
: options.logger.warn.bind(options.logger);
|
|
||||||
if (relative && full) {
|
|
||||||
warn("@aws-sdk/credential-provider-http: " +
|
|
||||||
"you have set both awsContainerCredentialsRelativeUri and awsContainerCredentialsFullUri.");
|
|
||||||
warn("awsContainerCredentialsFullUri will take precedence.");
|
|
||||||
}
|
|
||||||
if (token && tokenFile) {
|
|
||||||
warn("@aws-sdk/credential-provider-http: " +
|
|
||||||
"you have set both awsContainerAuthorizationToken and awsContainerAuthorizationTokenFile.");
|
|
||||||
warn("awsContainerAuthorizationToken will take precedence.");
|
|
||||||
}
|
|
||||||
if (full) {
|
|
||||||
host = full;
|
|
||||||
}
|
|
||||||
else if (relative) {
|
|
||||||
host = `${DEFAULT_LINK_LOCAL_HOST}${relative}`;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new property_provider_1.CredentialsProviderError(`No HTTP credential provider host provided.
|
|
||||||
Set AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI.`, { logger: options.logger });
|
|
||||||
}
|
|
||||||
const url = new URL(host);
|
|
||||||
(0, checkUrl_1.checkUrl)(url, options.logger);
|
|
||||||
const requestHandler = node_http_handler_1.NodeHttpHandler.create({
|
|
||||||
requestTimeout: options.timeout ?? 1000,
|
|
||||||
connectionTimeout: options.timeout ?? 1000,
|
|
||||||
});
|
|
||||||
return (0, retry_wrapper_1.retryWrapper)(async () => {
|
|
||||||
const request = (0, requestHelpers_1.createGetRequest)(url);
|
|
||||||
if (token) {
|
|
||||||
request.headers.Authorization = token;
|
|
||||||
}
|
|
||||||
else if (tokenFile) {
|
|
||||||
request.headers.Authorization = (await promises_1.default.readFile(tokenFile)).toString();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const result = await requestHandler.handle(request);
|
|
||||||
return (0, requestHelpers_1.getCredentials)(result.response).then((creds) => (0, client_1.setCredentialFeature)(creds, "CREDENTIALS_HTTP", "z"));
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new property_provider_1.CredentialsProviderError(String(e), { logger: options.logger });
|
|
||||||
}
|
|
||||||
}, options.maxRetries ?? 3, options.timeout ?? 1000);
|
|
||||||
};
|
|
||||||
exports.fromHttp = fromHttp;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 8914:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.createGetRequest = createGetRequest;
|
|
||||||
exports.getCredentials = getCredentials;
|
|
||||||
const property_provider_1 = __webpack_require__(1238);
|
|
||||||
const protocol_http_1 = __webpack_require__(2356);
|
|
||||||
const smithy_client_1 = __webpack_require__(1411);
|
|
||||||
const util_stream_1 = __webpack_require__(4252);
|
|
||||||
function createGetRequest(url) {
|
|
||||||
return new protocol_http_1.HttpRequest({
|
|
||||||
protocol: url.protocol,
|
|
||||||
hostname: url.hostname,
|
|
||||||
port: Number(url.port),
|
|
||||||
path: url.pathname,
|
|
||||||
query: Array.from(url.searchParams.entries()).reduce((acc, [k, v]) => {
|
|
||||||
acc[k] = v;
|
|
||||||
return acc;
|
|
||||||
}, {}),
|
|
||||||
fragment: url.hash,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
async function getCredentials(response, logger) {
|
|
||||||
const stream = (0, util_stream_1.sdkStreamMixin)(response.body);
|
|
||||||
const str = await stream.transformToString();
|
|
||||||
if (response.statusCode === 200) {
|
|
||||||
const parsed = JSON.parse(str);
|
|
||||||
if (typeof parsed.AccessKeyId !== "string" ||
|
|
||||||
typeof parsed.SecretAccessKey !== "string" ||
|
|
||||||
typeof parsed.Token !== "string" ||
|
|
||||||
typeof parsed.Expiration !== "string") {
|
|
||||||
throw new property_provider_1.CredentialsProviderError("HTTP credential provider response not of the required format, an object matching: " +
|
|
||||||
"{ AccessKeyId: string, SecretAccessKey: string, Token: string, Expiration: string(rfc3339) }", { logger });
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
accessKeyId: parsed.AccessKeyId,
|
|
||||||
secretAccessKey: parsed.SecretAccessKey,
|
|
||||||
sessionToken: parsed.Token,
|
|
||||||
expiration: (0, smithy_client_1.parseRfc3339DateTime)(parsed.Expiration),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (response.statusCode >= 400 && response.statusCode < 500) {
|
|
||||||
let parsedBody = {};
|
|
||||||
try {
|
|
||||||
parsedBody = JSON.parse(str);
|
|
||||||
}
|
|
||||||
catch (e) { }
|
|
||||||
throw Object.assign(new property_provider_1.CredentialsProviderError(`Server responded with status: ${response.statusCode}`, { logger }), {
|
|
||||||
Code: parsedBody.Code,
|
|
||||||
Message: parsedBody.Message,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
throw new property_provider_1.CredentialsProviderError(`Server responded with status: ${response.statusCode}`, { logger });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 1122:
|
|
||||||
/***/ ((__unused_webpack_module, exports) => {
|
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
||||||
exports.retryWrapper = void 0;
|
|
||||||
const retryWrapper = (toRetry, maxRetries, delayMs) => {
|
|
||||||
return async () => {
|
|
||||||
for (let i = 0; i < maxRetries; ++i) {
|
|
||||||
try {
|
|
||||||
return await toRetry();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return await toRetry();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
exports.retryWrapper = retryWrapper;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 8605:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
var __webpack_unused_export__;
|
|
||||||
|
|
||||||
__webpack_unused_export__ = ({ value: true });
|
|
||||||
exports.fromHttp = void 0;
|
|
||||||
var fromHttp_1 = __webpack_require__(8712);
|
|
||||||
Object.defineProperty(exports, "fromHttp", ({ enumerable: true, get: function () { return fromHttp_1.fromHttp; } }));
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-225
@@ -1,225 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
exports.id = 869;
|
|
||||||
exports.ids = [869];
|
|
||||||
exports.modules = {
|
|
||||||
|
|
||||||
/***/ 5869:
|
|
||||||
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var sharedIniFileLoader = __webpack_require__(4964);
|
|
||||||
var propertyProvider = __webpack_require__(1238);
|
|
||||||
var client = __webpack_require__(5152);
|
|
||||||
|
|
||||||
const resolveCredentialSource = (credentialSource, profileName, logger) => {
|
|
||||||
const sourceProvidersMap = {
|
|
||||||
EcsContainer: async (options) => {
|
|
||||||
const { fromHttp } = await __webpack_require__.e(/* import() */ 605).then(__webpack_require__.bind(__webpack_require__, 8605));
|
|
||||||
const { fromContainerMetadata } = await __webpack_require__.e(/* import() */ 566).then(__webpack_require__.t.bind(__webpack_require__, 566, 19));
|
|
||||||
logger?.debug("@aws-sdk/credential-provider-ini - credential_source is EcsContainer");
|
|
||||||
return async () => propertyProvider.chain(fromHttp(options ?? {}), fromContainerMetadata(options))().then(setNamedProvider);
|
|
||||||
},
|
|
||||||
Ec2InstanceMetadata: async (options) => {
|
|
||||||
logger?.debug("@aws-sdk/credential-provider-ini - credential_source is Ec2InstanceMetadata");
|
|
||||||
const { fromInstanceMetadata } = await __webpack_require__.e(/* import() */ 566).then(__webpack_require__.t.bind(__webpack_require__, 566, 19));
|
|
||||||
return async () => fromInstanceMetadata(options)().then(setNamedProvider);
|
|
||||||
},
|
|
||||||
Environment: async (options) => {
|
|
||||||
logger?.debug("@aws-sdk/credential-provider-ini - credential_source is Environment");
|
|
||||||
const { fromEnv } = await Promise.resolve(/* import() */).then(__webpack_require__.t.bind(__webpack_require__, 5606, 19));
|
|
||||||
return async () => fromEnv(options)().then(setNamedProvider);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (credentialSource in sourceProvidersMap) {
|
|
||||||
return sourceProvidersMap[credentialSource];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Unsupported credential source in profile ${profileName}. Got ${credentialSource}, ` +
|
|
||||||
`expected EcsContainer or Ec2InstanceMetadata or Environment.`, { logger });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const setNamedProvider = (creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_NAMED_PROVIDER", "p");
|
|
||||||
|
|
||||||
const isAssumeRoleProfile = (arg, { profile = "default", logger } = {}) => {
|
|
||||||
return (Boolean(arg) &&
|
|
||||||
typeof arg === "object" &&
|
|
||||||
typeof arg.role_arn === "string" &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.role_session_name) > -1 &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.external_id) > -1 &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.mfa_serial) > -1 &&
|
|
||||||
(isAssumeRoleWithSourceProfile(arg, { profile, logger }) || isCredentialSourceProfile(arg, { profile, logger })));
|
|
||||||
};
|
|
||||||
const isAssumeRoleWithSourceProfile = (arg, { profile, logger }) => {
|
|
||||||
const withSourceProfile = typeof arg.source_profile === "string" && typeof arg.credential_source === "undefined";
|
|
||||||
if (withSourceProfile) {
|
|
||||||
logger?.debug?.(` ${profile} isAssumeRoleWithSourceProfile source_profile=${arg.source_profile}`);
|
|
||||||
}
|
|
||||||
return withSourceProfile;
|
|
||||||
};
|
|
||||||
const isCredentialSourceProfile = (arg, { profile, logger }) => {
|
|
||||||
const withProviderProfile = typeof arg.credential_source === "string" && typeof arg.source_profile === "undefined";
|
|
||||||
if (withProviderProfile) {
|
|
||||||
logger?.debug?.(` ${profile} isCredentialSourceProfile credential_source=${arg.credential_source}`);
|
|
||||||
}
|
|
||||||
return withProviderProfile;
|
|
||||||
};
|
|
||||||
const resolveAssumeRoleCredentials = async (profileName, profiles, options, visitedProfiles = {}, resolveProfileData) => {
|
|
||||||
options.logger?.debug("@aws-sdk/credential-provider-ini - resolveAssumeRoleCredentials (STS)");
|
|
||||||
const profileData = profiles[profileName];
|
|
||||||
const { source_profile, region } = profileData;
|
|
||||||
if (!options.roleAssumer) {
|
|
||||||
const { getDefaultRoleAssumer } = await __webpack_require__.e(/* import() */ 136).then(__webpack_require__.t.bind(__webpack_require__, 1136, 23));
|
|
||||||
options.roleAssumer = getDefaultRoleAssumer({
|
|
||||||
...options.clientConfig,
|
|
||||||
credentialProviderLogger: options.logger,
|
|
||||||
parentClientConfig: {
|
|
||||||
...options?.parentClientConfig,
|
|
||||||
region: region ?? options?.parentClientConfig?.region,
|
|
||||||
},
|
|
||||||
}, options.clientPlugins);
|
|
||||||
}
|
|
||||||
if (source_profile && source_profile in visitedProfiles) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Detected a cycle attempting to resolve credentials for profile` +
|
|
||||||
` ${sharedIniFileLoader.getProfileName(options)}. Profiles visited: ` +
|
|
||||||
Object.keys(visitedProfiles).join(", "), { logger: options.logger });
|
|
||||||
}
|
|
||||||
options.logger?.debug(`@aws-sdk/credential-provider-ini - finding credential resolver using ${source_profile ? `source_profile=[${source_profile}]` : `profile=[${profileName}]`}`);
|
|
||||||
const sourceCredsProvider = source_profile
|
|
||||||
? resolveProfileData(source_profile, profiles, options, {
|
|
||||||
...visitedProfiles,
|
|
||||||
[source_profile]: true,
|
|
||||||
}, isCredentialSourceWithoutRoleArn(profiles[source_profile] ?? {}))
|
|
||||||
: (await resolveCredentialSource(profileData.credential_source, profileName, options.logger)(options))();
|
|
||||||
if (isCredentialSourceWithoutRoleArn(profileData)) {
|
|
||||||
return sourceCredsProvider.then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const params = {
|
|
||||||
RoleArn: profileData.role_arn,
|
|
||||||
RoleSessionName: profileData.role_session_name || `aws-sdk-js-${Date.now()}`,
|
|
||||||
ExternalId: profileData.external_id,
|
|
||||||
DurationSeconds: parseInt(profileData.duration_seconds || "3600", 10),
|
|
||||||
};
|
|
||||||
const { mfa_serial } = profileData;
|
|
||||||
if (mfa_serial) {
|
|
||||||
if (!options.mfaCodeProvider) {
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Profile ${profileName} requires multi-factor authentication, but no MFA code callback was provided.`, { logger: options.logger, tryNextLink: false });
|
|
||||||
}
|
|
||||||
params.SerialNumber = mfa_serial;
|
|
||||||
params.TokenCode = await options.mfaCodeProvider(mfa_serial);
|
|
||||||
}
|
|
||||||
const sourceCreds = await sourceCredsProvider;
|
|
||||||
return options.roleAssumer(sourceCreds, params).then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const isCredentialSourceWithoutRoleArn = (section) => {
|
|
||||||
return !section.role_arn && !!section.credential_source;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isProcessProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.credential_process === "string";
|
|
||||||
const resolveProcessCredentials = async (options, profile) => __webpack_require__.e(/* import() */ 360).then(__webpack_require__.t.bind(__webpack_require__, 5360, 19)).then(({ fromProcess }) => fromProcess({
|
|
||||||
...options,
|
|
||||||
profile,
|
|
||||||
})().then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_PROCESS", "v")));
|
|
||||||
|
|
||||||
const resolveSsoCredentials = async (profile, profileData, options = {}) => {
|
|
||||||
const { fromSSO } = await __webpack_require__.e(/* import() */ 998).then(__webpack_require__.t.bind(__webpack_require__, 998, 19));
|
|
||||||
return fromSSO({
|
|
||||||
profile,
|
|
||||||
logger: options.logger,
|
|
||||||
parentClientConfig: options.parentClientConfig,
|
|
||||||
clientConfig: options.clientConfig,
|
|
||||||
})().then((creds) => {
|
|
||||||
if (profileData.sso_session) {
|
|
||||||
return client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO", "r");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO_LEGACY", "t");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const isSsoProfile = (arg) => arg &&
|
|
||||||
(typeof arg.sso_start_url === "string" ||
|
|
||||||
typeof arg.sso_account_id === "string" ||
|
|
||||||
typeof arg.sso_session === "string" ||
|
|
||||||
typeof arg.sso_region === "string" ||
|
|
||||||
typeof arg.sso_role_name === "string");
|
|
||||||
|
|
||||||
const isStaticCredsProfile = (arg) => Boolean(arg) &&
|
|
||||||
typeof arg === "object" &&
|
|
||||||
typeof arg.aws_access_key_id === "string" &&
|
|
||||||
typeof arg.aws_secret_access_key === "string" &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.aws_session_token) > -1 &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.aws_account_id) > -1;
|
|
||||||
const resolveStaticCredentials = async (profile, options) => {
|
|
||||||
options?.logger?.debug("@aws-sdk/credential-provider-ini - resolveStaticCredentials");
|
|
||||||
const credentials = {
|
|
||||||
accessKeyId: profile.aws_access_key_id,
|
|
||||||
secretAccessKey: profile.aws_secret_access_key,
|
|
||||||
sessionToken: profile.aws_session_token,
|
|
||||||
...(profile.aws_credential_scope && { credentialScope: profile.aws_credential_scope }),
|
|
||||||
...(profile.aws_account_id && { accountId: profile.aws_account_id }),
|
|
||||||
};
|
|
||||||
return client.setCredentialFeature(credentials, "CREDENTIALS_PROFILE", "n");
|
|
||||||
};
|
|
||||||
|
|
||||||
const isWebIdentityProfile = (arg) => Boolean(arg) &&
|
|
||||||
typeof arg === "object" &&
|
|
||||||
typeof arg.web_identity_token_file === "string" &&
|
|
||||||
typeof arg.role_arn === "string" &&
|
|
||||||
["undefined", "string"].indexOf(typeof arg.role_session_name) > -1;
|
|
||||||
const resolveWebIdentityCredentials = async (profile, options) => __webpack_require__.e(/* import() */ 956).then(__webpack_require__.t.bind(__webpack_require__, 9956, 23)).then(({ fromTokenFile }) => fromTokenFile({
|
|
||||||
webIdentityTokenFile: profile.web_identity_token_file,
|
|
||||||
roleArn: profile.role_arn,
|
|
||||||
roleSessionName: profile.role_session_name,
|
|
||||||
roleAssumerWithWebIdentity: options.roleAssumerWithWebIdentity,
|
|
||||||
logger: options.logger,
|
|
||||||
parentClientConfig: options.parentClientConfig,
|
|
||||||
})().then((creds) => client.setCredentialFeature(creds, "CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN", "q")));
|
|
||||||
|
|
||||||
const resolveProfileData = async (profileName, profiles, options, visitedProfiles = {}, isAssumeRoleRecursiveCall = false) => {
|
|
||||||
const data = profiles[profileName];
|
|
||||||
if (Object.keys(visitedProfiles).length > 0 && isStaticCredsProfile(data)) {
|
|
||||||
return resolveStaticCredentials(data, options);
|
|
||||||
}
|
|
||||||
if (isAssumeRoleRecursiveCall || isAssumeRoleProfile(data, { profile: profileName, logger: options.logger })) {
|
|
||||||
return resolveAssumeRoleCredentials(profileName, profiles, options, visitedProfiles, resolveProfileData);
|
|
||||||
}
|
|
||||||
if (isStaticCredsProfile(data)) {
|
|
||||||
return resolveStaticCredentials(data, options);
|
|
||||||
}
|
|
||||||
if (isWebIdentityProfile(data)) {
|
|
||||||
return resolveWebIdentityCredentials(data, options);
|
|
||||||
}
|
|
||||||
if (isProcessProfile(data)) {
|
|
||||||
return resolveProcessCredentials(options, profileName);
|
|
||||||
}
|
|
||||||
if (isSsoProfile(data)) {
|
|
||||||
return await resolveSsoCredentials(profileName, data, options);
|
|
||||||
}
|
|
||||||
throw new propertyProvider.CredentialsProviderError(`Could not resolve credentials using profile: [${profileName}] in configuration/credentials file(s).`, { logger: options.logger });
|
|
||||||
};
|
|
||||||
|
|
||||||
const fromIni = (_init = {}) => async ({ callerClientConfig } = {}) => {
|
|
||||||
const init = {
|
|
||||||
..._init,
|
|
||||||
parentClientConfig: {
|
|
||||||
...callerClientConfig,
|
|
||||||
..._init.parentClientConfig,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
init.logger?.debug("@aws-sdk/credential-provider-ini - fromIni");
|
|
||||||
const profiles = await sharedIniFileLoader.parseKnownFiles(init);
|
|
||||||
return resolveProfileData(sharedIniFileLoader.getProfileName({
|
|
||||||
profile: _init.profile ?? callerClientConfig?.profile,
|
|
||||||
}), profiles, init);
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.fromIni = fromIni;
|
|
||||||
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
|
|
||||||
};
|
|
||||||
;
|
|
||||||
-1039
File diff suppressed because it is too large
Load Diff
-1455
File diff suppressed because it is too large
Load Diff
+18986
-44796
File diff suppressed because one or more lines are too long
+70248
-74689
File diff suppressed because one or more lines are too long
+7
-2
@@ -2,8 +2,13 @@
|
|||||||
|
|
||||||
## [federated-setup](./federated-setup/README.md)
|
## [federated-setup](./federated-setup/README.md)
|
||||||
|
|
||||||
The directory contains templates for setting up the `configure-aws-credentials` federation between your GitHub Organization/repository and your AWS account.
|
The directory contains templates for setting up the `configure-aws-credentials`
|
||||||
|
federation between your GitHub Organization/repository and your AWS account.
|
||||||
|
|
||||||
## [cfn-deploy-example](./cfn-deploy-example/README.md)
|
## [cfn-deploy-example](./cfn-deploy-example/README.md)
|
||||||
|
|
||||||
Repository example uses aws-action `configure-aws-credentials` with OIDC federation template [github-actions-oidc-federation-and-role](./github-actions-oidc-federation-and-role.yml). Example demonstrates a repository that deploys AWS CloudFormation template using cfn-deploy GitHub Action.
|
Repository example uses aws-action `configure-aws-credentials` with OIDC
|
||||||
|
federation template
|
||||||
|
[github-actions-oidc-federation-and-role](./github-actions-oidc-federation-and-role.yml).
|
||||||
|
Example demonstrates a repository that deploys AWS CloudFormation template using
|
||||||
|
cfn-deploy GitHub Action.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
- name: Configure AWS Credentials
|
- name: Configure AWS Credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v5
|
uses: aws-actions/configure-aws-credentials@v6
|
||||||
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
|
||||||
|
|||||||
@@ -1,13 +1,23 @@
|
|||||||
# cfn-deploy example
|
# cfn-deploy example
|
||||||
|
|
||||||
Example uses aws-action `configure-aws-credentials` with OIDC federation. Prior to using this example project, the user needs to deploy the [github-actions-oidc-federation-and-role](../federated-setup/github-actions-oidc-federation-and-role.yml) template in the AWS account they want to deploy the CloudFormation template into. Specify the GitHub Organization name, repository name, and the specific branch you want to deploy on.
|
Example uses aws-action `configure-aws-credentials` with OIDC federation. Prior
|
||||||
|
to using this example project, the user needs to deploy the
|
||||||
|
[github-actions-oidc-federation-and-role](../federated-setup/github-actions-oidc-federation-and-role.yml)
|
||||||
|
template in the AWS account they want to deploy the CloudFormation template
|
||||||
|
into. Specify the GitHub Organization name, repository name, and the specific
|
||||||
|
branch you want to deploy on.
|
||||||
|
|
||||||
Within the [github/workflows](./.github/workflows/) directory there is a [compliance.yml](./.github/workflows/compliance.yml) and a [deploy.yml](./.github/workflows/deploy.yml). The deploy.yml file leverages the aws-action `configure-aws-credentials` and accesses GitHub Action Secrets for some of the variables. The compliance.yml runs static application security testing using cfn-guard.
|
Within the [github/workflows](./.github/workflows/) directory there is a
|
||||||
|
[compliance.yml](./.github/workflows/compliance.yml) and a
|
||||||
|
[deploy.yml](./.github/workflows/deploy.yml). The deploy.yml file leverages the
|
||||||
|
aws-action `configure-aws-credentials` and accesses GitHub Action Secrets for
|
||||||
|
some of the variables. The compliance.yml runs static application security
|
||||||
|
testing using cfn-guard.
|
||||||
|
|
||||||
To use the example you will need to set the following GitHub Action Secrets:
|
To use the example you will need to set the following GitHub Action Secrets:
|
||||||
|
|
||||||
| Secret Key | Used With | Description |
|
| Secret Key | Used With | Description |
|
||||||
| --------- | -------- | -----------|
|
| --------------- | -------------------------------- | ---------------------------------------- |
|
||||||
| AWS_ACCOUNT_ID | configure-aws-credentials | The AWS account ID |
|
| AWS_ACCOUNT_ID | configure-aws-credentials | The AWS account ID |
|
||||||
| AWS_DEPLOY_ROLE | configure-aws-credentials | The name of the IAM role |
|
| AWS_DEPLOY_ROLE | configure-aws-credentials | The name of the IAM role |
|
||||||
| VPC_ID | aws-cloudformation-github-deploy | VPC ID the EC2 Bastion is deployed to |
|
| VPC_ID | aws-cloudformation-github-deploy | VPC ID the EC2 Bastion is deployed to |
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
## [github-action-oidc-federation](./github-actions-oidc-federation.yml)
|
## [github-action-oidc-federation](./github-actions-oidc-federation.yml)
|
||||||
|
|
||||||
Setup of the OIDC federation between your GitHub Organization/repository and your AWS account.
|
Setup of the OIDC federation between your GitHub Organization/repository and
|
||||||
|
your AWS account.
|
||||||
|
|
||||||
## [github-actions-oidc-federation-and-role](./github-actions-oidc-federation-and-role.yml)
|
## [github-actions-oidc-federation-and-role](./github-actions-oidc-federation-and-role.yml)
|
||||||
|
|
||||||
Setup of the OIDC federation between your GitHub Organization/repository and your AWS account along with a role that only executes on specific branch.
|
Setup of the OIDC federation between your GitHub Organization/repository and
|
||||||
|
your AWS account along with a role that only executes on specific branch.
|
||||||
|
|||||||
Generated
+5031
-3934
File diff suppressed because it is too large
Load Diff
+22
-21
@@ -1,14 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "configure-aws-credentials",
|
"name": "configure-aws-credentials",
|
||||||
"description": "A GitHub Action to configure AWS credentials",
|
"description": "A GitHub Action to configure AWS credentials",
|
||||||
"version": "5.1.1",
|
"version": "6.2.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"lint": "biome check --error-on-warnings ./src",
|
"lint": "biome check --error-on-warnings ./src ./test && markdownlint -i node_modules -i CHANGELOG.md '**/*.md'",
|
||||||
"lint:fix": "biome check --write ./src",
|
"lint:fix": "biome check --write ./src ./test && markdownlint -i node_modules -i CHANGELOG.md -f '**/*.md'",
|
||||||
"package": "npm run build && ncc build --license THIRD-PARTY -o dist && ncc build src/cleanup/index.ts -o dist/cleanup && cpy dist/THIRD-PARTY . && del-cli dist/THIRD-PARTY",
|
"package": "esbuild src/index.ts --bundle --platform=node --target=node24 --outfile=dist/index.js && esbuild src/cleanup/index.ts --bundle --platform=node --target=node24 --outfile=dist/cleanup/index.js && npm run license",
|
||||||
"test": "npm run lint && vitest run && npm run build",
|
"test": "npm run lint && vitest run && npm run build",
|
||||||
"clean": "del-cli coverage test-reports node_modules"
|
"clean": "del-cli coverage test-reports node_modules",
|
||||||
|
"license": "generate-license-file --config ./.generatelicensefile.json"
|
||||||
},
|
},
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Amazon.com, Inc. or its affiliates",
|
"name": "Amazon.com, Inc. or its affiliates",
|
||||||
@@ -16,26 +17,26 @@
|
|||||||
"organization": true
|
"organization": true
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@aws-sdk/credential-provider-env": "^3.928.0",
|
"@aws-sdk/credential-provider-env": "^3.972.57",
|
||||||
"@biomejs/biome": "2.3.6",
|
"@biomejs/biome": "2.5.3",
|
||||||
"@smithy/property-provider": "^4.2.5",
|
"@smithy/property-provider": "^4.4.8",
|
||||||
"@types/node": "^24.10.1",
|
"@types/node": "^26.1.1",
|
||||||
"@vercel/ncc": "^0.38.4",
|
"@vitest/coverage-v8": "4.1.10",
|
||||||
"@vitest/coverage-v8": "^3.2.4",
|
|
||||||
"aws-sdk-client-mock": "^4.1.0",
|
"aws-sdk-client-mock": "^4.1.0",
|
||||||
"cpy-cli": "^6.0.0",
|
"esbuild": "^0.28.1",
|
||||||
"del-cli": "^7.0.0",
|
"generate-license-file": "^4.2.1",
|
||||||
"json-schema": "^0.4.0",
|
"json-schema": "^0.4.0",
|
||||||
"memfs": "^4.51.0",
|
"markdownlint-cli": "^0.49.0",
|
||||||
|
"memfs": "^4.64.0",
|
||||||
"standard-version": "^9.5.0",
|
"standard-version": "^9.5.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^7.0.2",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "4.1.10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^3.0.1",
|
||||||
"@aws-sdk/client-sts": "^3.933.0",
|
"@aws-sdk/client-sts": "^3.1086.0",
|
||||||
"@smithy/node-http-handler": "^4.4.5",
|
"@smithy/node-http-handler": "^4.9.5",
|
||||||
"proxy-agent": "^6.5.0"
|
"proxy-agent": "^8.0.2"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"aws",
|
"aws",
|
||||||
@@ -43,7 +44,7 @@
|
|||||||
"github-action"
|
"github-action"
|
||||||
],
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 14.0.0"
|
"node": ">= 16.3.0"
|
||||||
},
|
},
|
||||||
"main": "build/index.js",
|
"main": "build/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
+44
-35
@@ -3,21 +3,27 @@ import { STSClient } from '@aws-sdk/client-sts';
|
|||||||
import type { AwsCredentialIdentity } from '@aws-sdk/types';
|
import type { AwsCredentialIdentity } from '@aws-sdk/types';
|
||||||
import { NodeHttpHandler } from '@smithy/node-http-handler';
|
import { NodeHttpHandler } from '@smithy/node-http-handler';
|
||||||
import { ProxyAgent } from 'proxy-agent';
|
import { ProxyAgent } from 'proxy-agent';
|
||||||
import { errorMessage, getCallerIdentity } from './helpers';
|
import { buildCustomUserAgent, errorMessage, getCallerIdentity } from './helpers';
|
||||||
import { ProxyResolver } from './ProxyResolver';
|
import { ProxyResolver } from './ProxyResolver';
|
||||||
|
|
||||||
const USER_AGENT = 'configure-aws-credentials-for-github-actions';
|
if (!process.env.AWS_EXECUTION_ENV) {
|
||||||
|
process.env.AWS_EXECUTION_ENV = 'GitHubActions';
|
||||||
|
}
|
||||||
|
|
||||||
export interface CredentialsClientProps {
|
export interface CredentialsClientProps {
|
||||||
region?: string;
|
region?: string;
|
||||||
proxyServer?: string;
|
proxyServer?: string;
|
||||||
noProxy?: string;
|
noProxy?: string;
|
||||||
|
stsEndpoint?: string;
|
||||||
|
roleChaining: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CredentialsClient {
|
export class CredentialsClient {
|
||||||
public region?: string;
|
public region?: string;
|
||||||
private _stsClient?: STSClient;
|
private _stsClient?: STSClient;
|
||||||
private readonly requestHandler?: NodeHttpHandler;
|
private readonly requestHandler?: NodeHttpHandler;
|
||||||
|
private readonly stsEndpoint?: string;
|
||||||
|
private roleChaining?: boolean;
|
||||||
|
|
||||||
constructor(props: CredentialsClientProps) {
|
constructor(props: CredentialsClientProps) {
|
||||||
if (props.region !== undefined) {
|
if (props.region !== undefined) {
|
||||||
@@ -39,60 +45,63 @@ export class CredentialsClient {
|
|||||||
httpAgent: handler,
|
httpAgent: handler,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (props.stsEndpoint) {
|
||||||
|
this.stsEndpoint = props.stsEndpoint;
|
||||||
|
}
|
||||||
|
this.roleChaining = props.roleChaining;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get stsClient(): STSClient {
|
public get stsClient(): STSClient {
|
||||||
if (!this._stsClient) {
|
if (!this._stsClient || this.roleChaining) {
|
||||||
const config = { customUserAgent: USER_AGENT } as {
|
this._stsClient = this.createStsClient();
|
||||||
customUserAgent: string;
|
|
||||||
region?: string;
|
|
||||||
requestHandler?: NodeHttpHandler;
|
|
||||||
};
|
|
||||||
if (this.region !== undefined) config.region = this.region;
|
|
||||||
if (this.requestHandler !== undefined) config.requestHandler = this.requestHandler;
|
|
||||||
this._stsClient = new STSClient(config);
|
|
||||||
}
|
}
|
||||||
return this._stsClient;
|
return this._stsClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Builds an STS client using the action's configured region/endpoint/proxy. When explicit credentials are provided,
|
||||||
|
// the client uses them directly instead of the SDK default credential provider chain.
|
||||||
|
// This matters for validateAccountId.
|
||||||
|
private createStsClient(credentials?: AwsCredentialIdentity): STSClient {
|
||||||
|
return new STSClient({
|
||||||
|
customUserAgent: buildCustomUserAgent(),
|
||||||
|
...(this.region !== undefined && { region: this.region }),
|
||||||
|
...(this.stsEndpoint !== undefined && { endpoint: this.stsEndpoint }),
|
||||||
|
...(this.requestHandler !== undefined && { requestHandler: this.requestHandler }),
|
||||||
|
...(credentials !== undefined && { credentials }),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validates that the credentials the action will hand to subsequent steps actually work, and returns the resolved
|
||||||
|
// caller identity (account + ARN). "Work" is proven by a sts:GetCallerIdentity call, which both confirms the
|
||||||
|
// credentials are accepted by AWS and returns the identity for later checks and outputs to use.
|
||||||
public async validateCredentials(
|
public async validateCredentials(
|
||||||
|
credentials?: AwsCredentialIdentity,
|
||||||
expectedAccessKeyId?: string,
|
expectedAccessKeyId?: string,
|
||||||
roleChaining?: boolean,
|
roleChaining?: boolean,
|
||||||
expectedAccountIds?: string[],
|
): Promise<Awaited<ReturnType<typeof getCallerIdentity>>> {
|
||||||
) {
|
if (!credentials) {
|
||||||
let credentials: AwsCredentialIdentity;
|
let resolved: AwsCredentialIdentity;
|
||||||
try {
|
try {
|
||||||
credentials = await this.loadCredentials();
|
resolved = await this.loadCredentials();
|
||||||
if (!credentials.accessKeyId) {
|
if (!resolved.accessKeyId) {
|
||||||
throw new Error('Access key ID empty after loading credentials');
|
throw new Error('Access key ID empty after loading credentials');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`Credentials could not be loaded, please check your action inputs: ${errorMessage(error)}`);
|
throw new Error(`Credentials could not be loaded, please check your action inputs: ${errorMessage(error)}`);
|
||||||
}
|
}
|
||||||
if (expectedAccountIds && expectedAccountIds.length > 0 && expectedAccountIds[0] !== '') {
|
if (!roleChaining && expectedAccessKeyId && expectedAccessKeyId !== resolved.accessKeyId) {
|
||||||
let callerIdentity: Awaited<ReturnType<typeof getCallerIdentity>>;
|
|
||||||
try {
|
|
||||||
callerIdentity = await getCallerIdentity(this.stsClient);
|
|
||||||
} catch (error) {
|
|
||||||
throw new Error(`Could not validate account ID of credentials: ${errorMessage(error)}`);
|
|
||||||
}
|
|
||||||
if (!callerIdentity.Account || !expectedAccountIds.includes(callerIdentity.Account)) {
|
|
||||||
throw new Error(
|
|
||||||
`The account ID of the provided credentials (${
|
|
||||||
callerIdentity.Account ?? 'unknown'
|
|
||||||
}) does not match any of the expected account IDs: ${expectedAccountIds.join(', ')}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roleChaining) {
|
|
||||||
const actualAccessKeyId = credentials.accessKeyId;
|
|
||||||
if (expectedAccessKeyId && expectedAccessKeyId !== actualAccessKeyId) {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Credentials loaded by the SDK do not match the expected access key ID configured by the action',
|
'Credentials loaded by the SDK do not match the expected access key ID configured by the action',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const client = credentials ? this.createStsClient(credentials) : this.stsClient;
|
||||||
|
try {
|
||||||
|
return await getCallerIdentity(client);
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Credentials could not be loaded, please check your action inputs: ${errorMessage(error)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadCredentials() {
|
private async loadCredentials() {
|
||||||
|
|||||||
+140
-20
@@ -1,14 +1,18 @@
|
|||||||
import assert from 'node:assert';
|
import assert from 'node:assert';
|
||||||
import fs from 'node:fs';
|
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import type { AssumeRoleCommandInput, STSClient, Tag } from '@aws-sdk/client-sts';
|
import type { AssumeRoleCommandInput, STSClient, Tag } from '@aws-sdk/client-sts';
|
||||||
import { AssumeRoleCommand, AssumeRoleWithWebIdentityCommand } from '@aws-sdk/client-sts';
|
import {
|
||||||
|
AssumeRoleCommand,
|
||||||
|
AssumeRoleWithWebIdentityCommand,
|
||||||
|
PackedPolicyTooLargeException,
|
||||||
|
} from '@aws-sdk/client-sts';
|
||||||
import type { CredentialsClient } from './CredentialsClient';
|
import type { CredentialsClient } from './CredentialsClient';
|
||||||
import { errorMessage, isDefined, sanitizeGitHubVariables } from './helpers';
|
import { errorMessage, isDefined, readFileUtf8, sanitizeGitHubVariables } from './helpers';
|
||||||
|
|
||||||
async function assumeRoleWithOIDC(params: AssumeRoleCommandInput, client: STSClient, webIdentityToken: string) {
|
async function assumeRoleWithOIDC(params: AssumeRoleCommandInput, client: STSClient, webIdentityToken: string) {
|
||||||
delete params.Tags;
|
delete params.Tags;
|
||||||
|
delete params.TransitiveTagKeys;
|
||||||
core.info('Assuming role with OIDC');
|
core.info('Assuming role with OIDC');
|
||||||
try {
|
try {
|
||||||
const creds = await client.send(
|
const creds = await client.send(
|
||||||
@@ -35,13 +39,14 @@ async function assumeRoleWithWebIdentityTokenFile(
|
|||||||
const webIdentityTokenFilePath = path.isAbsolute(webIdentityTokenFile)
|
const webIdentityTokenFilePath = path.isAbsolute(webIdentityTokenFile)
|
||||||
? webIdentityTokenFile
|
? webIdentityTokenFile
|
||||||
: path.join(workspace, webIdentityTokenFile);
|
: path.join(workspace, webIdentityTokenFile);
|
||||||
if (!fs.existsSync(webIdentityTokenFilePath)) {
|
const webIdentityToken = readFileUtf8(webIdentityTokenFilePath);
|
||||||
|
if (webIdentityToken === null) {
|
||||||
throw new Error(`Web identity token file does not exist: ${webIdentityTokenFilePath}`);
|
throw new Error(`Web identity token file does not exist: ${webIdentityTokenFilePath}`);
|
||||||
}
|
}
|
||||||
core.info('Assuming role with web identity token file');
|
core.info('Assuming role with web identity token file');
|
||||||
try {
|
try {
|
||||||
const webIdentityToken = fs.readFileSync(webIdentityTokenFilePath, 'utf8');
|
|
||||||
delete params.Tags;
|
delete params.Tags;
|
||||||
|
delete params.TransitiveTagKeys;
|
||||||
const creds = await client.send(
|
const creds = await client.send(
|
||||||
new AssumeRoleWithWebIdentityCommand({
|
new AssumeRoleWithWebIdentityCommand({
|
||||||
...params,
|
...params,
|
||||||
@@ -60,6 +65,13 @@ async function assumeRoleWithCredentials(params: AssumeRoleCommandInput, client:
|
|||||||
const creds = await client.send(new AssumeRoleCommand({ ...params }));
|
const creds = await client.send(new AssumeRoleCommand({ ...params }));
|
||||||
return creds;
|
return creds;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error instanceof PackedPolicyTooLargeException) {
|
||||||
|
core.info('Session tag size is too large; dropping droppable tags and retrying.');
|
||||||
|
const droppableKeys = new Set(DROPPABLE_TAG_SOURCES.map((s) => s.key));
|
||||||
|
params.Tags = params.Tags?.filter((tag) => !droppableKeys.has(tag.Key ?? ''));
|
||||||
|
const creds = await client.send(new AssumeRoleCommand({ ...params }));
|
||||||
|
return creds;
|
||||||
|
}
|
||||||
throw new Error(`Could not assume role with user credentials: ${errorMessage(error)}`);
|
throw new Error(`Could not assume role with user credentials: ${errorMessage(error)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,12 +82,106 @@ export interface assumeRoleParams {
|
|||||||
roleDuration: number;
|
roleDuration: number;
|
||||||
roleSessionName: string;
|
roleSessionName: string;
|
||||||
roleSkipSessionTagging?: boolean;
|
roleSkipSessionTagging?: boolean;
|
||||||
|
transitiveTagKeys?: string[];
|
||||||
sourceAccountId?: string;
|
sourceAccountId?: string;
|
||||||
roleExternalId?: string;
|
roleExternalId?: string;
|
||||||
webIdentityTokenFile?: string;
|
webIdentityTokenFile?: string;
|
||||||
webIdentityToken?: string;
|
webIdentityToken?: string;
|
||||||
inlineSessionPolicy?: string;
|
inlineSessionPolicy?: string;
|
||||||
managedSessionPolicies?: { arn: string }[];
|
managedSessionPolicies?: { arn: string }[];
|
||||||
|
customTags?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TAG_KEY_REGEX = /^[\p{L}\p{Z}\p{N}_.:/=+\-@]+$/u;
|
||||||
|
const TAG_VALUE_REGEX = /^[\p{L}\p{Z}\p{N}_.:/=+\-@]*$/u;
|
||||||
|
const MAX_TAG_KEY_LENGTH = 128;
|
||||||
|
const MAX_TAG_VALUE_LENGTH = 256;
|
||||||
|
const MAX_SESSION_TAGS = 50;
|
||||||
|
|
||||||
|
// Identity/audit primitives. Always emitted and cannot be dropped.
|
||||||
|
const NON_DROPPABLE_TAG_SOURCES: ReadonlyArray<{ key: string; envVar: string }> = [
|
||||||
|
{ key: 'Repository', envVar: 'GITHUB_REPOSITORY' },
|
||||||
|
{ key: 'Workflow', envVar: 'GITHUB_WORKFLOW' },
|
||||||
|
{ key: 'Action', envVar: 'GITHUB_ACTION' },
|
||||||
|
{ key: 'Actor', envVar: 'GITHUB_ACTOR' },
|
||||||
|
{ key: 'Commit', envVar: 'GITHUB_SHA' },
|
||||||
|
{ key: 'Branch', envVar: 'GITHUB_REF' },
|
||||||
|
];
|
||||||
|
|
||||||
|
// Convenience metadata. If the AssumeRole call fails due to compressed size of
|
||||||
|
// session tags being too large, we will drop these tags and retry once.
|
||||||
|
const DROPPABLE_TAG_SOURCES: ReadonlyArray<{ key: string; envVar: string }> = [
|
||||||
|
{ key: 'EventName', envVar: 'GITHUB_EVENT_NAME' },
|
||||||
|
{ key: 'BaseRef', envVar: 'GITHUB_BASE_REF' },
|
||||||
|
{ key: 'HeadRef', envVar: 'GITHUB_HEAD_REF' },
|
||||||
|
{ key: 'RunId', envVar: 'GITHUB_RUN_ID' },
|
||||||
|
{ key: 'Job', envVar: 'GITHUB_JOB' },
|
||||||
|
{ key: 'TriggeringActor', envVar: 'GITHUB_TRIGGERING_ACTOR' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const PROTECTED_TAG_KEYS = new Set<string>([
|
||||||
|
'GitHub',
|
||||||
|
...NON_DROPPABLE_TAG_SOURCES.map((s) => s.key),
|
||||||
|
...DROPPABLE_TAG_SOURCES.map((s) => s.key),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export function parseAndValidateCustomTags(customTags: string, existingTags: Tag[]): Tag[] {
|
||||||
|
let parsed: unknown;
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(customTags);
|
||||||
|
} catch {
|
||||||
|
throw new Error('custom-tags: input is not valid JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
||||||
|
throw new Error('custom-tags: input must be a JSON object (not an array or primitive)');
|
||||||
|
}
|
||||||
|
|
||||||
|
const newTags: Tag[] = [];
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(parsed)) {
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
throw new Error(
|
||||||
|
`custom-tags: value for key '${key}' must be a string, number, or boolean (not an object or array)`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const stringValue = String(value);
|
||||||
|
|
||||||
|
if (key.length === 0 || key.length > MAX_TAG_KEY_LENGTH) {
|
||||||
|
throw new Error(`custom-tags: key '${key}' must be between 1 and ${MAX_TAG_KEY_LENGTH} characters`);
|
||||||
|
}
|
||||||
|
if (stringValue.length > MAX_TAG_VALUE_LENGTH) {
|
||||||
|
throw new Error(
|
||||||
|
`custom-tags: value for key '${key}' exceeds maximum length of ${MAX_TAG_VALUE_LENGTH} characters`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!TAG_KEY_REGEX.test(key)) {
|
||||||
|
throw new Error(
|
||||||
|
`custom-tags: key '${key}' contains invalid characters. Allowed: unicode letters, digits, spaces, and _.:/=+-@`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (stringValue.length > 0 && !TAG_VALUE_REGEX.test(stringValue)) {
|
||||||
|
throw new Error(
|
||||||
|
`custom-tags: value for key '${key}' contains invalid characters. Allowed: unicode letters, digits, spaces, and _.:/=+-@`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (PROTECTED_TAG_KEYS.has(key)) {
|
||||||
|
throw new Error(
|
||||||
|
`custom-tags: key '${key}' conflicts with a protected session tag set by this action and cannot be overridden`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
newTags.push({ Key: key, Value: stringValue });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingTags.length + newTags.length > MAX_SESSION_TAGS) {
|
||||||
|
throw new Error(
|
||||||
|
`custom-tags: total session tags (${existingTags.length + newTags.length}) would exceed the AWS limit of ${MAX_SESSION_TAGS}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function assumeRole(params: assumeRoleParams) {
|
export async function assumeRole(params: assumeRoleParams) {
|
||||||
@@ -87,10 +193,12 @@ export async function assumeRole(params: assumeRoleParams) {
|
|||||||
roleDuration,
|
roleDuration,
|
||||||
roleSessionName,
|
roleSessionName,
|
||||||
roleSkipSessionTagging,
|
roleSkipSessionTagging,
|
||||||
|
transitiveTagKeys,
|
||||||
webIdentityTokenFile,
|
webIdentityTokenFile,
|
||||||
webIdentityToken,
|
webIdentityToken,
|
||||||
inlineSessionPolicy,
|
inlineSessionPolicy,
|
||||||
managedSessionPolicies,
|
managedSessionPolicies,
|
||||||
|
customTags,
|
||||||
} = { ...params };
|
} = { ...params };
|
||||||
|
|
||||||
// Load GitHub environment variables
|
// Load GitHub environment variables
|
||||||
@@ -99,28 +207,39 @@ export async function assumeRole(params: assumeRoleParams) {
|
|||||||
throw new Error('Missing required environment variables. Are you running in GitHub Actions?');
|
throw new Error('Missing required environment variables. Are you running in GitHub Actions?');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load role session tags
|
// Build session tags. Values are sanitized because the AWS tag value spec is more
|
||||||
const tagArray: Tag[] = [
|
// restrictive than permissible characters in environment variables.
|
||||||
{ Key: 'GitHub', Value: 'Actions' },
|
const protectedTags: Tag[] = [{ Key: 'GitHub', Value: 'Actions' }];
|
||||||
{ Key: 'Repository', Value: GITHUB_REPOSITORY },
|
for (const { key, envVar } of NON_DROPPABLE_TAG_SOURCES) {
|
||||||
{ Key: 'Workflow', Value: sanitizeGitHubVariables(GITHUB_WORKFLOW) },
|
const value = process.env[envVar];
|
||||||
{ Key: 'Action', Value: GITHUB_ACTION },
|
if (value) {
|
||||||
{ Key: 'Actor', Value: sanitizeGitHubVariables(GITHUB_ACTOR) },
|
protectedTags.push({ Key: key, Value: sanitizeGitHubVariables(value) });
|
||||||
{ Key: 'Commit', Value: GITHUB_SHA },
|
|
||||||
];
|
|
||||||
if (process.env.GITHUB_REF) {
|
|
||||||
tagArray.push({
|
|
||||||
Key: 'Branch',
|
|
||||||
Value: sanitizeGitHubVariables(process.env.GITHUB_REF),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for (const { key, envVar } of DROPPABLE_TAG_SOURCES) {
|
||||||
|
const value = process.env[envVar];
|
||||||
|
if (value) {
|
||||||
|
protectedTags.push({ Key: key, Value: sanitizeGitHubVariables(value) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedCustomTags: Tag[] = customTags ? parseAndValidateCustomTags(customTags, protectedTags) : [];
|
||||||
|
|
||||||
|
const tagArray: Tag[] = [...protectedTags, ...parsedCustomTags];
|
||||||
|
|
||||||
const tags = roleSkipSessionTagging ? undefined : tagArray;
|
const tags = roleSkipSessionTagging ? undefined : tagArray;
|
||||||
if (!tags) {
|
if (!tags) {
|
||||||
core.debug('Role session tagging has been skipped.');
|
core.debug('Role session tagging has been skipped.');
|
||||||
} else {
|
} else {
|
||||||
core.debug(`${tags.length} role session tags are being used.`);
|
core.debug(`${tags.length} role session tags are being used:`);
|
||||||
|
core.debug(JSON.stringify(tagArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//only populate transitiveTagKeys array if user is actually using session tagging
|
||||||
|
const transitiveTagKeysArray = roleSkipSessionTagging
|
||||||
|
? undefined
|
||||||
|
: transitiveTagKeys?.filter((key) => tags?.some((tag) => tag.Key === key));
|
||||||
|
|
||||||
// Calculate role ARN from name and account ID (currently only supports `aws` partition)
|
// Calculate role ARN from name and account ID (currently only supports `aws` partition)
|
||||||
let roleArn = roleToAssume;
|
let roleArn = roleToAssume;
|
||||||
if (!roleArn.startsWith('arn:aws')) {
|
if (!roleArn.startsWith('arn:aws')) {
|
||||||
@@ -137,6 +256,7 @@ export async function assumeRole(params: assumeRoleParams) {
|
|||||||
RoleSessionName: roleSessionName,
|
RoleSessionName: roleSessionName,
|
||||||
DurationSeconds: roleDuration,
|
DurationSeconds: roleDuration,
|
||||||
Tags: tags ? tags : undefined,
|
Tags: tags ? tags : undefined,
|
||||||
|
TransitiveTagKeys: transitiveTagKeysArray ? transitiveTagKeysArray : undefined,
|
||||||
ExternalId: roleExternalId ? roleExternalId : undefined,
|
ExternalId: roleExternalId ? roleExternalId : undefined,
|
||||||
Policy: inlineSessionPolicy ? inlineSessionPolicy : undefined,
|
Policy: inlineSessionPolicy ? inlineSessionPolicy : undefined,
|
||||||
PolicyArns: managedSessionPolicies?.length ? managedSessionPolicies : undefined,
|
PolicyArns: managedSessionPolicies?.length ? managedSessionPolicies : undefined,
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ import { errorMessage, getBooleanInput } from '../helpers';
|
|||||||
|
|
||||||
export function cleanup() {
|
export function cleanup() {
|
||||||
// Only attempt to change environment variables if we changed them in the first place
|
// Only attempt to change environment variables if we changed them in the first place
|
||||||
if (getBooleanInput('output-env-credentials', { required: false, default: true })) {
|
const awsProfile = core.getInput('aws-profile', { required: false });
|
||||||
|
if (getBooleanInput('output-env-credentials', { required: false, default: !awsProfile })) {
|
||||||
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
|
||||||
@@ -25,6 +26,9 @@ export 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', '');
|
||||||
|
if (core.getInput('aws-profile')) {
|
||||||
|
core.exportVariable('AWS_PROFILE', '');
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(errorMessage(error));
|
core.setFailed(errorMessage(error));
|
||||||
}
|
}
|
||||||
|
|||||||
+166
-7
@@ -1,11 +1,35 @@
|
|||||||
|
import * as fs from 'node:fs';
|
||||||
|
import * as path from 'node:path';
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import type { Credentials, STSClient } from '@aws-sdk/client-sts';
|
import type { Credentials, STSClient } from '@aws-sdk/client-sts';
|
||||||
import { GetCallerIdentityCommand } from '@aws-sdk/client-sts';
|
import { GetCallerIdentityCommand } from '@aws-sdk/client-sts';
|
||||||
|
import type { AwsCredentialIdentity } from '@aws-sdk/types';
|
||||||
|
import type { UserAgent } from '@smithy/types';
|
||||||
import type { CredentialsClient } from './CredentialsClient';
|
import type { CredentialsClient } from './CredentialsClient';
|
||||||
|
|
||||||
const MAX_TAG_VALUE_LENGTH = 256;
|
const MAX_TAG_VALUE_LENGTH = 256;
|
||||||
const SANITIZATION_CHARACTER = '_';
|
const SANITIZATION_CHARACTER = '_';
|
||||||
const SPECIAL_CHARS_REGEX = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]+/;
|
const SPECIAL_CHARS_REGEX = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]+/;
|
||||||
|
const USER_AGENT_PREFIX = 'configure-aws-credentials-for-github-actions';
|
||||||
|
const UA_FIELDS: ReadonlyArray<{ env: string; label: string; pattern: RegExp }> = [
|
||||||
|
{ env: 'GITHUB_ACTION', label: 'action', pattern: /^[A-Za-z0-9_-]{1,128}$/ },
|
||||||
|
{ env: 'GITHUB_RUN_ID', label: 'run_id', pattern: /^[0-9]{1,20}$/ },
|
||||||
|
{ env: 'GITHUB_RUN_ATTEMPT', label: 'attempt', pattern: /^[0-9]{1,10}$/ },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function buildCustomUserAgent(): UserAgent {
|
||||||
|
const tokens: UserAgent = [[USER_AGENT_PREFIX]];
|
||||||
|
for (const { env, label, pattern } of UA_FIELDS) {
|
||||||
|
const value = process.env[env];
|
||||||
|
if (value === undefined) continue;
|
||||||
|
if (pattern.test(value)) {
|
||||||
|
tokens.push(['md', `${label}#${value}`]);
|
||||||
|
} else {
|
||||||
|
core.warning(`${env} has unexpected format; omitting from User-Agent`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
export function translateEnvVariables() {
|
export function translateEnvVariables() {
|
||||||
const envVars = [
|
const envVars = [
|
||||||
@@ -20,6 +44,7 @@ export function translateEnvVariables() {
|
|||||||
'ROLE_EXTERNAL_ID',
|
'ROLE_EXTERNAL_ID',
|
||||||
'ROLE_SESSION_NAME',
|
'ROLE_SESSION_NAME',
|
||||||
'ROLE_SKIP_SESSION_TAGGING',
|
'ROLE_SKIP_SESSION_TAGGING',
|
||||||
|
'TRANSITIVE_TAG_KEYS',
|
||||||
'INLINE_SESSION_POLICY',
|
'INLINE_SESSION_POLICY',
|
||||||
'MANAGED_SESSION_POLICIES',
|
'MANAGED_SESSION_POLICIES',
|
||||||
'OUTPUT_CREDENTIALS',
|
'OUTPUT_CREDENTIALS',
|
||||||
@@ -29,6 +54,7 @@ export function translateEnvVariables() {
|
|||||||
'SPECIAL_CHARACTERS_WORKAROUND',
|
'SPECIAL_CHARACTERS_WORKAROUND',
|
||||||
'USE_EXISTING_CREDENTIALS',
|
'USE_EXISTING_CREDENTIALS',
|
||||||
'NO_PROXY',
|
'NO_PROXY',
|
||||||
|
'OVERWRITE_AWS_PROFILE',
|
||||||
];
|
];
|
||||||
// Treat HTTPS_PROXY as HTTP_PROXY. Precedence is HTTPS_PROXY > HTTP_PROXY
|
// Treat HTTPS_PROXY as HTTP_PROXY. Precedence is HTTPS_PROXY > HTTP_PROXY
|
||||||
if (process.env.HTTPS_PROXY) process.env.HTTP_PROXY = process.env.HTTPS_PROXY;
|
if (process.env.HTTPS_PROXY) process.env.HTTP_PROXY = process.env.HTTPS_PROXY;
|
||||||
@@ -125,9 +151,8 @@ export async function getCallerIdentity(client: STSClient): Promise<{ Account: s
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtains account ID from STS Client and sets it as output
|
// Emits the account ID and ARN of an already-resolved caller identity as action outputs.
|
||||||
export async function exportAccountId(credentialsClient: CredentialsClient, maskAccountId?: boolean) {
|
export function exportAccountId(identity: { Account: string; Arn: string }, maskAccountId?: boolean) {
|
||||||
const identity = await getCallerIdentity(credentialsClient.stsClient);
|
|
||||||
const accountId = identity.Account;
|
const accountId = identity.Account;
|
||||||
const arn = identity.Arn;
|
const arn = identity.Arn;
|
||||||
if (maskAccountId) {
|
if (maskAccountId) {
|
||||||
@@ -139,6 +164,35 @@ export async function exportAccountId(credentialsClient: CredentialsClient, mask
|
|||||||
return accountId;
|
return accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validates that the account of the already-resolved caller identity is in the allow-list provided via the
|
||||||
|
// `allowed-account-ids` input.
|
||||||
|
export function validateAccountId(expectedAccountIds: string[] | undefined, account: string | undefined): void {
|
||||||
|
if (!expectedAccountIds || expectedAccountIds.length === 0 || expectedAccountIds[0] === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!account || !expectedAccountIds.includes(account)) {
|
||||||
|
throw new Error(
|
||||||
|
`The account ID of the provided credentials (${
|
||||||
|
account ?? 'unknown'
|
||||||
|
}) does not match any of the expected account IDs: ${expectedAccountIds.join(', ')}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts the STS Credentials shape (returned by AssumeRole and provided as action inputs) into
|
||||||
|
// the AwsCredentialIdentity shape the SDK expects when credentials are supplied explicitly to a
|
||||||
|
// client. Returns undefined if the access key ID or secret access key is missing.
|
||||||
|
export function toCredentialIdentity(creds?: Partial<Credentials>): AwsCredentialIdentity | undefined {
|
||||||
|
if (!creds?.AccessKeyId || !creds.SecretAccessKey) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
accessKeyId: creds.AccessKeyId,
|
||||||
|
secretAccessKey: creds.SecretAccessKey,
|
||||||
|
...(creds.SessionToken && { sessionToken: creds.SessionToken }),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Tags have a more restrictive set of acceptable characters than GitHub environment variables can.
|
// 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.
|
// 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.
|
// See the AWS documentation for constraint specifics https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html.
|
||||||
@@ -187,6 +241,7 @@ export async function retryAndBackoff<T>(
|
|||||||
maxRetries = 12,
|
maxRetries = 12,
|
||||||
retries = 0,
|
retries = 0,
|
||||||
base = 50,
|
base = 50,
|
||||||
|
label?: string,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
try {
|
try {
|
||||||
return await fn();
|
return await fn();
|
||||||
@@ -198,20 +253,21 @@ export async function retryAndBackoff<T>(
|
|||||||
// It's retryable, so sleep and retry.
|
// It's retryable, so sleep and retry.
|
||||||
const delay = Math.random() * (2 ** retries * base);
|
const delay = Math.random() * (2 ** retries * base);
|
||||||
const nextRetry = retries + 1;
|
const nextRetry = retries + 1;
|
||||||
|
const opName = label ? ` ${label}` : '';
|
||||||
|
|
||||||
core.debug(
|
core.info(
|
||||||
`retryAndBackoff: attempt ${nextRetry} of ${maxRetries} failed: ${errorMessage(err)}. ` +
|
`Retry${opName}: attempt ${nextRetry} of ${maxRetries} failed: ${errorMessage(err)}. ` +
|
||||||
`Retrying after ${Math.floor(delay)}ms.`,
|
`Retrying after ${Math.floor(delay)}ms.`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await sleep(delay);
|
await sleep(delay);
|
||||||
|
|
||||||
if (nextRetry >= maxRetries) {
|
if (nextRetry >= maxRetries) {
|
||||||
core.debug('retryAndBackoff: reached max retries; giving up.');
|
core.info(`Retry${opName}: reached max retries (${maxRetries}); giving up.`);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await retryAndBackoff(fn, isRetryable, maxRetries, nextRetry, base);
|
return await retryAndBackoff(fn, isRetryable, maxRetries, nextRetry, base, label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,3 +322,106 @@ export function getBooleanInput(name: string, options?: core.InputOptions & { de
|
|||||||
`Support boolean input list: \`true | True | TRUE | false | False | FALSE\``,
|
`Support boolean input list: \`true | True | TRUE | false | False | FALSE\``,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// O_NOFOLLOW is undefined on Windows. This sets it to 0 if it's not defined.
|
||||||
|
const O_NOFOLLOW: number = (fs.constants as { O_NOFOLLOW?: number }).O_NOFOLLOW ?? 0;
|
||||||
|
|
||||||
|
export function isAllowListed(filePath: string): boolean {
|
||||||
|
// Kubelet projects service-account tokens through a symlink chain
|
||||||
|
// (token -> ..data/token, ..data -> ..<timestamp>/). The containing path is
|
||||||
|
// kubelet-controlled, so we allow symlink-following reads of this fixed
|
||||||
|
// location only.
|
||||||
|
const KUBERNETES_TOKEN_PATH_REGEX = /^\/var\/run\/secrets\/[^/]+\/serviceaccount\/token$/;
|
||||||
|
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
// No Kubernetes token paths on Windows
|
||||||
|
return KUBERNETES_TOKEN_PATH_REGEX.test(path.posix.normalize(filePath));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isSymlink(filePath: string): boolean {
|
||||||
|
try {
|
||||||
|
return fs.lstatSync(filePath).isSymbolicLink();
|
||||||
|
} catch (err) {
|
||||||
|
if ((err as NodeJS.ErrnoException).code === 'ENOENT') return false;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refuses if filePath or its parent directory is a symbolic link.
|
||||||
|
function refuseSymlinkOnPath(filePath: string): void {
|
||||||
|
const parent = path.dirname(filePath);
|
||||||
|
if (parent !== filePath && isSymlink(parent)) {
|
||||||
|
throw new Error(`Refusing ${filePath} (parent directory is a symbolic link)`);
|
||||||
|
}
|
||||||
|
if (isSymlink(filePath)) {
|
||||||
|
throw new Error(`Refusing ${filePath} (path is a symbolic link)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertRegularFile(fd: number, filePath: string): void {
|
||||||
|
const stats = fs.fstatSync(fd);
|
||||||
|
if (!stats.isFile()) {
|
||||||
|
throw new Error(`${filePath} (path is not a regular file)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ENOENT: file does not exist
|
||||||
|
// ELOOP: too many symbolic links (from NOFOLLOW)
|
||||||
|
|
||||||
|
export function readFileUtf8(filePath: string): string | null {
|
||||||
|
const allowSymlink = isAllowListed(filePath);
|
||||||
|
if (!allowSymlink) {
|
||||||
|
refuseSymlinkOnPath(filePath);
|
||||||
|
}
|
||||||
|
const openFlags = fs.constants.O_RDONLY | (allowSymlink ? 0 : O_NOFOLLOW);
|
||||||
|
let fd: number;
|
||||||
|
try {
|
||||||
|
fd = fs.openSync(filePath, openFlags);
|
||||||
|
} catch (err) {
|
||||||
|
const code = (err as NodeJS.ErrnoException).code;
|
||||||
|
if (code === 'ENOENT') return null;
|
||||||
|
if (code === 'ELOOP') {
|
||||||
|
throw new Error(`Refusing ${filePath} (path is a symbolic link)`);
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertRegularFile(fd, filePath);
|
||||||
|
return fs.readFileSync(fd, 'utf-8');
|
||||||
|
} finally {
|
||||||
|
fs.closeSync(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function writeFileUtf8(filePath: string, content: string, mode = 0o600): void {
|
||||||
|
refuseSymlinkOnPath(filePath);
|
||||||
|
let fd: number;
|
||||||
|
try {
|
||||||
|
fd = fs.openSync(filePath, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_TRUNC | O_NOFOLLOW, mode);
|
||||||
|
} catch (err) {
|
||||||
|
if ((err as NodeJS.ErrnoException).code === 'ELOOP') {
|
||||||
|
throw new Error(`Refusing ${filePath} (path is a symbolic link)`);
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
assertRegularFile(fd, filePath);
|
||||||
|
// openSync only applies mode on creation.
|
||||||
|
// If the file already exists, we need to ensure the mode is correct.
|
||||||
|
if (process.platform !== 'win32') {
|
||||||
|
fs.fchmodSync(fd, mode);
|
||||||
|
}
|
||||||
|
fs.writeFileSync(fd, content);
|
||||||
|
} finally {
|
||||||
|
fs.closeSync(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mkdir(dir: string, mode = 0o700): void {
|
||||||
|
fs.mkdirSync(dir, { recursive: true, mode });
|
||||||
|
if (isSymlink(dir)) {
|
||||||
|
throw new Error(`Refusing ${dir} (path is a symbolic link)`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+117
-33
@@ -10,14 +10,18 @@ import {
|
|||||||
exportRegion,
|
exportRegion,
|
||||||
getBooleanInput,
|
getBooleanInput,
|
||||||
retryAndBackoff,
|
retryAndBackoff,
|
||||||
|
toCredentialIdentity,
|
||||||
translateEnvVariables,
|
translateEnvVariables,
|
||||||
unsetCredentials,
|
unsetCredentials,
|
||||||
|
validateAccountId,
|
||||||
verifyKeys,
|
verifyKeys,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
|
import { writeProfileFiles } from './profileManager';
|
||||||
|
|
||||||
const DEFAULT_ROLE_DURATION = 3600; // One hour (seconds)
|
const DEFAULT_ROLE_DURATION = 3600; // One hour (seconds)
|
||||||
const ROLE_SESSION_NAME = 'GitHubActions';
|
const ROLE_SESSION_NAME = 'GitHubActions';
|
||||||
const REGION_REGEX = /^[a-z0-9-]+$/g;
|
const REGION_REGEX = /^[a-z0-9-]+$/g;
|
||||||
|
const ROLE_SESSION_NAME_REGEX = /^[\w+=,.@-]*$/;
|
||||||
|
|
||||||
export async function run() {
|
export async function run() {
|
||||||
try {
|
try {
|
||||||
@@ -29,6 +33,8 @@ export async function run() {
|
|||||||
const sessionTokenInput = core.getInput('aws-session-token', { required: false });
|
const sessionTokenInput = core.getInput('aws-session-token', { required: false });
|
||||||
const SessionToken = sessionTokenInput === '' ? undefined : sessionTokenInput;
|
const SessionToken = sessionTokenInput === '' ? undefined : sessionTokenInput;
|
||||||
const region = core.getInput('aws-region', { required: true });
|
const region = core.getInput('aws-region', { required: true });
|
||||||
|
const awsProfile = core.getInput('aws-profile', { required: false });
|
||||||
|
const overwriteAwsProfile = getBooleanInput('overwrite-aws-profile', { required: false });
|
||||||
const roleToAssume = core.getInput('role-to-assume', { required: false });
|
const roleToAssume = core.getInput('role-to-assume', { required: false });
|
||||||
const audience = core.getInput('audience', { required: false });
|
const audience = core.getInput('audience', { required: false });
|
||||||
const maskAccountId = getBooleanInput('mask-aws-account-id', { required: false });
|
const maskAccountId = getBooleanInput('mask-aws-account-id', { required: false });
|
||||||
@@ -38,14 +44,18 @@ export async function run() {
|
|||||||
Number.parseInt(core.getInput('role-duration-seconds', { required: false })) || DEFAULT_ROLE_DURATION;
|
Number.parseInt(core.getInput('role-duration-seconds', { required: false })) || DEFAULT_ROLE_DURATION;
|
||||||
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
|
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
|
||||||
const roleSkipSessionTagging = getBooleanInput('role-skip-session-tagging', { required: false });
|
const roleSkipSessionTagging = getBooleanInput('role-skip-session-tagging', { required: false });
|
||||||
|
const transitiveTagKeys = core.getMultilineInput('transitive-tag-keys', { required: false });
|
||||||
const proxyServer = core.getInput('http-proxy', { required: false }) || process.env.HTTP_PROXY;
|
const proxyServer = core.getInput('http-proxy', { required: false }) || process.env.HTTP_PROXY;
|
||||||
|
const customTags = core.getInput('custom-tags', { required: false });
|
||||||
const inlineSessionPolicy = core.getInput('inline-session-policy', { required: false });
|
const inlineSessionPolicy = core.getInput('inline-session-policy', { required: false });
|
||||||
const managedSessionPolicies = core.getMultilineInput('managed-session-policies', { required: false }).map((p) => {
|
const managedSessionPolicies = core.getMultilineInput('managed-session-policies', { required: false }).map((p) => {
|
||||||
return { arn: p };
|
return { arn: p };
|
||||||
});
|
});
|
||||||
const roleChaining = getBooleanInput('role-chaining', { required: false });
|
const roleChaining = getBooleanInput('role-chaining', { required: false });
|
||||||
const outputCredentials = getBooleanInput('output-credentials', { required: false });
|
const outputCredentials = getBooleanInput('output-credentials', { required: false });
|
||||||
const outputEnvCredentials = getBooleanInput('output-env-credentials', { required: false, default: true });
|
// Default to always outputting environment credentials unless profile is specified. If profile is specified, default
|
||||||
|
// to no environment credentials (but still output them if the user specifically requests it).
|
||||||
|
const outputEnvCredentials = getBooleanInput('output-env-credentials', { required: false, default: !awsProfile });
|
||||||
const unsetCurrentCredentials = getBooleanInput('unset-current-credentials', { required: false });
|
const unsetCurrentCredentials = getBooleanInput('unset-current-credentials', { required: false });
|
||||||
let disableRetry = getBooleanInput('disable-retry', { required: false });
|
let disableRetry = getBooleanInput('disable-retry', { required: false });
|
||||||
const specialCharacterWorkaround = getBooleanInput('special-characters-workaround', { required: false });
|
const specialCharacterWorkaround = getBooleanInput('special-characters-workaround', { required: false });
|
||||||
@@ -57,6 +67,7 @@ export async function run() {
|
|||||||
.map((s) => s.trim());
|
.map((s) => s.trim());
|
||||||
const forceSkipOidc = getBooleanInput('force-skip-oidc', { required: false });
|
const forceSkipOidc = getBooleanInput('force-skip-oidc', { required: false });
|
||||||
const noProxy = core.getInput('no-proxy', { required: false });
|
const noProxy = core.getInput('no-proxy', { required: false });
|
||||||
|
const stsEndpoint = core.getInput('sts-endpoint', { required: false });
|
||||||
const globalTimeout = Number.parseInt(core.getInput('action-timeout-s', { required: false })) || 0;
|
const globalTimeout = Number.parseInt(core.getInput('action-timeout-s', { required: false })) || 0;
|
||||||
|
|
||||||
let timeoutId: NodeJS.Timeout | undefined;
|
let timeoutId: NodeJS.Timeout | undefined;
|
||||||
@@ -82,6 +93,9 @@ export async function run() {
|
|||||||
maxRetries = 1;
|
maxRetries = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const withRetry = <T>(fn: () => Promise<T>, label: string): Promise<T> =>
|
||||||
|
retryAndBackoff(fn, !disableRetry, maxRetries, 0, 50, label);
|
||||||
|
|
||||||
// Logic to decide whether to attempt to use OIDC or not
|
// Logic to decide whether to attempt to use OIDC or not
|
||||||
const useGitHubOIDCProvider = () => {
|
const useGitHubOIDCProvider = () => {
|
||||||
if (forceSkipOidc) return false;
|
if (forceSkipOidc) return false;
|
||||||
@@ -117,12 +131,34 @@ export async function run() {
|
|||||||
if (!region.match(REGION_REGEX)) {
|
if (!region.match(REGION_REGEX)) {
|
||||||
throw new Error(`Region is not valid: ${region}`);
|
throw new Error(`Region is not valid: ${region}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (roleSessionName.length < 2 || roleSessionName.length > 64) {
|
||||||
|
throw new Error(
|
||||||
|
`Role session name must be between 2 and 64 characters, got ${roleSessionName.length}: '${roleSessionName}'`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!roleSessionName.match(ROLE_SESSION_NAME_REGEX)) {
|
||||||
|
throw new Error(
|
||||||
|
`Role session name is not valid: '${roleSessionName}'. Must satisfy regular expression pattern: [\\w+=,.@-]*`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
exportRegion(region, outputEnvCredentials);
|
exportRegion(region, outputEnvCredentials);
|
||||||
|
|
||||||
// Instantiate credentials client
|
// Instantiate credentials client
|
||||||
const clientProps: { region: string; proxyServer?: string; noProxy?: string } = { region };
|
const clientProps: {
|
||||||
|
region: string;
|
||||||
|
proxyServer?: string;
|
||||||
|
noProxy?: string;
|
||||||
|
stsEndpoint?: string;
|
||||||
|
roleChaining: boolean;
|
||||||
|
} = {
|
||||||
|
region,
|
||||||
|
roleChaining,
|
||||||
|
};
|
||||||
if (proxyServer) clientProps.proxyServer = proxyServer;
|
if (proxyServer) clientProps.proxyServer = proxyServer;
|
||||||
if (noProxy) clientProps.noProxy = noProxy;
|
if (noProxy) clientProps.noProxy = noProxy;
|
||||||
|
if (stsEndpoint) clientProps.stsEndpoint = stsEndpoint;
|
||||||
const credentialsClient = new CredentialsClient(clientProps);
|
const credentialsClient = new CredentialsClient(clientProps);
|
||||||
let sourceAccountId: string;
|
let sourceAccountId: string;
|
||||||
let webIdentityToken: string;
|
let webIdentityToken: string;
|
||||||
@@ -142,13 +178,9 @@ export async function run() {
|
|||||||
// Else, export credentials provided as input
|
// Else, export credentials provided as input
|
||||||
if (useGitHubOIDCProvider()) {
|
if (useGitHubOIDCProvider()) {
|
||||||
try {
|
try {
|
||||||
webIdentityToken = await retryAndBackoff(
|
webIdentityToken = await withRetry(async () => {
|
||||||
async () => {
|
|
||||||
return core.getIDToken(audience);
|
return core.getIDToken(audience);
|
||||||
},
|
}, 'getIDToken');
|
||||||
!disableRetry,
|
|
||||||
maxRetries,
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`getIDToken call failed: ${errorMessage(error)}`);
|
throw new Error(`getIDToken call failed: ${errorMessage(error)}`);
|
||||||
}
|
}
|
||||||
@@ -161,26 +193,59 @@ export async function run() {
|
|||||||
// the source credentials to already be masked as secrets
|
// the source credentials to already be masked as secrets
|
||||||
// in any error messages.
|
// in any error messages.
|
||||||
exportCredentials({ AccessKeyId, SecretAccessKey, SessionToken }, outputCredentials, outputEnvCredentials);
|
exportCredentials({ AccessKeyId, SecretAccessKey, SessionToken }, outputCredentials, outputEnvCredentials);
|
||||||
|
|
||||||
|
// If using IAM User Credentials, write to profile now so that the assumeRole call can succeed (and also for
|
||||||
|
// credential validation before role assumption).
|
||||||
|
if (awsProfile) {
|
||||||
|
writeProfileFiles(awsProfile, { AccessKeyId, SecretAccessKey, SessionToken }, region, overwriteAwsProfile);
|
||||||
|
}
|
||||||
} else if (!webIdentityTokenFile && !roleChaining) {
|
} else if (!webIdentityTokenFile && !roleChaining) {
|
||||||
// Proceed only if credentials can be picked up
|
// Proceed only if credentials can be picked up. validateCredentials resolves the ambient
|
||||||
await credentialsClient.validateCredentials(undefined, roleChaining, expectedAccountIds);
|
// credentials via the SDK default chain, proves they work, and returns the caller identity.
|
||||||
sourceAccountId = await exportAccountId(credentialsClient, maskAccountId);
|
const identity = await withRetry(
|
||||||
|
() => credentialsClient.validateCredentials(undefined, undefined, roleChaining),
|
||||||
|
'validateCredentials',
|
||||||
|
);
|
||||||
|
// Enforce the allowed-account-ids guardrail unless a role will be assumed, in which case the
|
||||||
|
// final account is validated after assumeRole (these ambient credentials are the source account).
|
||||||
|
if (!roleToAssume) {
|
||||||
|
validateAccountId(expectedAccountIds, identity.Account);
|
||||||
|
}
|
||||||
|
sourceAccountId = exportAccountId(identity, maskAccountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AccessKeyId || roleChaining) {
|
if (AccessKeyId || roleChaining) {
|
||||||
// Validate that the SDK can actually pick up credentials.
|
// Validate that the credentials the action will use actually work, and resolve their identity.
|
||||||
// This validates cases where this action is using existing environment credentials,
|
const resolutionCredentials =
|
||||||
// and cases where the user intended to provide input credentials but the secrets inputs resolved to empty strings.
|
outputEnvCredentials || !AccessKeyId
|
||||||
await credentialsClient.validateCredentials(AccessKeyId, roleChaining, expectedAccountIds);
|
? undefined
|
||||||
sourceAccountId = await exportAccountId(credentialsClient, maskAccountId);
|
: toCredentialIdentity({ AccessKeyId, SecretAccessKey, SessionToken });
|
||||||
|
const identity = await withRetry(
|
||||||
|
() => credentialsClient.validateCredentials(resolutionCredentials, AccessKeyId, roleChaining),
|
||||||
|
'validateCredentials',
|
||||||
|
);
|
||||||
|
// Enforce the allowed-account-ids guardrail unless a role will be assumed (the final account is
|
||||||
|
// validated after assumeRole; these are the source credentials).
|
||||||
|
if (!roleToAssume) {
|
||||||
|
validateAccountId(expectedAccountIds, identity.Account);
|
||||||
|
}
|
||||||
|
sourceAccountId = identity.Account;
|
||||||
|
if (outputEnvCredentials) {
|
||||||
|
exportAccountId(identity, maskAccountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (customTags && (useGitHubOIDCProvider() || webIdentityTokenFile)) {
|
||||||
|
core.warning(
|
||||||
|
"'custom-tags' is set but will be ignored because session tags cannot be applied when using OIDC or web identity token authentication. " +
|
||||||
|
'Tags are controlled by the identity provider token claims in these authentication flows.',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get role credentials if configured to do so
|
// Get role credentials if configured to do so
|
||||||
if (roleToAssume) {
|
if (roleToAssume) {
|
||||||
let roleCredentials: AssumeRoleCommandOutput;
|
let roleCredentials: AssumeRoleCommandOutput;
|
||||||
do {
|
do {
|
||||||
roleCredentials = await retryAndBackoff(
|
roleCredentials = await withRetry(async () => {
|
||||||
async () => {
|
|
||||||
return assumeRole({
|
return assumeRole({
|
||||||
credentialsClient,
|
credentialsClient,
|
||||||
sourceAccountId,
|
sourceAccountId,
|
||||||
@@ -189,34 +254,53 @@ export async function run() {
|
|||||||
roleDuration,
|
roleDuration,
|
||||||
roleSessionName,
|
roleSessionName,
|
||||||
roleSkipSessionTagging,
|
roleSkipSessionTagging,
|
||||||
|
transitiveTagKeys,
|
||||||
webIdentityTokenFile,
|
webIdentityTokenFile,
|
||||||
webIdentityToken,
|
webIdentityToken,
|
||||||
inlineSessionPolicy,
|
inlineSessionPolicy,
|
||||||
managedSessionPolicies,
|
managedSessionPolicies,
|
||||||
|
customTags,
|
||||||
});
|
});
|
||||||
},
|
}, 'AssumeRole');
|
||||||
!disableRetry,
|
|
||||||
maxRetries,
|
|
||||||
);
|
|
||||||
} while (specialCharacterWorkaround && !verifyKeys(roleCredentials.Credentials));
|
} while (specialCharacterWorkaround && !verifyKeys(roleCredentials.Credentials));
|
||||||
core.info(`Authenticated as assumedRoleId ${roleCredentials.AssumedRoleUser?.AssumedRoleId}`);
|
core.info(`Authenticated as assumedRoleId ${roleCredentials.AssumedRoleUser?.AssumedRoleId}`);
|
||||||
exportCredentials(roleCredentials.Credentials, outputCredentials, outputEnvCredentials);
|
exportCredentials(roleCredentials.Credentials, outputCredentials, outputEnvCredentials);
|
||||||
// We need to validate the credentials in 2 of our use-cases
|
// Validate the assumed-role credentials and resolve their identity.
|
||||||
// First: self-hosted runners. If the GITHUB_ACTIONS environment variable
|
const identity = await withRetry(
|
||||||
// is set to `true` then we are NOT in a self-hosted runner.
|
() => credentialsClient.validateCredentials(toCredentialIdentity(roleCredentials.Credentials)),
|
||||||
// Second: Customer provided credentials manually (IAM User keys stored in GH Secrets)
|
'validateCredentials',
|
||||||
if (!process.env.GITHUB_ACTIONS || AccessKeyId) {
|
|
||||||
await credentialsClient.validateCredentials(
|
|
||||||
roleCredentials.Credentials?.AccessKeyId,
|
|
||||||
roleChaining,
|
|
||||||
expectedAccountIds,
|
|
||||||
);
|
);
|
||||||
}
|
// Enforce the allowed-account-ids guardrail against the assumed (final) account.
|
||||||
|
validateAccountId(expectedAccountIds, identity.Account);
|
||||||
if (outputEnvCredentials) {
|
if (outputEnvCredentials) {
|
||||||
await exportAccountId(credentialsClient, maskAccountId);
|
exportAccountId(identity, maskAccountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write profile files if profile mode is enabled
|
||||||
|
if (awsProfile) {
|
||||||
|
if (!roleCredentials.Credentials) {
|
||||||
|
throw new Error('AssumeRole call succeeded but returned no credentials');
|
||||||
|
}
|
||||||
|
// If user provided IAM User Credentials and then we assumed a role, overwrite the profile file to add
|
||||||
|
// the session token. (this only overwrites the profile within a single run of the action).
|
||||||
|
if (AccessKeyId || !process.env.GITHUB_ACTIONS) {
|
||||||
|
writeProfileFiles(awsProfile, roleCredentials.Credentials, region, true);
|
||||||
|
} else {
|
||||||
|
writeProfileFiles(awsProfile, roleCredentials.Credentials, region, overwriteAwsProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outputEnvCredentials) {
|
||||||
|
core.exportVariable('AWS_PROFILE', awsProfile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
core.info('Proceeding with IAM user credentials');
|
core.info('Proceeding with IAM user credentials');
|
||||||
|
|
||||||
|
if (awsProfile) {
|
||||||
|
if (outputEnvCredentials) {
|
||||||
|
core.exportVariable('AWS_PROFILE', awsProfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear timeout on successful completion
|
// Clear timeout on successful completion
|
||||||
|
|||||||
@@ -0,0 +1,206 @@
|
|||||||
|
import * as os from 'node:os';
|
||||||
|
import * as path from 'node:path';
|
||||||
|
import * as core from '@actions/core';
|
||||||
|
import type { Credentials } from '@aws-sdk/client-sts';
|
||||||
|
import { mkdir, readFileUtf8, writeFileUtf8 } from './helpers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse an INI-format string into a nested object.
|
||||||
|
* Preserves literal section names (e.g. "profile dev" stays as-is).
|
||||||
|
*/
|
||||||
|
export function parseIni(iniData: string): Record<string, Record<string, string>> {
|
||||||
|
const result: Record<string, Record<string, string>> = {};
|
||||||
|
let currentSection: string | undefined;
|
||||||
|
|
||||||
|
for (const line of iniData.split(/\r?\n/)) {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
if (!trimmed || trimmed.startsWith(';') || trimmed.startsWith('#')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sectionMatch = trimmed.match(/^\[([^\]]*)\]$/);
|
||||||
|
if (sectionMatch) {
|
||||||
|
currentSection = sectionMatch[1] as string;
|
||||||
|
if (currentSection === '__proto__') {
|
||||||
|
currentSection = undefined;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result[currentSection] = result[currentSection] || {};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSection) {
|
||||||
|
const eqIndex = trimmed.indexOf('=');
|
||||||
|
if (eqIndex > 0) {
|
||||||
|
const key = trimmed.substring(0, eqIndex).trim();
|
||||||
|
const value = trimmed.substring(eqIndex + 1).trim();
|
||||||
|
if (key !== '__proto__') {
|
||||||
|
const section = result[currentSection];
|
||||||
|
if (section) {
|
||||||
|
section[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize a nested object into INI-format string.
|
||||||
|
*/
|
||||||
|
export function stringifyIni(data: Record<string, Record<string, string>>): string {
|
||||||
|
const sections: string[] = [];
|
||||||
|
for (const [sectionName, sectionData] of Object.entries(data)) {
|
||||||
|
const lines: string[] = [`[${sectionName}]`];
|
||||||
|
for (const [key, value] of Object.entries(sectionData)) {
|
||||||
|
lines.push(`${key} = ${value}`);
|
||||||
|
}
|
||||||
|
sections.push(lines.join('\n'));
|
||||||
|
}
|
||||||
|
return `${sections.join('\n\n')}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ProfileFilePaths {
|
||||||
|
credentials: string;
|
||||||
|
config: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file paths for AWS credentials and config files
|
||||||
|
* Respects AWS_SHARED_CREDENTIALS_FILE and AWS_CONFIG_FILE environment variables
|
||||||
|
*/
|
||||||
|
export function getProfileFilePaths(): ProfileFilePaths {
|
||||||
|
const credentialsPath = process.env.AWS_SHARED_CREDENTIALS_FILE || path.join(os.homedir(), '.aws', 'credentials');
|
||||||
|
const configPath = process.env.AWS_CONFIG_FILE || path.join(os.homedir(), '.aws', 'config');
|
||||||
|
|
||||||
|
return {
|
||||||
|
credentials: credentialsPath,
|
||||||
|
config: configPath,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure the AWS directory exists with secure permissions
|
||||||
|
* Creates the directory with 700 permissions (rwx for owner only)
|
||||||
|
*/
|
||||||
|
export function ensureAwsDirectoryExists(filePath: string): void {
|
||||||
|
const dir = path.dirname(filePath);
|
||||||
|
core.debug(`Ensuring directory exists: ${dir}`);
|
||||||
|
mkdir(dir, 0o700);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate profile name format
|
||||||
|
* Profile names must be non-empty, contain no whitespace, brackets, or path separators
|
||||||
|
*/
|
||||||
|
export function validateProfileName(profileName: string): void {
|
||||||
|
if (!profileName || profileName.trim() === '') {
|
||||||
|
throw new Error('aws-profile must not be empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/\s/.test(profileName)) {
|
||||||
|
throw new Error('aws-profile must not contain whitespace');
|
||||||
|
}
|
||||||
|
|
||||||
|
// INI section names can't contain brackets
|
||||||
|
if (/[[\]]/.test(profileName)) {
|
||||||
|
throw new Error('aws-profile must not contain brackets');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent path traversal
|
||||||
|
if (profileName.includes('/') || profileName.includes('\\')) {
|
||||||
|
throw new Error('aws-profile must not contain path separators');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge a profile section into an INI file
|
||||||
|
* Reads existing file, updates the specified section, and writes back
|
||||||
|
*/
|
||||||
|
export function mergeProfileSection(
|
||||||
|
filePath: string,
|
||||||
|
sectionName: string,
|
||||||
|
data: Record<string, string>,
|
||||||
|
overwriteAwsProfile: boolean,
|
||||||
|
): void {
|
||||||
|
const fileContent = readFileUtf8(filePath);
|
||||||
|
const existingContent: Record<string, Record<string, string>> = fileContent === null ? {} : parseIni(fileContent);
|
||||||
|
|
||||||
|
if (existingContent[sectionName] && !overwriteAwsProfile) {
|
||||||
|
throw new Error(
|
||||||
|
`Profile with name "${sectionName}" already exists. Please use the overwrite-aws-profile input if you want to overwrite existing profiles.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Merge: update existing profile or add new one
|
||||||
|
existingContent[sectionName] = data;
|
||||||
|
|
||||||
|
const content = stringifyIni(existingContent);
|
||||||
|
|
||||||
|
core.debug(`Writing profile to ${filePath}`);
|
||||||
|
writeFileUtf8(filePath, content, 0o600);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write AWS profile files with credentials and configuration
|
||||||
|
* This is the main entry point for profile file operations
|
||||||
|
*
|
||||||
|
* @param profileName - Name of the AWS profile to configure
|
||||||
|
* @param credentials - AWS credentials (access key, secret key, session token)
|
||||||
|
* @param region - AWS region
|
||||||
|
*/
|
||||||
|
export function writeProfileFiles(
|
||||||
|
profileName: string,
|
||||||
|
credentials: Partial<Credentials>,
|
||||||
|
region: string,
|
||||||
|
overwriteAwsProfile: boolean,
|
||||||
|
): void {
|
||||||
|
try {
|
||||||
|
// Validate profile name
|
||||||
|
validateProfileName(profileName);
|
||||||
|
|
||||||
|
const paths = getProfileFilePaths();
|
||||||
|
|
||||||
|
// Ensure .aws directory exists
|
||||||
|
ensureAwsDirectoryExists(paths.credentials);
|
||||||
|
ensureAwsDirectoryExists(paths.config);
|
||||||
|
|
||||||
|
// Prepare credentials data
|
||||||
|
const credentialsData: Record<string, string> = {};
|
||||||
|
if (credentials.AccessKeyId) {
|
||||||
|
credentialsData.aws_access_key_id = credentials.AccessKeyId;
|
||||||
|
}
|
||||||
|
if (credentials.SecretAccessKey) {
|
||||||
|
credentialsData.aws_secret_access_key = credentials.SecretAccessKey;
|
||||||
|
}
|
||||||
|
if (credentials.SessionToken) {
|
||||||
|
credentialsData.aws_session_token = credentials.SessionToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Credentials file uses [profileName] syntax
|
||||||
|
const credsSectionName = profileName;
|
||||||
|
|
||||||
|
// Config file uses [profile profileName] syntax, except for 'default'
|
||||||
|
const configSectionName = profileName === 'default' ? 'default' : `profile ${profileName}`;
|
||||||
|
|
||||||
|
// Prepare config data
|
||||||
|
const configData: Record<string, string> = {
|
||||||
|
region: region,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Write to credentials file
|
||||||
|
core.info(`Writing credentials to profile: ${profileName}`);
|
||||||
|
mergeProfileSection(paths.credentials, credsSectionName, credentialsData, overwriteAwsProfile);
|
||||||
|
|
||||||
|
// Write to config file
|
||||||
|
core.info(`Writing config to profile: ${profileName}`);
|
||||||
|
mergeProfileSection(paths.config, configSectionName, configData, overwriteAwsProfile);
|
||||||
|
|
||||||
|
core.info(`✓ Successfully configured AWS profile: ${profileName}`);
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(
|
||||||
|
`Failed to write AWS profile '${profileName}': ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import { AssumeRoleWithWebIdentityCommand, GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';
|
||||||
|
import { mockClient } from 'aws-sdk-client-mock';
|
||||||
|
import { fs, vol } from 'memfs';
|
||||||
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
import * as helpers from '../src/helpers';
|
||||||
|
import { run } from '../src/index';
|
||||||
|
import mocks from './mockinputs.test';
|
||||||
|
|
||||||
|
vi.mock('node:fs');
|
||||||
|
vi.mock('@actions/core');
|
||||||
|
|
||||||
|
const mockedSTSClient = mockClient(STSClient);
|
||||||
|
|
||||||
|
describe('assumeRoleWithWebIdentityTokenFile', {}, () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
vi.clearAllMocks();
|
||||||
|
mockedSTSClient.reset();
|
||||||
|
vol.reset();
|
||||||
|
helpers.withsleep(() => Promise.resolve());
|
||||||
|
vi.mocked(core.getInput).mockImplementation(mocks.getInput(mocks.WEBIDENTITY_TOKEN_FILE_INPUTS));
|
||||||
|
vi.mocked(core.getMultilineInput).mockReturnValue([]);
|
||||||
|
mockedSTSClient.on(GetCallerIdentityCommand).resolves({ ...mocks.outputs.GET_CALLER_IDENTITY });
|
||||||
|
process.env = { ...mocks.envs };
|
||||||
|
fs.mkdirSync('/home/github', { recursive: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
helpers.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refuses when the token file is a symlink and never calls STS', async () => {
|
||||||
|
fs.mkdirSync('/etc', { recursive: true });
|
||||||
|
fs.writeFileSync('/etc/passwd', 'root:x:0:0::/root:/bin/sh');
|
||||||
|
fs.symlinkSync('/etc/passwd', '/home/github/file.txt');
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(expect.stringMatching(/Refusing .* \(.* symbolic link\)/));
|
||||||
|
expect(mockedSTSClient.commandCalls(AssumeRoleWithWebIdentityCommand)).toHaveLength(0);
|
||||||
|
expect(fs.readFileSync('/etc/passwd', 'utf-8')).toBe('root:x:0:0::/root:/bin/sh');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves the existing missing-file error when the token file does not exist', async () => {
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).toHaveBeenCalledWith(expect.stringContaining('Web identity token file does not exist'));
|
||||||
|
expect(mockedSTSClient.commandCalls(AssumeRoleWithWebIdentityCommand)).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes token contents to STS when the file is regular', async () => {
|
||||||
|
fs.writeFileSync('/home/github/file.txt', 'real-token');
|
||||||
|
mockedSTSClient.on(AssumeRoleWithWebIdentityCommand).resolves(mocks.outputs.STS_CREDENTIALS);
|
||||||
|
|
||||||
|
await run();
|
||||||
|
|
||||||
|
expect(core.setFailed).not.toHaveBeenCalled();
|
||||||
|
const calls = mockedSTSClient.commandCalls(AssumeRoleWithWebIdentityCommand);
|
||||||
|
expect(calls).toHaveLength(1);
|
||||||
|
expect(calls[0]?.args[0].input.WebIdentityToken).toBe('real-token');
|
||||||
|
});
|
||||||
|
});
|
||||||
+26
-11
@@ -5,20 +5,15 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|||||||
import { cleanup } from '../src/cleanup';
|
import { cleanup } from '../src/cleanup';
|
||||||
import mocks from './mockinputs.test';
|
import mocks from './mockinputs.test';
|
||||||
|
|
||||||
|
vi.mock('@actions/core');
|
||||||
|
|
||||||
const mockedSTSClient = mockClient(STSClient);
|
const mockedSTSClient = mockClient(STSClient);
|
||||||
|
|
||||||
describe('Configure AWS Credentials cleanup', {}, () => {
|
describe('Configure AWS Credentials cleanup', {}, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Reset mock state
|
vi.resetAllMocks();
|
||||||
vi.restoreAllMocks();
|
|
||||||
mockedSTSClient.reset();
|
mockedSTSClient.reset();
|
||||||
// Mock GitHub Actions core functions
|
vi.mocked(core.getInput).mockReturnValue('');
|
||||||
vi.spyOn(core, 'exportVariable').mockImplementation((_n, _v) => {});
|
|
||||||
vi.spyOn(core, 'setSecret').mockImplementation((_s) => {});
|
|
||||||
vi.spyOn(core, 'setFailed').mockImplementation((_m) => {});
|
|
||||||
vi.spyOn(core, 'setOutput').mockImplementation((_n, _v) => {});
|
|
||||||
vi.spyOn(core, 'debug').mockImplementation((_m) => {});
|
|
||||||
vi.spyOn(core, 'info').mockImplementation((_m) => {});
|
|
||||||
process.env = {
|
process.env = {
|
||||||
...mocks.envs,
|
...mocks.envs,
|
||||||
AWS_ACCESS_KEY_ID: 'CLEANUPTEST',
|
AWS_ACCESS_KEY_ID: 'CLEANUPTEST',
|
||||||
@@ -38,15 +33,35 @@ describe('Configure AWS Credentials cleanup', {}, () => {
|
|||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', '');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', '');
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', '');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', '');
|
||||||
});
|
});
|
||||||
|
it('also clears AWS_PROFILE when aws-profile was set', {}, () => {
|
||||||
|
vi.mocked(core.getInput).mockImplementation((name: string) => {
|
||||||
|
if (name === 'aws-profile') return 'my-profile';
|
||||||
|
if (name === 'output-env-credentials') return 'true';
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
cleanup();
|
||||||
|
expect(core.setFailed).toHaveBeenCalledTimes(0);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(6);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_PROFILE', '');
|
||||||
|
});
|
||||||
|
it('skips env cleanup when aws-profile is set without output-env-credentials', {}, () => {
|
||||||
|
vi.mocked(core.getInput).mockImplementation((name: string) => {
|
||||||
|
if (name === 'aws-profile') return 'my-profile';
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
cleanup();
|
||||||
|
expect(core.setFailed).toHaveBeenCalledTimes(0);
|
||||||
|
expect(core.exportVariable).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
it('handles errors', {}, () => {
|
it('handles errors', {}, () => {
|
||||||
vi.spyOn(core, 'exportVariable').mockImplementationOnce(() => {
|
vi.mocked(core.exportVariable).mockImplementationOnce(() => {
|
||||||
throw new Error('Test error');
|
throw new Error('Test error');
|
||||||
});
|
});
|
||||||
cleanup();
|
cleanup();
|
||||||
expect(core.setFailed).toHaveBeenCalled();
|
expect(core.setFailed).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
it(`doesn't export credentials as empty env variables if asked not to`, {}, () => {
|
it(`doesn't export credentials as empty env variables if asked not to`, {}, () => {
|
||||||
vi.spyOn(core, 'getInput').mockImplementation(mocks.getInput(mocks.NO_ENV_CREDS_INPUTS));
|
vi.mocked(core.getInput).mockImplementation(mocks.getInput(mocks.NO_ENV_CREDS_INPUTS));
|
||||||
cleanup();
|
cleanup();
|
||||||
expect(core.exportVariable).toHaveBeenCalledTimes(0);
|
expect(core.exportVariable).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|||||||
+170
-2
@@ -1,11 +1,16 @@
|
|||||||
import { beforeEach } from 'node:test';
|
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
import { describe, expect, it, vi } from 'vitest';
|
import { fs, vol } from 'memfs';
|
||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import * as helpers from '../src/helpers';
|
import * as helpers from '../src/helpers';
|
||||||
|
|
||||||
|
vi.mock('node:fs');
|
||||||
|
vi.mock('@actions/core');
|
||||||
|
|
||||||
describe('Configure AWS Credentials helpers', {}, () => {
|
describe('Configure AWS Credentials helpers', {}, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
|
vi.clearAllMocks();
|
||||||
|
vol.reset();
|
||||||
});
|
});
|
||||||
it('removes brackets from GitHub Actor', {}, () => {
|
it('removes brackets from GitHub Actor', {}, () => {
|
||||||
const actor = 'actor[bot]';
|
const actor = 'actor[bot]';
|
||||||
@@ -23,6 +28,29 @@ describe('Configure AWS Credentials helpers', {}, () => {
|
|||||||
await expect(helpers.retryAndBackoff(fn, false)).rejects.toMatch('i am not retryable');
|
await expect(helpers.retryAndBackoff(fn, false)).rejects.toMatch('i am not retryable');
|
||||||
expect(fn).toHaveBeenCalledTimes(1);
|
expect(fn).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
it('retries and logs with label at info level', {}, async () => {
|
||||||
|
helpers.withsleep(() => Promise.resolve());
|
||||||
|
const fn = vi.fn().mockRejectedValueOnce(new Error('transient')).mockResolvedValueOnce('success');
|
||||||
|
const result = await helpers.retryAndBackoff(fn, true, 3, 0, 50, 'TestOp');
|
||||||
|
expect(result).toBe('success');
|
||||||
|
expect(fn).toHaveBeenCalledTimes(2);
|
||||||
|
expect(core.info).toHaveBeenCalledWith(expect.stringContaining('Retry TestOp: attempt 1 of 3 failed'));
|
||||||
|
helpers.reset();
|
||||||
|
});
|
||||||
|
it('logs max retries reached with label', {}, async () => {
|
||||||
|
helpers.withsleep(() => Promise.resolve());
|
||||||
|
const fn = vi.fn().mockRejectedValue(new Error('persistent'));
|
||||||
|
await expect(helpers.retryAndBackoff(fn, true, 2, 0, 50, 'TestOp')).rejects.toThrow('persistent');
|
||||||
|
expect(core.info).toHaveBeenCalledWith(expect.stringContaining('Retry TestOp: reached max retries (2)'));
|
||||||
|
helpers.reset();
|
||||||
|
});
|
||||||
|
it('retries without a label (backward compat)', {}, async () => {
|
||||||
|
helpers.withsleep(() => Promise.resolve());
|
||||||
|
const fn = vi.fn().mockRejectedValueOnce(new Error('transient')).mockResolvedValueOnce('ok');
|
||||||
|
await helpers.retryAndBackoff(fn, true, 3);
|
||||||
|
expect(core.info).toHaveBeenCalledWith(expect.stringContaining('Retry: attempt 1 of 3 failed'));
|
||||||
|
helpers.reset();
|
||||||
|
});
|
||||||
it('can output creds when told to', {}, () => {
|
it('can output creds when told to', {}, () => {
|
||||||
vi.spyOn(core, 'setOutput').mockImplementation(() => {});
|
vi.spyOn(core, 'setOutput').mockImplementation(() => {});
|
||||||
vi.spyOn(core, 'setSecret').mockImplementation(() => {});
|
vi.spyOn(core, 'setSecret').mockImplementation(() => {});
|
||||||
@@ -91,9 +119,149 @@ describe('Configure AWS Credentials helpers', {}, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('clears session token when not provided', {}, () => {
|
it('clears session token when not provided', {}, () => {
|
||||||
|
vi.spyOn(core, 'setSecret').mockImplementation(() => {});
|
||||||
vi.spyOn(core, 'exportVariable').mockImplementation(() => {});
|
vi.spyOn(core, 'exportVariable').mockImplementation(() => {});
|
||||||
process.env.AWS_SESSION_TOKEN = 'old-token';
|
process.env.AWS_SESSION_TOKEN = 'old-token';
|
||||||
helpers.exportCredentials({ AccessKeyId: 'test', SecretAccessKey: 'test' }, false, true);
|
helpers.exportCredentials({ AccessKeyId: 'test', SecretAccessKey: 'test' }, false, true);
|
||||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('filesystem helpers', {}, () => {
|
||||||
|
describe('isSymlink', {}, () => {
|
||||||
|
it('returns true for a symlink', {}, () => {
|
||||||
|
fs.mkdirSync('/dir', { recursive: true });
|
||||||
|
fs.writeFileSync('/dir/target', 'data');
|
||||||
|
fs.symlinkSync('/dir/target', '/dir/link');
|
||||||
|
expect(helpers.isSymlink('/dir/link')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for a regular file', {}, () => {
|
||||||
|
fs.mkdirSync('/dir', { recursive: true });
|
||||||
|
fs.writeFileSync('/dir/file', 'data');
|
||||||
|
expect(helpers.isSymlink('/dir/file')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false for a missing path', {}, () => {
|
||||||
|
expect(helpers.isSymlink('/nonexistent')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('readFileUtf8', {}, () => {
|
||||||
|
it('returns content for a regular file', {}, () => {
|
||||||
|
fs.mkdirSync('/dir', { recursive: true });
|
||||||
|
fs.writeFileSync('/dir/file', 'hello');
|
||||||
|
expect(helpers.readFileUtf8('/dir/file')).toBe('hello');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when the file does not exist', {}, () => {
|
||||||
|
fs.mkdirSync('/dir', { recursive: true });
|
||||||
|
expect(helpers.readFileUtf8('/dir/missing')).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refuses to read through a symlink at the target', {}, () => {
|
||||||
|
fs.mkdirSync('/dir', { recursive: true });
|
||||||
|
fs.writeFileSync('/dir/secret', 'sensitive');
|
||||||
|
fs.symlinkSync('/dir/secret', '/dir/link');
|
||||||
|
expect(() => helpers.readFileUtf8('/dir/link')).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refuses to read when the parent directory is a symlink', {}, () => {
|
||||||
|
fs.mkdirSync('/real/.aws', { recursive: true });
|
||||||
|
fs.writeFileSync('/real/.aws/credentials', 'data');
|
||||||
|
fs.mkdirSync('/home', { recursive: true });
|
||||||
|
fs.symlinkSync('/real/.aws', '/home/.aws');
|
||||||
|
expect(() => helpers.readFileUtf8('/home/.aws/credentials')).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refuses to read when the path is a directory', {}, () => {
|
||||||
|
fs.mkdirSync('/dir/subdir', { recursive: true });
|
||||||
|
expect(() => helpers.readFileUtf8('/dir/subdir')).toThrow(/not a regular file/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skipIf(process.platform === 'win32')(
|
||||||
|
'follows the kubelet projected-token symlink chain at /var/run/secrets/*/serviceaccount/token',
|
||||||
|
() => {
|
||||||
|
fs.mkdirSync('/var/run/secrets/eks.amazonaws.com/serviceaccount/..2026_05_28_00_00_00.123', {
|
||||||
|
recursive: true,
|
||||||
|
});
|
||||||
|
fs.writeFileSync(
|
||||||
|
'/var/run/secrets/eks.amazonaws.com/serviceaccount/..2026_05_28_00_00_00.123/token',
|
||||||
|
'jwt-token',
|
||||||
|
);
|
||||||
|
fs.symlinkSync('..2026_05_28_00_00_00.123', '/var/run/secrets/eks.amazonaws.com/serviceaccount/..data');
|
||||||
|
fs.symlinkSync('..data/token', '/var/run/secrets/eks.amazonaws.com/serviceaccount/token');
|
||||||
|
expect(helpers.readFileUtf8('/var/run/secrets/eks.amazonaws.com/serviceaccount/token')).toBe('jwt-token');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
it.skipIf(process.platform === 'win32')('still refuses symlinks at lookalike paths outside the allowlist', () => {
|
||||||
|
fs.mkdirSync('/var/run/secrets/eks.amazonaws.com/serviceaccount', { recursive: true });
|
||||||
|
fs.writeFileSync('/var/run/secrets/eks.amazonaws.com/serviceaccount/secret', 'jwt-token');
|
||||||
|
fs.symlinkSync(
|
||||||
|
'/var/run/secrets/eks.amazonaws.com/serviceaccount/secret',
|
||||||
|
'/var/run/secrets/eks.amazonaws.com/serviceaccount/token2',
|
||||||
|
);
|
||||||
|
expect(() => helpers.readFileUtf8('/var/run/secrets/eks.amazonaws.com/serviceaccount/token2')).toThrow(
|
||||||
|
/Refusing .* \(.* symbolic link\)/,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isAllowListed', {}, () => {
|
||||||
|
it.skipIf(process.platform === 'win32')('matches the canonical kubelet projected-token path', () => {
|
||||||
|
expect(helpers.isAllowListed('/var/run/secrets/eks.amazonaws.com/serviceaccount/token')).toBe(true);
|
||||||
|
expect(helpers.isAllowListed('/var/run/secrets/kubernetes.io/serviceaccount/token')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skipIf(process.platform === 'win32')('rejects nested or unrelated paths', () => {
|
||||||
|
expect(helpers.isAllowListed('/var/run/secrets/serviceaccount/token')).toBe(false);
|
||||||
|
expect(helpers.isAllowListed('/var/run/secrets/a/b/serviceaccount/token')).toBe(false);
|
||||||
|
expect(helpers.isAllowListed('/var/run/secrets/eks.amazonaws.com/serviceaccount/token2')).toBe(false);
|
||||||
|
expect(helpers.isAllowListed('/etc/var/run/secrets/foo/serviceaccount/token')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skipIf(process.platform === 'win32')('normalizes path traversal attempts', () => {
|
||||||
|
expect(helpers.isAllowListed('/var/run/secrets/foo/serviceaccount/../../../../etc/passwd')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('writeFileUtf8', {}, () => {
|
||||||
|
it('writes content with the specified mode', {}, () => {
|
||||||
|
fs.mkdirSync('/dir', { recursive: true });
|
||||||
|
helpers.writeFileUtf8('/dir/file', 'payload', 0o600);
|
||||||
|
expect(fs.readFileSync('/dir/file', 'utf-8')).toBe('payload');
|
||||||
|
expect(fs.statSync('/dir/file').mode & 0o777).toBe(0o600);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refuses to follow a symlink at the target and leaves the target file untouched', {}, () => {
|
||||||
|
fs.mkdirSync('/dir', { recursive: true });
|
||||||
|
fs.writeFileSync('/dir/target', 'original');
|
||||||
|
fs.symlinkSync('/dir/target', '/dir/link');
|
||||||
|
expect(() => helpers.writeFileUtf8('/dir/link', 'attacker', 0o600)).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||||
|
expect(fs.readFileSync('/dir/target', 'utf-8')).toBe('original');
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skipIf(process.platform === 'win32')('tightens mode on existing files', () => {
|
||||||
|
fs.mkdirSync('/dir', { recursive: true });
|
||||||
|
fs.writeFileSync('/dir/file', 'old', { mode: 0o644 });
|
||||||
|
helpers.writeFileUtf8('/dir/file', 'new', 0o600);
|
||||||
|
expect(fs.statSync('/dir/file').mode & 0o777).toBe(0o600);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('mkdir', {}, () => {
|
||||||
|
it('is idempotent on a regular directory', {}, () => {
|
||||||
|
helpers.mkdir('/some/nested/dir', 0o700);
|
||||||
|
helpers.mkdir('/some/nested/dir', 0o700);
|
||||||
|
expect(fs.statSync('/some/nested/dir').isDirectory()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('refuses when the target directory is a symlink', {}, () => {
|
||||||
|
fs.mkdirSync('/real', { recursive: true });
|
||||||
|
fs.mkdirSync('/home', { recursive: true });
|
||||||
|
fs.symlinkSync('/real', '/home/.aws');
|
||||||
|
expect(() => helpers.mkdir('/home/.aws', 0o700)).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+850
-75
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,46 @@ const inputs = {
|
|||||||
'aws-region': 'fake-region-1',
|
'aws-region': 'fake-region-1',
|
||||||
'special-characters-workaround': 'true',
|
'special-characters-workaround': 'true',
|
||||||
},
|
},
|
||||||
|
CUSTOM_TAGS_INVALID_JSON_INPUTS: {
|
||||||
|
'aws-access-key-id': 'MYAWSACCESSKEYID',
|
||||||
|
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
|
||||||
|
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
'aws-region': 'fake-region-1',
|
||||||
|
'retry-max-attempts': '1',
|
||||||
|
'custom-tags': 'not a json',
|
||||||
|
},
|
||||||
|
CUSTOM_TAGS_ARRAY_INPUTS: {
|
||||||
|
'aws-access-key-id': 'MYAWSACCESSKEYID',
|
||||||
|
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
|
||||||
|
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
'aws-region': 'fake-region-1',
|
||||||
|
'retry-max-attempts': '1',
|
||||||
|
'custom-tags': '[1, 2, 3]',
|
||||||
|
},
|
||||||
|
CUSTOM_TAGS_RESERVED_KEY_INPUTS: {
|
||||||
|
'aws-access-key-id': 'MYAWSACCESSKEYID',
|
||||||
|
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
|
||||||
|
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
'aws-region': 'fake-region-1',
|
||||||
|
'retry-max-attempts': '1',
|
||||||
|
'custom-tags': JSON.stringify({ Repository: 'evil-repo' }),
|
||||||
|
},
|
||||||
|
CUSTOM_TAGS_INVALID_KEY_CHARS_INPUTS: {
|
||||||
|
'aws-access-key-id': 'MYAWSACCESSKEYID',
|
||||||
|
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
|
||||||
|
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
'aws-region': 'fake-region-1',
|
||||||
|
'retry-max-attempts': '1',
|
||||||
|
'custom-tags': JSON.stringify({ 'invalid{key}': 'value' }),
|
||||||
|
},
|
||||||
|
CUSTOM_TAGS_OBJECT_INPUTS: {
|
||||||
|
'aws-access-key-id': 'MYAWSACCESSKEYID',
|
||||||
|
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
|
||||||
|
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
'aws-region': 'fake-region-1',
|
||||||
|
'retry-max-attempts': '1',
|
||||||
|
'custom-tags': JSON.stringify({ Environment: 'Production', Team: 'DevOps' }),
|
||||||
|
},
|
||||||
IAM_USER_INPUTS: {
|
IAM_USER_INPUTS: {
|
||||||
'aws-access-key-id': 'MYAWSACCESSKEYID',
|
'aws-access-key-id': 'MYAWSACCESSKEYID',
|
||||||
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
|
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
|
||||||
@@ -43,6 +83,14 @@ const inputs = {
|
|||||||
'output-env-credentials': 'false',
|
'output-env-credentials': 'false',
|
||||||
'output-credentials': 'true',
|
'output-credentials': 'true',
|
||||||
},
|
},
|
||||||
|
IAM_ASSUMEROLE_NO_ENV_INPUTS: {
|
||||||
|
'aws-access-key-id': 'MYAWSACCESSKEYID',
|
||||||
|
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
|
||||||
|
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||||
|
'aws-region': 'fake-region-1',
|
||||||
|
'output-env-credentials': 'false',
|
||||||
|
'output-credentials': 'true',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const envs = {
|
const envs = {
|
||||||
@@ -53,6 +101,13 @@ const envs = {
|
|||||||
GITHUB_SHA: 'MY-COMMIT-ID',
|
GITHUB_SHA: 'MY-COMMIT-ID',
|
||||||
GITHUB_WORKSPACE: '/home/github',
|
GITHUB_WORKSPACE: '/home/github',
|
||||||
GITHUB_ACTIONS: 'true',
|
GITHUB_ACTIONS: 'true',
|
||||||
|
GITHUB_REF: 'refs/pull/42/merge',
|
||||||
|
GITHUB_EVENT_NAME: 'pull_request',
|
||||||
|
GITHUB_RUN_ID: '16412345678',
|
||||||
|
GITHUB_JOB: 'build',
|
||||||
|
GITHUB_BASE_REF: 'main',
|
||||||
|
GITHUB_HEAD_REF: 'feature-branch',
|
||||||
|
GITHUB_TRIGGERING_ACTOR: 'MY-USERNAME[bot]',
|
||||||
};
|
};
|
||||||
|
|
||||||
const outputs = {
|
const outputs = {
|
||||||
|
|||||||
@@ -0,0 +1,804 @@
|
|||||||
|
import * as core from '@actions/core';
|
||||||
|
import { fs, vol } from 'memfs';
|
||||||
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
import {
|
||||||
|
ensureAwsDirectoryExists,
|
||||||
|
getProfileFilePaths,
|
||||||
|
mergeProfileSection,
|
||||||
|
parseIni,
|
||||||
|
stringifyIni,
|
||||||
|
validateProfileName,
|
||||||
|
writeProfileFiles,
|
||||||
|
} from '../src/profileManager';
|
||||||
|
|
||||||
|
vi.mock('node:fs');
|
||||||
|
vi.mock('@actions/core');
|
||||||
|
|
||||||
|
describe('Profile Manager', {}, () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
vi.clearAllMocks();
|
||||||
|
vol.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('parseIni', {}, () => {
|
||||||
|
it('parses a single section', {}, () => {
|
||||||
|
const result = parseIni('[dev]\naws_access_key_id=AKIA\naws_secret_access_key=secret\n');
|
||||||
|
expect(result.dev).toEqual({ aws_access_key_id: 'AKIA', aws_secret_access_key: 'secret' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses multiple sections', {}, () => {
|
||||||
|
const result = parseIni('[dev]\nkey=dev_val\n\n[prod]\nkey=prod_val\n');
|
||||||
|
expect(result.dev.key).toBe('dev_val');
|
||||||
|
expect(result.prod.key).toBe('prod_val');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('skips comments and empty lines', {}, () => {
|
||||||
|
const result = parseIni('# comment\n; another comment\n\n[dev]\nkey=val\n');
|
||||||
|
expect(result.dev).toEqual({ key: 'val' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('trims whitespace around keys and values', {}, () => {
|
||||||
|
const result = parseIni('[dev]\n key = val \n');
|
||||||
|
expect(result.dev.key).toBe('val');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves section names with spaces (e.g. profile prefix)', {}, () => {
|
||||||
|
const result = parseIni('[profile dev]\nregion=us-east-1\n');
|
||||||
|
expect(result['profile dev']).toEqual({ region: 'us-east-1' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('guards against __proto__ section pollution', {}, () => {
|
||||||
|
const result = parseIni('[__proto__]\npolluted=true\n[safe]\nkey=val\n');
|
||||||
|
expect(Object.getPrototypeOf(result)).not.toHaveProperty('polluted');
|
||||||
|
expect(result.safe).toEqual({ key: 'val' });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('guards against __proto__ key pollution', {}, () => {
|
||||||
|
const result = parseIni('[dev]\n__proto__=evil\naws_access_key_id=AKIA\n');
|
||||||
|
expect(result.dev).toEqual({ aws_access_key_id: 'AKIA' });
|
||||||
|
expect(result.dev).not.toHaveProperty('__proto__', 'evil');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles values containing equals signs', {}, () => {
|
||||||
|
const result = parseIni('[dev]\naws_session_token=FwoGZXIvYXdzEBYa/base64==\n');
|
||||||
|
expect(result.dev.aws_session_token).toBe('FwoGZXIvYXdzEBYa/base64==');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles empty values', {}, () => {
|
||||||
|
const result = parseIni('[dev]\ncli_pager=\n');
|
||||||
|
expect(result.dev.cli_pager).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns empty object for empty input', {}, () => {
|
||||||
|
expect(parseIni('')).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns empty object for whitespace-only input', {}, () => {
|
||||||
|
expect(parseIni(' \n\n \n')).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles Windows line endings (CRLF)', {}, () => {
|
||||||
|
const result = parseIni('[dev]\r\naws_access_key_id=AKIA\r\naws_secret_access_key=secret\r\n');
|
||||||
|
expect(result.dev).toEqual({ aws_access_key_id: 'AKIA', aws_secret_access_key: 'secret' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('stringifyIni', {}, () => {
|
||||||
|
it('serializes a single section', {}, () => {
|
||||||
|
const result = stringifyIni({ dev: { key: 'val' } });
|
||||||
|
expect(result).toBe('[dev]\nkey = val\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('serializes multiple sections with blank line separator', {}, () => {
|
||||||
|
const result = stringifyIni({ dev: { a: '1' }, prod: { b: '2' } });
|
||||||
|
expect(result).toBe('[dev]\na = 1\n\n[prod]\nb = 2\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('round-trips through parseIni', {}, () => {
|
||||||
|
const data = {
|
||||||
|
dev: { aws_access_key_id: 'AKIA', aws_secret_access_key: 'secret' },
|
||||||
|
'profile prod': { region: 'us-west-2' },
|
||||||
|
};
|
||||||
|
const roundTripped = parseIni(stringifyIni(data));
|
||||||
|
expect(roundTripped).toEqual(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles empty data object', {}, () => {
|
||||||
|
const result = stringifyIni({});
|
||||||
|
expect(result).toBe('\n');
|
||||||
|
expect(parseIni(result)).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles section with no keys', {}, () => {
|
||||||
|
const result = stringifyIni({ dev: {} });
|
||||||
|
expect(result).toBe('[dev]\n');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('validateProfileName', {}, () => {
|
||||||
|
it('accepts valid profile names', {}, () => {
|
||||||
|
expect(() => validateProfileName('dev')).not.toThrow();
|
||||||
|
expect(() => validateProfileName('production')).not.toThrow();
|
||||||
|
expect(() => validateProfileName('my-profile-123')).not.toThrow();
|
||||||
|
expect(() => validateProfileName('default')).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects empty profile names', {}, () => {
|
||||||
|
expect(() => validateProfileName('')).toThrow('aws-profile must not be empty');
|
||||||
|
expect(() => validateProfileName(' ')).toThrow('aws-profile must not be empty');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects profile names with whitespace', {}, () => {
|
||||||
|
expect(() => validateProfileName('my profile')).toThrow('aws-profile must not contain whitespace');
|
||||||
|
expect(() => validateProfileName('dev\ntest')).toThrow('aws-profile must not contain whitespace');
|
||||||
|
expect(() => validateProfileName('prod\tenv')).toThrow('aws-profile must not contain whitespace');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects profile names with brackets', {}, () => {
|
||||||
|
expect(() => validateProfileName('dev[test]')).toThrow('aws-profile must not contain brackets');
|
||||||
|
expect(() => validateProfileName('[profile]')).toThrow('aws-profile must not contain brackets');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects profile names with path separators', {}, () => {
|
||||||
|
expect(() => validateProfileName('dev/test')).toThrow('aws-profile must not contain path separators');
|
||||||
|
expect(() => validateProfileName('dev\\test')).toThrow('aws-profile must not contain path separators');
|
||||||
|
expect(() => validateProfileName('../etc/passwd')).toThrow('aws-profile must not contain path separators');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getProfileFilePaths', {}, () => {
|
||||||
|
it('returns default paths when env vars not set', {}, () => {
|
||||||
|
delete process.env.AWS_SHARED_CREDENTIALS_FILE;
|
||||||
|
delete process.env.AWS_CONFIG_FILE;
|
||||||
|
|
||||||
|
const paths = getProfileFilePaths();
|
||||||
|
|
||||||
|
expect(paths.credentials).toMatch(/\.aws[/\\]credentials$/);
|
||||||
|
expect(paths.config).toMatch(/\.aws[/\\]config$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects AWS_SHARED_CREDENTIALS_FILE env var', {}, () => {
|
||||||
|
process.env.AWS_SHARED_CREDENTIALS_FILE = '/custom/path/credentials';
|
||||||
|
process.env.AWS_CONFIG_FILE = '/custom/path/config';
|
||||||
|
|
||||||
|
const paths = getProfileFilePaths();
|
||||||
|
|
||||||
|
expect(paths.credentials).toBe('/custom/path/credentials');
|
||||||
|
expect(paths.config).toBe('/custom/path/config');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ensureAwsDirectoryExists', {}, () => {
|
||||||
|
it('creates directory if it does not exist', {}, () => {
|
||||||
|
const filePath = '/home/runner/.aws/credentials';
|
||||||
|
|
||||||
|
ensureAwsDirectoryExists(filePath);
|
||||||
|
|
||||||
|
expect(fs.existsSync('/home/runner/.aws')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not error if directory already exists', {}, () => {
|
||||||
|
const filePath = '/home/runner/.aws/credentials';
|
||||||
|
|
||||||
|
fs.mkdirSync('/home/runner/.aws', { recursive: true });
|
||||||
|
|
||||||
|
expect(() => ensureAwsDirectoryExists(filePath)).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('creates nested directories', {}, () => {
|
||||||
|
const filePath = '/home/runner/custom/path/.aws/credentials';
|
||||||
|
|
||||||
|
ensureAwsDirectoryExists(filePath);
|
||||||
|
|
||||||
|
expect(fs.existsSync('/home/runner/custom/path/.aws')).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('mergeProfileSection', {}, () => {
|
||||||
|
it('creates new file with profile section', {}, () => {
|
||||||
|
const filePath = '/home/runner/.aws/credentials';
|
||||||
|
fs.mkdirSync('/home/runner/.aws', { recursive: true });
|
||||||
|
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'AKIAIOSFODNN7EXAMPLE',
|
||||||
|
aws_secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
expect(parsed.dev).toBeDefined();
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('AKIAIOSFODNN7EXAMPLE');
|
||||||
|
expect(parsed.dev.aws_secret_access_key).toBe('wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('merges with existing profiles', {}, () => {
|
||||||
|
const filePath = '/home/runner/.aws/credentials';
|
||||||
|
fs.mkdirSync('/home/runner/.aws', { recursive: true });
|
||||||
|
|
||||||
|
// Create initial profile
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'AKIAIOSFODNN7EXAMPLE',
|
||||||
|
aws_secret_access_key: 'devSecretKey',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add second profile
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'prod',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'AKIAPRODEXAMPLE',
|
||||||
|
aws_secret_access_key: 'prodSecretKey',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
expect(parsed.dev).toBeDefined();
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('AKIAIOSFODNN7EXAMPLE');
|
||||||
|
expect(parsed.prod).toBeDefined();
|
||||||
|
expect(parsed.prod.aws_access_key_id).toBe('AKIAPRODEXAMPLE');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('overwrites existing profile with same name', {}, () => {
|
||||||
|
const filePath = '/home/runner/.aws/credentials';
|
||||||
|
fs.mkdirSync('/home/runner/.aws', { recursive: true });
|
||||||
|
|
||||||
|
// Create initial profile
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'OLD_KEY',
|
||||||
|
aws_secret_access_key: 'oldSecretKey',
|
||||||
|
aws_session_token: 'oldSessionToken',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Overwrite with new credentials
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'NEW_KEY',
|
||||||
|
aws_secret_access_key: 'newSecretKey',
|
||||||
|
aws_session_token: 'newSessionToken',
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('NEW_KEY');
|
||||||
|
expect(parsed.dev.aws_secret_access_key).toBe('newSecretKey');
|
||||||
|
expect(parsed.dev.aws_session_token).toBe('newSessionToken');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('overwriting a profile removes stale keys', {}, () => {
|
||||||
|
const filePath = '/home/runner/.aws/credentials';
|
||||||
|
fs.mkdirSync('/home/runner/.aws', { recursive: true });
|
||||||
|
|
||||||
|
// Create profile with session token
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'AKIA',
|
||||||
|
aws_secret_access_key: 'secret',
|
||||||
|
aws_session_token: 'old-token',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Overwrite without session token
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'AKIA2',
|
||||||
|
aws_secret_access_key: 'secret2',
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('AKIA2');
|
||||||
|
expect(parsed.dev.aws_secret_access_key).toBe('secret2');
|
||||||
|
expect(parsed.dev.aws_session_token).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles empty existing file', {}, () => {
|
||||||
|
const filePath = '/home/runner/.aws/credentials';
|
||||||
|
fs.mkdirSync('/home/runner/.aws', { recursive: true });
|
||||||
|
fs.writeFileSync(filePath, '', { mode: 0o600 });
|
||||||
|
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'AKIA',
|
||||||
|
aws_secret_access_key: 'secret',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('AKIA');
|
||||||
|
expect(parsed.dev.aws_secret_access_key).toBe('secret');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('errors if profile name already exists but overwrite flag is false', {}, () => {
|
||||||
|
const filePath = '/home/runner/.aws/credentials';
|
||||||
|
fs.mkdirSync('/home/runner/.aws', { recursive: true });
|
||||||
|
|
||||||
|
// Create initial profile
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'OLD_KEY',
|
||||||
|
aws_secret_access_key: 'oldSecretKey',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Overwrite with new credentials
|
||||||
|
expect(() =>
|
||||||
|
mergeProfileSection(
|
||||||
|
filePath,
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
aws_access_key_id: 'NEW_KEY',
|
||||||
|
aws_secret_access_key: 'newSecretKey',
|
||||||
|
aws_session_token: 'sessionToken',
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
).toThrow(
|
||||||
|
`Profile with name "dev" already exists. Please use the overwrite-aws-profile input if you want to overwrite existing profiles.`,
|
||||||
|
);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('OLD_KEY');
|
||||||
|
expect(parsed.dev.aws_secret_access_key).toBe('oldSecretKey');
|
||||||
|
expect(parsed.dev.aws_session_token).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('writeProfileFiles', {}, () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
delete process.env.AWS_SHARED_CREDENTIALS_FILE;
|
||||||
|
delete process.env.AWS_CONFIG_FILE;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('writes credentials and config for new profile', {}, () => {
|
||||||
|
writeProfileFiles(
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
||||||
|
SecretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
|
||||||
|
SessionToken: 'FwoGZXIvYXdzEBYaDEXAMPLE',
|
||||||
|
},
|
||||||
|
'us-east-1',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check credentials file
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
const credContent = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
const credParsed = parseIni(credContent);
|
||||||
|
|
||||||
|
expect(credParsed.dev).toBeDefined();
|
||||||
|
expect(credParsed.dev.aws_access_key_id).toBe('AKIAIOSFODNN7EXAMPLE');
|
||||||
|
expect(credParsed.dev.aws_secret_access_key).toBe('wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY');
|
||||||
|
expect(credParsed.dev.aws_session_token).toBe('FwoGZXIvYXdzEBYaDEXAMPLE');
|
||||||
|
|
||||||
|
// Check config file
|
||||||
|
const configPath = getProfileFilePaths().config;
|
||||||
|
const configContent = fs.readFileSync(configPath, 'utf-8');
|
||||||
|
const configParsed = parseIni(configContent);
|
||||||
|
|
||||||
|
expect(configParsed['profile dev']).toBeDefined();
|
||||||
|
expect(configParsed['profile dev'].region).toBe('us-east-1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('uses correct section naming for default profile', {}, () => {
|
||||||
|
writeProfileFiles(
|
||||||
|
'default',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
||||||
|
SecretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
|
||||||
|
},
|
||||||
|
'us-west-2',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check credentials file uses [default]
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
const credContent = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
const credParsed = parseIni(credContent);
|
||||||
|
|
||||||
|
expect(credParsed.default).toBeDefined();
|
||||||
|
expect(credParsed['profile default']).toBeUndefined();
|
||||||
|
|
||||||
|
// Check config file uses [default] (not [profile default])
|
||||||
|
const configPath = getProfileFilePaths().config;
|
||||||
|
const configContent = fs.readFileSync(configPath, 'utf-8');
|
||||||
|
const configParsed = parseIni(configContent);
|
||||||
|
|
||||||
|
expect(configParsed.default).toBeDefined();
|
||||||
|
expect(configParsed['profile default']).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('supports multiple profiles', {}, () => {
|
||||||
|
// Write first profile
|
||||||
|
writeProfileFiles(
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIADEV',
|
||||||
|
SecretAccessKey: 'devSecret',
|
||||||
|
},
|
||||||
|
'us-east-1',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Write second profile
|
||||||
|
writeProfileFiles(
|
||||||
|
'prod',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIAPROD',
|
||||||
|
SecretAccessKey: 'prodSecret',
|
||||||
|
SessionToken: 'prodToken',
|
||||||
|
},
|
||||||
|
'us-west-2',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Verify both profiles exist
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
const credContent = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
const credParsed = parseIni(credContent);
|
||||||
|
|
||||||
|
expect(credParsed.dev).toBeDefined();
|
||||||
|
expect(credParsed.prod).toBeDefined();
|
||||||
|
expect(credParsed.dev.aws_access_key_id).toBe('AKIADEV');
|
||||||
|
expect(credParsed.prod.aws_access_key_id).toBe('AKIAPROD');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles credentials without session token', {}, () => {
|
||||||
|
writeProfileFiles(
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
||||||
|
SecretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
|
||||||
|
},
|
||||||
|
'us-east-1',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
const credContent = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
const credParsed = parseIni(credContent);
|
||||||
|
|
||||||
|
expect(credParsed.dev.aws_access_key_id).toBe('AKIAIOSFODNN7EXAMPLE');
|
||||||
|
expect(credParsed.dev.aws_secret_access_key).toBe('wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY');
|
||||||
|
expect(credParsed.dev.aws_session_token).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws error for invalid profile name', {}, () => {
|
||||||
|
expect(() =>
|
||||||
|
writeProfileFiles(
|
||||||
|
'invalid profile',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIA',
|
||||||
|
SecretAccessKey: 'secret',
|
||||||
|
},
|
||||||
|
'us-east-1',
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
).toThrow('Failed to write AWS profile');
|
||||||
|
expect(() =>
|
||||||
|
writeProfileFiles(
|
||||||
|
'invalid profile',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIA',
|
||||||
|
SecretAccessKey: 'secret',
|
||||||
|
},
|
||||||
|
'us-east-1',
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
).toThrow('whitespace');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('respects custom file paths from env vars', {}, () => {
|
||||||
|
process.env.AWS_SHARED_CREDENTIALS_FILE = '/custom/credentials';
|
||||||
|
process.env.AWS_CONFIG_FILE = '/custom/config';
|
||||||
|
|
||||||
|
fs.mkdirSync('/custom', { recursive: true });
|
||||||
|
|
||||||
|
writeProfileFiles(
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIA',
|
||||||
|
SecretAccessKey: 'secret',
|
||||||
|
},
|
||||||
|
'us-east-1',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(fs.existsSync('/custom/credentials')).toBe(true);
|
||||||
|
expect(fs.existsSync('/custom/config')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('logs info messages', {}, () => {
|
||||||
|
writeProfileFiles(
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIA',
|
||||||
|
SecretAccessKey: 'secret',
|
||||||
|
},
|
||||||
|
'us-east-1',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(core.info).toHaveBeenCalledWith('Writing credentials to profile: dev');
|
||||||
|
expect(core.info).toHaveBeenCalledWith('Writing config to profile: dev');
|
||||||
|
expect(core.info).toHaveBeenCalledWith('✓ Successfully configured AWS profile: dev');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves pre-existing unrelated profiles in credentials file', {}, () => {
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
fs.mkdirSync(require('node:path').dirname(credsPath), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
credsPath,
|
||||||
|
'[personal]\naws_access_key_id=AKIAPERSONAL\naws_secret_access_key=personalSecret\naws_session_token=personalToken\n',
|
||||||
|
);
|
||||||
|
|
||||||
|
writeProfileFiles('dev', { AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' }, 'us-east-1', false);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
// Pre-existing profile must be fully intact
|
||||||
|
expect(parsed.personal).toEqual({
|
||||||
|
aws_access_key_id: 'AKIAPERSONAL',
|
||||||
|
aws_secret_access_key: 'personalSecret',
|
||||||
|
aws_session_token: 'personalToken',
|
||||||
|
});
|
||||||
|
// New profile also present
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('AKIADEV');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves pre-existing config with extra keys', {}, () => {
|
||||||
|
const configPath = getProfileFilePaths().config;
|
||||||
|
fs.mkdirSync(require('node:path').dirname(configPath), { recursive: true });
|
||||||
|
fs.writeFileSync(configPath, '[profile personal]\nregion=eu-west-1\noutput=json\ncli_pager=\n');
|
||||||
|
|
||||||
|
writeProfileFiles('dev', { AccessKeyId: 'AKIA', SecretAccessKey: 'secret' }, 'us-east-1', false);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(configPath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
expect(parsed['profile personal']).toEqual({
|
||||||
|
region: 'eu-west-1',
|
||||||
|
output: 'json',
|
||||||
|
cli_pager: '',
|
||||||
|
});
|
||||||
|
expect(parsed['profile dev'].region).toBe('us-east-1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves pre-existing default profile when writing a named profile', {}, () => {
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
fs.mkdirSync(require('node:path').dirname(credsPath), { recursive: true });
|
||||||
|
fs.writeFileSync(credsPath, '[default]\naws_access_key_id=AKIADEFAULT\naws_secret_access_key=defaultSecret\n');
|
||||||
|
|
||||||
|
writeProfileFiles('dev', { AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' }, 'us-west-2', false);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
|
||||||
|
expect(parsed.default).toEqual({
|
||||||
|
aws_access_key_id: 'AKIADEFAULT',
|
||||||
|
aws_secret_access_key: 'defaultSecret',
|
||||||
|
});
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('AKIADEV');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('comments in pre-existing files are stripped on round-trip', {}, () => {
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
fs.mkdirSync(require('node:path').dirname(credsPath), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
credsPath,
|
||||||
|
'# My important comment\n[personal]\naws_access_key_id=AKIA\naws_secret_access_key=secret\n',
|
||||||
|
);
|
||||||
|
|
||||||
|
writeProfileFiles('dev', { AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' }, 'us-east-1', false);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(credsPath, 'utf-8') as string;
|
||||||
|
|
||||||
|
// Comment is lost (known trade-off), but profile data is preserved
|
||||||
|
expect(content).not.toContain('# My important comment');
|
||||||
|
const parsed = parseIni(content);
|
||||||
|
expect(parsed.personal.aws_access_key_id).toBe('AKIA');
|
||||||
|
expect(parsed.dev.aws_access_key_id).toBe('AKIADEV');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('writes empty section when credentials object has no keys', {}, () => {
|
||||||
|
writeProfileFiles('dev', {}, 'us-east-1', false);
|
||||||
|
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
const credContent = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
const credParsed = parseIni(credContent);
|
||||||
|
|
||||||
|
// Section exists but has no credential keys
|
||||||
|
expect(credParsed.dev).toEqual({});
|
||||||
|
|
||||||
|
// Config still gets region
|
||||||
|
const configPath = getProfileFilePaths().config;
|
||||||
|
const configContent = fs.readFileSync(configPath, 'utf-8');
|
||||||
|
const configParsed = parseIni(configContent);
|
||||||
|
expect(configParsed['profile dev'].region).toBe('us-east-1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resolves credentials and config paths independently from env vars', {}, () => {
|
||||||
|
process.env.AWS_SHARED_CREDENTIALS_FILE = '/custom-creds/credentials';
|
||||||
|
// AWS_CONFIG_FILE is NOT set — should use default path
|
||||||
|
|
||||||
|
fs.mkdirSync('/custom-creds', { recursive: true });
|
||||||
|
|
||||||
|
writeProfileFiles('dev', { AccessKeyId: 'AKIA', SecretAccessKey: 'secret' }, 'us-east-1', false);
|
||||||
|
|
||||||
|
expect(fs.existsSync('/custom-creds/credentials')).toBe(true);
|
||||||
|
// Config file should be at the default path (under homedir)
|
||||||
|
const defaultConfigPath = require('node:path').join(require('node:os').homedir(), '.aws', 'config');
|
||||||
|
expect(fs.existsSync(defaultConfigPath)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('produces AWS CLI-compatible INI output (golden file)', {}, () => {
|
||||||
|
writeProfileFiles(
|
||||||
|
'dev',
|
||||||
|
{
|
||||||
|
AccessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
||||||
|
SecretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
|
||||||
|
SessionToken: 'FwoGZXIvYXdzEBYaDEXAMPLE',
|
||||||
|
},
|
||||||
|
'us-east-1',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
const credContent = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
|
||||||
|
const configPath = getProfileFilePaths().config;
|
||||||
|
const configContent = fs.readFileSync(configPath, 'utf-8');
|
||||||
|
|
||||||
|
// Verify exact byte-for-byte format matching AWS CLI style:
|
||||||
|
// - [section] header on its own line
|
||||||
|
// - key = value with spaces around =
|
||||||
|
// - LF line endings, trailing newline
|
||||||
|
expect(credContent).toBe(
|
||||||
|
'[dev]\n' +
|
||||||
|
'aws_access_key_id = AKIAIOSFODNN7EXAMPLE\n' +
|
||||||
|
'aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n' +
|
||||||
|
'aws_session_token = FwoGZXIvYXdzEBYaDEXAMPLE\n',
|
||||||
|
);
|
||||||
|
expect(configContent).toBe('[profile dev]\n' + 'region = us-east-1\n');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('golden file for multi-profile output', {}, () => {
|
||||||
|
writeProfileFiles('dev', { AccessKeyId: 'AKIADEV', SecretAccessKey: 'devSecret' }, 'us-east-1', false);
|
||||||
|
writeProfileFiles(
|
||||||
|
'prod',
|
||||||
|
{ AccessKeyId: 'AKIAPROD', SecretAccessKey: 'prodSecret', SessionToken: 'prodToken' },
|
||||||
|
'us-west-2',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
|
const credsPath = getProfileFilePaths().credentials;
|
||||||
|
const credContent = fs.readFileSync(credsPath, 'utf-8');
|
||||||
|
|
||||||
|
const configPath = getProfileFilePaths().config;
|
||||||
|
const configContent = fs.readFileSync(configPath, 'utf-8');
|
||||||
|
|
||||||
|
expect(credContent).toBe(
|
||||||
|
'[dev]\n' +
|
||||||
|
'aws_access_key_id = AKIADEV\n' +
|
||||||
|
'aws_secret_access_key = devSecret\n' +
|
||||||
|
'\n' +
|
||||||
|
'[prod]\n' +
|
||||||
|
'aws_access_key_id = AKIAPROD\n' +
|
||||||
|
'aws_secret_access_key = prodSecret\n' +
|
||||||
|
'aws_session_token = prodToken\n',
|
||||||
|
);
|
||||||
|
expect(configContent).toBe(
|
||||||
|
'[profile dev]\n' + 'region = us-east-1\n' + '\n' + '[profile prod]\n' + 'region = us-west-2\n',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('symlink hardening', {}, () => {
|
||||||
|
const credsPath = '/home/user/.aws/credentials';
|
||||||
|
const configPath = '/home/user/.aws/config';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env.AWS_SHARED_CREDENTIALS_FILE = credsPath;
|
||||||
|
process.env.AWS_CONFIG_FILE = configPath;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('mergeProfileSection refuses when the credentials path is a symlink and leaves the target unchanged', {}, () => {
|
||||||
|
fs.mkdirSync('/home/user/.aws', { recursive: true });
|
||||||
|
fs.mkdirSync('/etc', { recursive: true });
|
||||||
|
fs.writeFileSync('/etc/passwd', 'root:x:0:0::/root:/bin/sh');
|
||||||
|
fs.symlinkSync('/etc/passwd', credsPath);
|
||||||
|
|
||||||
|
expect(() => mergeProfileSection(credsPath, 'dev', { aws_access_key_id: 'AKIA' }, true)).toThrow(
|
||||||
|
/Refusing .* \(.* symbolic link\)/,
|
||||||
|
);
|
||||||
|
expect(fs.readFileSync('/etc/passwd', 'utf-8')).toBe('root:x:0:0::/root:/bin/sh');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('mergeProfileSection refuses when the config path is a symlink', {}, () => {
|
||||||
|
fs.mkdirSync('/home/user/.aws', { recursive: true });
|
||||||
|
fs.mkdirSync('/etc', { recursive: true });
|
||||||
|
fs.writeFileSync('/etc/sensitive', 'do not overwrite');
|
||||||
|
fs.symlinkSync('/etc/sensitive', configPath);
|
||||||
|
|
||||||
|
expect(() => mergeProfileSection(configPath, 'profile dev', { region: 'us-east-1' }, true)).toThrow(
|
||||||
|
/Refusing .* \(.* symbolic link\)/,
|
||||||
|
);
|
||||||
|
expect(fs.readFileSync('/etc/sensitive', 'utf-8')).toBe('do not overwrite');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ensureAwsDirectoryExists refuses when ~/.aws is a symlink', {}, () => {
|
||||||
|
fs.mkdirSync('/real-target', { recursive: true });
|
||||||
|
fs.mkdirSync('/home/user', { recursive: true });
|
||||||
|
fs.symlinkSync('/real-target', '/home/user/.aws');
|
||||||
|
|
||||||
|
expect(() => ensureAwsDirectoryExists(credsPath)).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('writeProfileFiles refuses to overwrite a pre-existing symlink at the credentials path', {}, () => {
|
||||||
|
fs.mkdirSync('/home/user/.aws', { recursive: true });
|
||||||
|
fs.mkdirSync('/etc', { recursive: true });
|
||||||
|
fs.writeFileSync('/etc/passwd', 'root:x:0:0::/root:/bin/sh');
|
||||||
|
fs.symlinkSync('/etc/passwd', credsPath);
|
||||||
|
|
||||||
|
expect(() =>
|
||||||
|
writeProfileFiles('dev', { AccessKeyId: 'AKIA', SecretAccessKey: 'secret' }, 'us-east-1', true),
|
||||||
|
).toThrow(/Refusing .* \(.* symbolic link\)/);
|
||||||
|
|
||||||
|
expect(fs.lstatSync(credsPath).isSymbolicLink()).toBe(true);
|
||||||
|
expect(fs.readFileSync('/etc/passwd', 'utf-8')).toBe('root:x:0:0::/root:/bin/sh');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('happy path still writes both files with mode 0o600 when no symlinks are present', {}, () => {
|
||||||
|
writeProfileFiles('dev', { AccessKeyId: 'AKIA', SecretAccessKey: 'secret' }, 'us-east-1', false);
|
||||||
|
|
||||||
|
expect(fs.statSync(credsPath).mode & 0o777).toBe(0o600);
|
||||||
|
expect(fs.statSync(configPath).mode & 0o777).toBe(0o600);
|
||||||
|
expect(fs.lstatSync(credsPath).isSymbolicLink()).toBe(false);
|
||||||
|
expect(fs.lstatSync(configPath).isSymbolicLink()).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
+2
-1
@@ -23,7 +23,8 @@
|
|||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"noErrorTruncation": true,
|
"noErrorTruncation": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"rootDir": "src"
|
"rootDir": "src",
|
||||||
|
"skipLibCheck": true
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts"],
|
"include": ["src/**/*.ts"],
|
||||||
"exclude": ["test/**/*.ts"]
|
"exclude": ["test/**/*.ts"]
|
||||||
|
|||||||
Reference in New Issue
Block a user