mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-08-24 04:25:05 +09:00
Compare commits
477 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 67fbcbb121 | |||
| 58bb841154 | |||
| 34779ed730 | |||
| bf7f81fcf7 | |||
| 79fafe359f | |||
| d1edd20a7e | |||
| 8a84b07f20 | |||
| 2e344a8a34 | |||
| 9f69d0f0bc | |||
| 1ca0e74a85 | |||
| 1684cc585e | |||
| 4ee5565853 | |||
| 4ff5ea70e6 | |||
| 6abb918e09 | |||
| 082f9f0637 | |||
| 2f8dfd0ed4 | |||
| f350a92ff6 | |||
| 88da7d4f1c | |||
| 18cfdaf552 | |||
| 84665e59c8 | |||
| 8788ec5aa1 | |||
| 22e077f99c | |||
| dfe025559e | |||
| 8050a91cfa | |||
| e9dce0860a | |||
| 1936d118bd | |||
| 5d27778945 | |||
| f06248b64a | |||
| ead0512447 | |||
| d63be9338f | |||
| 3ffb855336 | |||
| 25579cba53 | |||
| a64e523261 | |||
| ebad18e1cb | |||
| f324ccbd8b | |||
| f500e4423a | |||
| 717cbc82f1 | |||
| 8b86e3223d | |||
| 72ccd62416 | |||
| 852be5b0ee | |||
| 488370bebd | |||
| a8081b3d23 | |||
| fd1891d12d | |||
| 2d5d4077ee | |||
| f24ace22d4 | |||
| 05b148adc3 | |||
| 4e8c2213ad | |||
| 6b3c017dce | |||
| 45451d5084 | |||
| a27dcef2f6 | |||
| 8a29164c8b | |||
| 8d9fac2d2c | |||
| c3e3b80272 | |||
| b878f4b65b | |||
| 860d476018 | |||
| 98c131dea9 | |||
| 4d108addaf | |||
| 133757e9b8 | |||
| 603116e993 | |||
| 4c5e1c60cc | |||
| 9b9980021a | |||
| f3ce02b094 | |||
| b76c725e12 | |||
| 0dbbed9302 | |||
| ebbea79d94 | |||
| 7c62b07b9f | |||
| 3fbeeb47e5 | |||
| 63e6f31c9a | |||
| bd9e4620f6 | |||
| 57753efe28 | |||
| 306df94bc9 | |||
| f6ce4d6612 | |||
| 96a6b113cd | |||
| f93938f25d | |||
| ba85598351 | |||
| b978ecdce1 | |||
| f60aed899f | |||
| abe2958c93 | |||
| ea7b857d8a | |||
| 5932afb4de | |||
| 11ee46bb92 | |||
| cbf875bf3b | |||
| fcd8bb1e0a | |||
| f299f4c22f | |||
| 2be883a47f | |||
| 6781b24514 | |||
| 331e770405 | |||
| 8eba69932f | |||
| 61cd0b489b | |||
| e21f7333e8 | |||
| 8852ea8a14 | |||
| 40618848ac | |||
| e0e9866084 | |||
| 599a2e5580 | |||
| 9e14050741 | |||
| f382f48182 | |||
| 14cfe7b281 | |||
| f9473e17aa | |||
| 84e68dc625 | |||
| 036a4a1ddf | |||
| 9aaa1daa91 | |||
| 9ec13c9c00 | |||
| 3256f157d6 | |||
| ee3f482dac | |||
| 6ea0f4143d | |||
| a78fcb01f7 | |||
| 9815921334 | |||
| 20ce4e5ba1 | |||
| 0c8047f19c | |||
| b8c74de753 | |||
| ef6880f4e4 | |||
| 88e36ed0d9 | |||
| 207a070d63 | |||
| 74ed23ca5e | |||
| b9d67c7f13 | |||
| 7d82086556 | |||
| adee807d7a | |||
| 0f2c607a61 | |||
| dbc7efa3ed | |||
| 34986b7882 | |||
| 7b9eb2f6e4 | |||
| 2e3c5998fd | |||
| dfa266992b | |||
| 882cf48fb9 | |||
| 149a4abd85 | |||
| 2bd0cfca33 | |||
| 9b8de54d9b | |||
| fa2fb9f874 | |||
| f7a95e1861 | |||
| 710f5b29b3 | |||
| 6e5810b844 | |||
| c48e1b5784 | |||
| b0e8652658 | |||
| 88787fda18 | |||
| 1f1eb0f055 | |||
| 8053174404 | |||
| ef6b971eca | |||
| 5548ca9128 | |||
| f8c0a913fd | |||
| af7d0d7799 | |||
| 8085c119c3 | |||
| e75b7bbcfa | |||
| 9b77c5dd92 | |||
| 0d9a5be0dc | |||
| 10fe4828d8 | |||
| 2b3967abf0 | |||
| 7acd73f5ec | |||
| b66e321a4e | |||
| 54cbd0351a | |||
| 6a87164302 | |||
| 061049d49f | |||
| f68ad753c3 | |||
| 122d9ef75e | |||
| ab06157722 | |||
| 13debc4a47 | |||
| 3db60a3b37 | |||
| 02e35facd1 | |||
| d905ac4d91 | |||
| dc534a08cf | |||
| 0bcf2b267e | |||
| 77db83ef6f | |||
| 7e1dbf6504 | |||
| b0d5abffa1 | |||
| 17c44e335b | |||
| 1497fd0f1e | |||
| 13d241b293 | |||
| 230d25f14e | |||
| 65b54d1a99 | |||
| ef2b041797 | |||
| e1cbb915a6 | |||
| 7c6941c992 | |||
| 0af073e722 | |||
| 47603571fa | |||
| 819cc639a4 | |||
| 9a884abe4a | |||
| 8ad8d14cff | |||
| 55f5493fd1 | |||
| 30d0c4e632 | |||
| 4900858c22 | |||
| 745b3becf5 | |||
| 74dad352c3 | |||
| d3caf7c609 | |||
| 0309c38ebd | |||
| 4d9ce2370c | |||
| c0c73be6cb | |||
| 8010a38f2f | |||
| 19d68a0d47 | |||
| 39f792ec84 | |||
| 9fe291a3f3 | |||
| 77b2885776 | |||
| 3042b00962 | |||
| 93dd093454 | |||
| c8b5accf57 | |||
| 6581bb4bd3 | |||
| ee53e0d6af | |||
| 03bfb0cafa | |||
| 61a6713690 | |||
| acbb33241d | |||
| 1baaea24a2 | |||
| f2d0b7a94e | |||
| 7de2dc37d5 | |||
| 0c8e8bf539 | |||
| 6b6f7920d0 | |||
| e3e6192b50 | |||
| a17646e263 | |||
| 037b51464b | |||
| 1d2234ee66 | |||
| 53576a08f3 | |||
| 3d6bca3a5e | |||
| 4d8c9f2742 | |||
| d13f5dc513 | |||
| 0f303ba92b | |||
| 904a120efa | |||
| cefc5912bc | |||
| 9f7841f60d | |||
| 61e8bf5b49 | |||
| 2531ddf814 | |||
| 3b07a5d7d6 | |||
| 0550ff3fba | |||
| a01fde2ed9 | |||
| ef86a79bf6 | |||
| d534d3b8d0 | |||
| 916a21bcff | |||
| 1ed6eed14f | |||
| 0eb11a215f | |||
| d2221ce3c7 | |||
| 26585563ca | |||
| 705fa2cc37 | |||
| 5dc4c3d2a6 | |||
| 51e2d042f8 | |||
| f8b306538e | |||
| 2a063c0f20 | |||
| 2aaa3ace10 | |||
| 9ea63e0c1c | |||
| d8c098c761 | |||
| 85e7ce3b92 | |||
| fc852a1695 | |||
| be944dcd2c | |||
| 4ba4aae9c3 | |||
| 6785554155 | |||
| 2c6ae0b84c | |||
| 11e2ed0b8e | |||
| 700a98f832 | |||
| 924b30ae74 | |||
| 20678a2279 | |||
| fcc33cd084 | |||
| 13b88c0c81 | |||
| 8eb464ba85 | |||
| 511cf35fc6 | |||
| 2d7cbae786 | |||
| efa2ed5c1b | |||
| e170948652 | |||
| 258e7f8cab | |||
| 4e5693d1a4 | |||
| a79cc86c37 | |||
| cdbd9dddff | |||
| e97d7fbc8e | |||
| f0443dc328 | |||
| 2ae108f761 | |||
| e9d3185f7a | |||
| 50c5f6a9ae | |||
| 799028b6e7 | |||
| 2072054963 | |||
| a96f0d5e15 | |||
| ff948b5bcd | |||
| 99a3c5bb5b | |||
| 1417e62aea | |||
| bb03c2ee7b | |||
| 425482b94a | |||
| 02f26017bf | |||
| 62efffd7ad | |||
| 1d113084d4 | |||
| 72a7e6cdba | |||
| c454fee73b | |||
| 90247e87dd | |||
| a54581b883 | |||
| 7e3571efa9 | |||
| 2e9bc72f3b | |||
| b02a62cbae | |||
| 16a0614ae3 | |||
| 22b0a7dc86 | |||
| 396a1c7c45 | |||
| 214f943454 | |||
| 32d908adfb | |||
| 6768bf5af8 | |||
| 8a7fa7d17d | |||
| db6713fa3c | |||
| bbbc6b4198 | |||
| 309e4f9a23 | |||
| f236cf74fb | |||
| c0c6ec7711 | |||
| bdd9b18e5c | |||
| 9ea3fd2d2c | |||
| 945cefb87c | |||
| 74c47f66ad | |||
| 12393d18cb | |||
| cb0a5ccf21 | |||
| 00c7247e2f | |||
| 3b79abcb5e | |||
| 5ffb84d3ca | |||
| bcb9e41da8 | |||
| f6db0e7866 | |||
| 7341ffc943 | |||
| e06266abb5 | |||
| 90970bf18c | |||
| 0800dc1221 | |||
| 57ef748805 | |||
| fb1ac42514 | |||
| 330f1dc6e2 | |||
| 43bab13abd | |||
| f11c314954 | |||
| a91df705ac | |||
| a052dc1338 | |||
| bfe5d10a7d | |||
| e1f1c897e8 | |||
| ba5041f7bb | |||
| cb8fb66325 | |||
| 22b366553a | |||
| 1dffab446b | |||
| b514bcba01 | |||
| c0243dfafd | |||
| df7d846161 | |||
| ad85e9c2d3 | |||
| d19cafcdd1 | |||
| 1fa7ccadcd | |||
| 34a2f81761 | |||
| 6835cc9216 | |||
| bb38f46f0f | |||
| e55fab9d37 | |||
| 740d8a44f8 | |||
| baf85d8be9 | |||
| b3a87c1114 | |||
| 9ba95ecaf9 | |||
| 2e0b693663 | |||
| 2f596bbeba | |||
| 9a78866a56 | |||
| 58784d3648 | |||
| e22426a453 | |||
| fe3da2c1fd | |||
| 67b6c7c1a9 | |||
| 7ab2a28ca9 | |||
| 77a21a780c | |||
| ae509cd90a | |||
| f04843b510 | |||
| 5b6b815585 | |||
| 1a820d1dd7 | |||
| cdd78886ae | |||
| 053a0e8b78 | |||
| 863af956d9 | |||
| f4f3929463 | |||
| 96febc6582 | |||
| da082bd937 | |||
| 554e695b56 | |||
| 06ce89fcf6 | |||
| 684c75b685 | |||
| 442c1ba794 | |||
| c787feb964 | |||
| 58b282f00f | |||
| 472e549195 | |||
| 187737abc2 | |||
| 8d8bc098cc | |||
| fa078d278f | |||
| 9f7f57b093 | |||
| 09758fb6fe | |||
| 38878c03af | |||
| ab6dfc4459 | |||
| 9d7a893ad4 | |||
| 48c7de6aec | |||
| 2371778031 | |||
| aec054896e | |||
| 9c93b3b896 | |||
| 0c2c1f7c12 | |||
| 2d01f93692 | |||
| 7d7a0bc951 | |||
| 92f9ac93ef | |||
| d91230b55a | |||
| 00fabbe944 | |||
| 0b4d37d15b | |||
| 6222ef53ed | |||
| 4dffe9935f | |||
| 7a20e4d87a | |||
| d0f92ec22a | |||
| c4c5364d3e | |||
| 5c99022f7d | |||
| 573b434a39 | |||
| 4162c23c46 | |||
| 1116bc7043 | |||
| 32a3a7cc43 | |||
| 35a0f3fe6c | |||
| 0a0b8e52b4 | |||
| b77dc22838 | |||
| 40fbf99f9b | |||
| bc03572061 | |||
| c831837ecb | |||
| 9a3b1bcbca | |||
| e798aff9bb | |||
| f99a28d036 | |||
| 96ec5c4c14 | |||
| 8ee391aeef | |||
| a679b609cc | |||
| c9874b9244 | |||
| 3e2ba00093 | |||
| fc72bd38db | |||
| a633ed5e02 | |||
| c8c5fb1fc0 | |||
| cf6b87e99e | |||
| 5ce6d03987 | |||
| 3d568d2c43 | |||
| 75aa8f1e41 | |||
| dee935fabb | |||
| a20ed60252 | |||
| ee662900a5 | |||
| db6655e0af | |||
| 82c08e4055 | |||
| 816f5cc0cf | |||
| a5771a059f | |||
| dc0dd17052 | |||
| 9f5d66e392 | |||
| fb645e2d6b | |||
| 64d137fefc | |||
| af8cbf10db | |||
| da090bd22d | |||
| 3c4f95f73f | |||
| 96c6f7e07b | |||
| 47312577c9 | |||
| 1c435bbd5e | |||
| 4d0082acf8 | |||
| 058322d68a | |||
| 18a20dfee9 | |||
| 9b3e97711b | |||
| 55f6a14016 | |||
| e8a907912d | |||
| 3a0d6924fb | |||
| d317dedbb3 | |||
| d15e9e3279 | |||
| 260c6cc0ed | |||
| 1436a160af | |||
| a4a9d2530c | |||
| 1e5e67d2bc | |||
| 5eb8c27349 | |||
| 3ea5fc971d | |||
| 52de4c7182 | |||
| adc64e45b8 | |||
| a8ef869f65 | |||
| ca04437296 | |||
| 77f2df7a41 | |||
| 3de962edc9 | |||
| 344f5cbe7e | |||
| 4faf8cd19a | |||
| c69f29a23c | |||
| 52bc82a29b | |||
| 8cff48fde9 | |||
| e2fd53ab66 | |||
| 7b221d2e08 | |||
| 25960ab095 | |||
| e3c83cfe60 | |||
| cf2cbf51d2 | |||
| 6f58251f8d | |||
| d3c4189f16 | |||
| 4f6148fd2d | |||
| 5f791d0fc5 | |||
| 3e55b391c1 | |||
| 23d406d277 | |||
| 8588cbdcd3 | |||
| be8d1ecb70 | |||
| c2cc6055b3 | |||
| 9aba253d91 | |||
| 83b93836ae | |||
| 1169129f3d | |||
| 11ae4e96f3 | |||
| 18a79864eb | |||
| 6f45a2f25a | |||
| d352c53832 | |||
| d18f724ec8 | |||
| b6dbec51a5 | |||
| e673e43e70 | |||
| 5cd5be4c98 |
@@ -1,5 +0,0 @@
|
||||
version: 1
|
||||
update_configs:
|
||||
- package_manager: "javascript"
|
||||
directory: "/"
|
||||
update_schedule: "monthly"
|
||||
@@ -0,0 +1,8 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
day: tuesday
|
||||
open-pull-requests-limit: 10
|
||||
@@ -0,0 +1,16 @@
|
||||
on:
|
||||
[pull_request]
|
||||
|
||||
name: Check
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Run Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Run tests
|
||||
run: |
|
||||
npm ci
|
||||
npm test
|
||||
@@ -0,0 +1,71 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '0 0 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ['javascript']
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
@@ -0,0 +1,27 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
name: Package
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Package distribution file
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: master
|
||||
- name: Package
|
||||
run: |
|
||||
npm ci
|
||||
npm test
|
||||
npm run package
|
||||
- name: Commit
|
||||
run: |
|
||||
git config --global user.name "GitHub Actions"
|
||||
git add dist/
|
||||
git commit -m "chore: Update dist" || echo "No changes to commit"
|
||||
git push origin HEAD:master
|
||||
@@ -2,6 +2,7 @@ node_modules/
|
||||
|
||||
# Editors
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# Logs
|
||||
logs
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
queue_rules:
|
||||
- name: default
|
||||
conditions:
|
||||
# Conditions to get out of the queue (= merged)
|
||||
- status-success=Run Unit Tests
|
||||
- status-success=Semantic Pull Request
|
||||
|
||||
pull_request_rules:
|
||||
- name: Automatically merge on CI success and review approval
|
||||
conditions:
|
||||
- base~=master|integ-tests
|
||||
- "#approved-reviews-by>=1"
|
||||
- approved-reviews-by=@aws-actions/aws-ecs-devx
|
||||
- -approved-reviews-by~=author
|
||||
- status-success=Run Unit Tests
|
||||
- status-success=Semantic Pull Request
|
||||
- label!=work-in-progress
|
||||
- -title~=(WIP|wip)
|
||||
- -merged
|
||||
- -closed
|
||||
- author!=dependabot[bot]
|
||||
actions:
|
||||
queue:
|
||||
method: squash
|
||||
name: default
|
||||
|
||||
- name: Automatically approve and merge Dependabot PRs
|
||||
conditions:
|
||||
- base=master
|
||||
- author=dependabot[bot]
|
||||
- status-success=Run Unit Tests
|
||||
- status-success=Semantic Pull Request
|
||||
- -title~=(WIP|wip)
|
||||
- -label~=(blocked|do-not-merge)
|
||||
- -merged
|
||||
- -closed
|
||||
actions:
|
||||
review:
|
||||
type: APPROVE
|
||||
queue:
|
||||
method: squash
|
||||
name: default
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
# Changelog
|
||||
|
||||
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.
|
||||
|
||||
## [1.7.0](https://github.com/aws-actions/configure-aws-credentials/compare/v1.6.1...v1.7.0) (2022-08-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Allow audience to be explicitly specified ([2f8dfd0](https://github.com/aws-actions/configure-aws-credentials/commit/2f8dfd0ed43d880f85b57f0c8727b497af2037de))
|
||||
|
||||
### [1.6.1](https://github.com/aws-actions/configure-aws-credentials/compare/v1.6.0...v1.6.1) (2022-01-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* OIDC Parallel Requests error ([133757e](https://github.com/aws-actions/configure-aws-credentials/commit/133757e9b829f4ef44c8e99e3f272879b45fc9c5))
|
||||
* Strict Mode Deprecation ([4c5e1c6](https://github.com/aws-actions/configure-aws-credentials/commit/4c5e1c60ccfc95d0e48bf1bc95fc707a94aa2c60))
|
||||
|
||||
## [1.6.0](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.11...v1.6.0) (2021-11-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add the ability to use a web identity token file ([#240](https://github.com/aws-actions/configure-aws-credentials/issues/240)) ([8053174](https://github.com/aws-actions/configure-aws-credentials/commit/8053174404968575ac1dd102dcb1109d2fe6d9ea))
|
||||
* added OIDC ([#262](https://github.com/aws-actions/configure-aws-credentials/issues/262)) ([b8c74de](https://github.com/aws-actions/configure-aws-credentials/commit/b8c74de753fbcb4868bf2011fb2e15826ce973af)), closes [#267](https://github.com/aws-actions/configure-aws-credentials/issues/267)
|
||||
* upgraded to new GH OIDC API ([#284](https://github.com/aws-actions/configure-aws-credentials/issues/284)) ([036a4a1](https://github.com/aws-actions/configure-aws-credentials/commit/036a4a1ddf2c0e7a782dca6e083c6c53e5d90321))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* reverting update to use new API ([#274](https://github.com/aws-actions/configure-aws-credentials/issues/274)) ([a78fcb0](https://github.com/aws-actions/configure-aws-credentials/commit/a78fcb01f76c8c5c3b05ab82718a6f7919fc0269)), closes [#270](https://github.com/aws-actions/configure-aws-credentials/issues/270)
|
||||
* typo "charcters" in README.md ([#241](https://github.com/aws-actions/configure-aws-credentials/issues/241)) ([c48e1b5](https://github.com/aws-actions/configure-aws-credentials/commit/c48e1b578416f3457ccf757c47385df5c054d23f))
|
||||
* Updated token retrieval to use new API ([#270](https://github.com/aws-actions/configure-aws-credentials/issues/270)) ([20ce4e5](https://github.com/aws-actions/configure-aws-credentials/commit/20ce4e5ba1de2e753d034b5415075a8767d64d4d))
|
||||
|
||||
### [1.5.11](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.10...v1.5.11) (2021-07-19)
|
||||
|
||||
### [1.5.10](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.9...v1.5.10) (2021-06-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* skips session tagging ([#209](https://github.com/aws-actions/configure-aws-credentials/issues/209)) ([4900858](https://github.com/aws-actions/configure-aws-credentials/commit/4900858c22f8f07170e3032d4105f99c2aafa9e7))
|
||||
|
||||
### [1.5.9](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.8...v1.5.9) (2021-05-10)
|
||||
|
||||
### [1.5.8](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.7...v1.5.8) (2021-03-02)
|
||||
|
||||
### [1.5.7](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.6...v1.5.7) (2021-02-08)
|
||||
|
||||
### [1.5.6](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.5...v1.5.6) (2021-01-26)
|
||||
|
||||
### [1.5.5](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.4...v1.5.5) (2020-11-24)
|
||||
|
||||
### [1.5.4](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.3...v1.5.4) (2020-10-29)
|
||||
|
||||
### [1.5.3](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.2...v1.5.3) (2020-10-05)
|
||||
|
||||
### [1.5.2](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.1...v1.5.2) (2020-08-25)
|
||||
|
||||
### [1.5.1](https://github.com/aws-actions/configure-aws-credentials/compare/v1.5.0...v1.5.1) (2020-08-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* make GITHUB_REF env var optional ([#82](https://github.com/aws-actions/configure-aws-credentials/issues/82)) ([ba5041f](https://github.com/aws-actions/configure-aws-credentials/commit/ba5041f7bb4990ac5d10d9009de69e639ebee3df)), closes [#92](https://github.com/aws-actions/configure-aws-credentials/issues/92)
|
||||
|
||||
## [1.5.0](https://github.com/aws-actions/configure-aws-credentials/compare/v1.4.4...v1.5.0) (2020-07-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add post-job action cleanup of credentials and region env vars ([#101](https://github.com/aws-actions/configure-aws-credentials/issues/101)) ([d19cafc](https://github.com/aws-actions/configure-aws-credentials/commit/d19cafcdd1be7e3358f84574a00df37af494036a))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Mask assume role response in debug output ([#102](https://github.com/aws-actions/configure-aws-credentials/issues/102)) ([df7d846](https://github.com/aws-actions/configure-aws-credentials/commit/df7d84616183de7ed37e53e1980284a07e56b216))
|
||||
|
||||
### [1.4.4](https://github.com/aws-actions/configure-aws-credentials/compare/v1.4.3...v1.4.4) (2020-07-17)
|
||||
|
||||
### [1.4.3](https://github.com/aws-actions/configure-aws-credentials/compare/v1.4.2...v1.4.3) (2020-07-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Make tagging optional ([#92](https://github.com/aws-actions/configure-aws-credentials/issues/92)) ([baf85d8](https://github.com/aws-actions/configure-aws-credentials/commit/baf85d8be969f190df9bc9153f06958c32ef3828))
|
||||
|
||||
### [1.4.2](https://github.com/aws-actions/configure-aws-credentials/compare/v1.4.1...v1.4.2) (2020-06-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add comma to set of special characters ([#78](https://github.com/aws-actions/configure-aws-credentials/issues/78)) ([f04843b](https://github.com/aws-actions/configure-aws-credentials/commit/f04843b510a6c8adf77eed907a616cf00a99970d))
|
||||
|
||||
### [1.4.1](https://github.com/aws-actions/configure-aws-credentials/compare/v1.4.0...v1.4.1) (2020-06-09)
|
||||
|
||||
## [1.4.0](https://github.com/aws-actions/configure-aws-credentials/compare/v1.3.5...v1.4.0) (2020-06-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Refresh and validate credentials after setting env var creds ([#71](https://github.com/aws-actions/configure-aws-credentials/issues/71)) ([472e549](https://github.com/aws-actions/configure-aws-credentials/commit/472e549195ba1f153e9fb72e39dc2a094e5de13e))
|
||||
|
||||
### [1.3.5](https://github.com/aws-actions/configure-aws-credentials/compare/v1.3.4...v1.3.5) (2020-05-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* clear session token env var if present for non-session credentials ([#65](https://github.com/aws-actions/configure-aws-credentials/issues/65)) ([0c2c1f7](https://github.com/aws-actions/configure-aws-credentials/commit/0c2c1f7c129971b6f433551b1f4ba4a6a9cc8b70))
|
||||
|
||||
### [1.3.4](https://github.com/aws-actions/configure-aws-credentials/compare/v1.3.3...v1.3.4) (2020-05-18)
|
||||
|
||||
### [1.3.3](https://github.com/aws-actions/configure-aws-credentials/compare/v1.3.2...v1.3.3) (2020-04-02)
|
||||
|
||||
### [1.3.2](https://github.com/aws-actions/configure-aws-credentials/compare/v1.3.1...v1.3.2) (2020-03-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* let the AWS SDK determine the STS regional endpoint ([#48](https://github.com/aws-actions/configure-aws-credentials/issues/48)) ([fc72bd3](https://github.com/aws-actions/configure-aws-credentials/commit/fc72bd38dbe25493f5113760c9c6e1ef2f6f9a0e))
|
||||
|
||||
### [1.3.1](https://github.com/aws-actions/configure-aws-credentials/compare/v1.3.0...v1.3.1) (2020-03-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* validate region input string ([#44](https://github.com/aws-actions/configure-aws-credentials/issues/44)) ([3d568d2](https://github.com/aws-actions/configure-aws-credentials/commit/3d568d2c4359304d46d9bd1b4d9f69e088ccbf7b))
|
||||
|
||||
## [1.3.0](https://github.com/aws-actions/configure-aws-credentials/compare/v1.2.0...v1.3.0) (2020-03-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* don't require access key credentials for self-hosted runners ([#42](https://github.com/aws-actions/configure-aws-credentials/issues/42)) ([a20ed60](https://github.com/aws-actions/configure-aws-credentials/commit/a20ed6025224ca999786c8d4e687f119cfedec65))
|
||||
|
||||
## [1.2.0](https://github.com/aws-actions/configure-aws-credentials/compare/v1.1.2...v1.2.0) (2020-03-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add option to provide external ID ([#32](https://github.com/aws-actions/configure-aws-credentials/issues/32)) ([1c435bb](https://github.com/aws-actions/configure-aws-credentials/commit/1c435bbd5e1f1d36cdd703da5c4d6ee1ad91efac)), closes [#28](https://github.com/aws-actions/configure-aws-credentials/issues/28)
|
||||
* Have an ability to configure session name ([#29](https://github.com/aws-actions/configure-aws-credentials/issues/29)) ([4d0082a](https://github.com/aws-actions/configure-aws-credentials/commit/4d0082acf8b4102597f2570a056a320194f13e63))
|
||||
* infer role ARN if given role name ([#35](https://github.com/aws-actions/configure-aws-credentials/issues/35)) ([96c6f7e](https://github.com/aws-actions/configure-aws-credentials/commit/96c6f7e07b5fabc5a907fce84745ea625eeb005d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* mask both source and role credentials ([#40](https://github.com/aws-actions/configure-aws-credentials/issues/40)) ([816f5cc](https://github.com/aws-actions/configure-aws-credentials/commit/816f5cc0cf79541b2a6d639e8f93ae43aadaf09c))
|
||||
|
||||
### [1.1.2](https://github.com/aws-actions/configure-aws-credentials/compare/v1.1.1...v1.1.2) (2020-02-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* change sanitization character from '*' to '_' ([55f6a14](https://github.com/aws-actions/configure-aws-credentials/commit/55f6a14016cb47190b15751dcce450441bba35e3))
|
||||
|
||||
### [1.1.1](https://github.com/aws-actions/configure-aws-credentials/compare/v1.1.0...v1.1.1) (2020-02-07)
|
||||
|
||||
## [1.1.0](https://github.com/aws-actions/configure-aws-credentials/compare/v1.0.1...v1.1.0) (2020-02-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add support for assuming a role ([#17](https://github.com/aws-actions/configure-aws-credentials/issues/17)) ([25960ab](https://github.com/aws-actions/configure-aws-credentials/commit/25960ab0950f92074b17fa0cb8ff33eeaa1615f0))
|
||||
* Build and integ test scripts for pipeline ([52bc82a](https://github.com/aws-actions/configure-aws-credentials/commit/52bc82a29bb08f2f8f87a92f380149945eb8d6f1))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* create workflows dir in integ-tests ([3de962e](https://github.com/aws-actions/configure-aws-credentials/commit/3de962edc9fe1169ff6032bef94b934be53211d1))
|
||||
* remove buildspecs ([260c6cc](https://github.com/aws-actions/configure-aws-credentials/commit/260c6cc0ed07cbd8ff2a7a74066ad9f67ecc82f7))
|
||||
* remove release script ([1436a16](https://github.com/aws-actions/configure-aws-credentials/commit/1436a160af84c3a086a812f98daf457a042274cb))
|
||||
* resolve commit ID in integ test script ([77f2df7](https://github.com/aws-actions/configure-aws-credentials/commit/77f2df7a41882637145683bb1acf60bb04fddc24))
|
||||
* sanitize AWS session tags ([#20](https://github.com/aws-actions/configure-aws-credentials/issues/20)) ([4faf8cd](https://github.com/aws-actions/configure-aws-credentials/commit/4faf8cd19a5b6cc50c9c66c89dd32d7e6e51bd8a))
|
||||
* set role credentials as secrets to mask them in logs ([#19](https://github.com/aws-actions/configure-aws-credentials/issues/19)) ([e2fd53a](https://github.com/aws-actions/configure-aws-credentials/commit/e2fd53ab66a094843f790497dcc950894c245786))
|
||||
@@ -2,6 +2,21 @@
|
||||
|
||||
Configure AWS credential and region environment variables for use in other GitHub Actions. The environment variables will be detected by both the AWS SDKs and the AWS CLI to determine the credentials and region to use for AWS API calls.
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Usage](#usage)
|
||||
- [Credentials](#credentials)
|
||||
- [Assuming a Role](#assuming-a-role)
|
||||
+ [Session tagging](#session-tagging)
|
||||
+ [Sample IAM Role Permissions](#sample-iam-role-cloudformation-template)
|
||||
- [Self-Hosted Runners](#self-hosted-runners)
|
||||
- [License Summary](#license-summary)
|
||||
- [Security Disclosures](#security-disclosures)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Usage
|
||||
|
||||
Add the following step to your workflow:
|
||||
@@ -10,20 +25,235 @@ Add the following step to your workflow:
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||
aws-region: us-east-2
|
||||
```
|
||||
|
||||
For example, you can use this action with the AWS CLI available in [GitHub's hosted virtual environments](https://help.github.com/en/actions/reference/software-installed-on-github-hosted-runners).
|
||||
You can also run this action multiple times to use different AWS accounts, regions, or IAM roles in the same GitHub Actions workflow job.
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deploy:
|
||||
name: Upload to Amazon S3
|
||||
runs-on: ubuntu-latest
|
||||
# These permissions are needed to interact with GitHub's OIDC Token endpoint.
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Configure AWS credentials from Test account
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::111111111111:role/my-github-actions-role-test
|
||||
aws-region: us-east-1
|
||||
|
||||
- name: Copy files to the test website with the AWS CLI
|
||||
run: |
|
||||
aws s3 sync . s3://my-s3-test-website-bucket
|
||||
|
||||
- name: Configure AWS credentials from Production account
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::222222222222:role/my-github-actions-role-prod
|
||||
aws-region: us-west-2
|
||||
|
||||
- name: Copy files to the production website with the AWS CLI
|
||||
run: |
|
||||
aws s3 sync . s3://my-s3-prod-website-bucket
|
||||
```
|
||||
|
||||
See [action.yml](action.yml) for the full documentation for this action's inputs and outputs.
|
||||
|
||||
## Credentials
|
||||
|
||||
We recommend following [Amazon IAM best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) for the AWS credentials used in GitHub Actions workflows, including:
|
||||
* Do not store credentials in your repository's code. You may use [GitHub Actions secrets](https://help.github.com/en/github/automating-your-workflow-with-github-actions/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables) to store credentials and redact credentials from GitHub Actions workflow logs.
|
||||
* [Create an individual IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users) with an access key for use in GitHub Actions workflows, preferably one per repository. Do not use the AWS account root user access key.
|
||||
* Do not store credentials in your repository's code.
|
||||
* [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) to the credentials used in GitHub Actions workflows. Grant only the permissions required to perform the actions in your GitHub Actions workflows.
|
||||
* [Rotate the credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#rotate-credentials) used in GitHub Actions workflows regularly.
|
||||
* [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log) of the credentials used in GitHub Actions workflows.
|
||||
|
||||
## Assuming a Role
|
||||
We recommend using GitHub's OIDC provider to get short-lived credentials needed for your actions.
|
||||
Specifying `role-to-assume` without providing an `aws-access-key-id` or a `web-identity-token-file` will signal to the action that you wish to use the OIDC provider.
|
||||
The default session duration is 1 hour when using the OIDC provider to directly assume an IAM Role.
|
||||
The default session duration is 6 hours when using an IAM User to assume an IAM Role (by providing an `aws-access-key-id`, `aws-secret-access-key`, and a `role-to-assume`) .
|
||||
If you would like to adjust this you can pass a duration to `role-duration-seconds`, but the duration cannot exceed the maximum that was defined when the IAM Role was created.
|
||||
The default session name is GitHubActions, and you can modify it by specifying the desired name in `role-session-name`.
|
||||
The default audience is `sts.amazonaws.com` which you can replace by specifying the desired audience name in `audience`.
|
||||
|
||||
The following table describes which identity is used based on which values are supplied to the Action:
|
||||
|
||||
| **Identity Used** | `aws-access-key-id` | `role-to-assume` | `web-identity-token-file` |
|
||||
|------------------------------------------------------------------|---------------------|------------------|---------------------------|
|
||||
| [✅ Recommended] Assume Role directly using GitHub OIDC provider | | ✔ | |
|
||||
| IAM User | ✔ | | |
|
||||
| Assume Role using IAM User credentials | ✔ | ✔ | |
|
||||
| Assume Role using WebIdentity Token File credentials | | ✔ | ✔ |
|
||||
|
||||
### Examples
|
||||
|
||||
```yaml
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||
role-session-name: MySessionName
|
||||
```
|
||||
In this example, the Action will load the OIDC token from the GitHub-provided environment variable and use it to assume the role `arn:aws:iam::123456789100:role/my-github-actions-role` with the session name `MySessionName`.
|
||||
|
||||
```yaml
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-east-2
|
||||
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
|
||||
role-external-id: ${{ secrets.AWS_ROLE_EXTERNAL_ID }}
|
||||
role-duration-seconds: 1200
|
||||
role-session-name: MySessionName
|
||||
```
|
||||
In this example, the secret `AWS_ROLE_TO_ASSUME` contains a string like `arn:aws:iam::123456789100:role/my-github-actions-role`. To assume a role in the same account as the static credentials, you can simply specify the role name, like `role-to-assume: my-github-actions-role`.
|
||||
|
||||
```yaml
|
||||
- name: Configure AWS Credentials for Beta Customers
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
audience: beta-customers
|
||||
aws-region: us-east-3
|
||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||
role-session-name: MySessionName
|
||||
```
|
||||
In this example, the audience has been changed from the default to use a different audience name `beta-customers`. This can help ensure that the role can only affect those AWS accounts whose GitHub OIDC providers have explicitly opted in to the `beta-customers` label.
|
||||
|
||||
Changing the default audience may be necessary when using non-default [AWS partitions](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html).
|
||||
|
||||
### Sample IAM Role CloudFormation Template
|
||||
```yaml
|
||||
Parameters:
|
||||
GitHubOrg:
|
||||
Type: String
|
||||
RepositoryName:
|
||||
Type: String
|
||||
OIDCProviderArn:
|
||||
Description: Arn for the GitHub OIDC Provider.
|
||||
Default: ""
|
||||
Type: String
|
||||
|
||||
Conditions:
|
||||
CreateOIDCProvider: !Equals
|
||||
- !Ref OIDCProviderArn
|
||||
- ""
|
||||
|
||||
Resources:
|
||||
Role:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action: sts:AssumeRoleWithWebIdentity
|
||||
Principal:
|
||||
Federated: !If
|
||||
- CreateOIDCProvider
|
||||
- !Ref GithubOidc
|
||||
- !Ref OIDCProviderArn
|
||||
Condition:
|
||||
StringLike:
|
||||
token.actions.githubusercontent.com:sub: !Sub repo:${GitHubOrg}/${RepositoryName}:*
|
||||
|
||||
GithubOidc:
|
||||
Type: AWS::IAM::OIDCProvider
|
||||
Condition: CreateOIDCProvider
|
||||
Properties:
|
||||
Url: https://token.actions.githubusercontent.com
|
||||
ClientIdList:
|
||||
- sts.amazonaws.com
|
||||
ThumbprintList:
|
||||
- 6938fd4d98bab03faadb97b34396831e3780aea1
|
||||
|
||||
Outputs:
|
||||
Role:
|
||||
Value: !GetAtt Role.Arn
|
||||
```
|
||||
|
||||
The GitHub OIDC Provider only needs to be created once per account (i.e. multiple IAM Roles that can be assumed by the GitHub's OIDC can share a single OIDC Provider)
|
||||
|
||||
### Session tagging
|
||||
The session will have the name "GitHubActions" and be tagged with the following tags:
|
||||
(`GITHUB_` environment variable definitions can be [found here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables))
|
||||
|
||||
| Key | Value|
|
||||
| --- | --- |
|
||||
| GitHub | "Actions" |
|
||||
| Repository | GITHUB_REPOSITORY |
|
||||
| Workflow | GITHUB_WORKFLOW |
|
||||
| Action | GITHUB_ACTION |
|
||||
| Actor | GITHUB_ACTOR |
|
||||
| Branch | GITHUB_REF |
|
||||
| Commit | GITHUB_SHA |
|
||||
|
||||
_Note: all tag values must conform to [the requirements](https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html). Particularly, `GITHUB_WORKFLOW` will be truncated if it's too long. If `GITHUB_ACTOR` or `GITHUB_WORKFLOW` contain invalid characters, the characters will be replaced with an '*'._
|
||||
|
||||
The action will use session tagging by default during role assumption.
|
||||
Note that for WebIdentity role assumption, the session tags have to be included in the encoded WebIdentity token.
|
||||
This means that Tags can only be supplied by the OIDC provider and not set during the AssumeRoleWithWebIdentity API call within the Action.
|
||||
You can skip this session tagging by providing `role-skip-session-tagging` as true in the action's inputs:
|
||||
|
||||
```yaml
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
role-skip-session-tagging: true
|
||||
```
|
||||
|
||||
## Self-Hosted Runners
|
||||
|
||||
If you run your GitHub Actions in a [self-hosted runner](https://help.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners) that already has access to AWS credentials, such as an EC2 instance, then you do not need to provide IAM user access key credentials to this action.
|
||||
|
||||
If no access key credentials are given in the action inputs, this action will use credentials from the runner environment using the [default methods for the AWS SDK for Javascript](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html).
|
||||
|
||||
You can use this action to simply configure the region and account ID in the environment, and then use the runner's credentials for all AWS API calls made by your Actions workflow:
|
||||
```yaml
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
```
|
||||
In this case, your runner's credentials must have permissions to call any AWS APIs called by your Actions workflow.
|
||||
|
||||
Or, you can use this action to assume a role, and then use the role credentials for all AWS API calls made by your Actions workflow:
|
||||
```yaml
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: my-github-actions-role
|
||||
```
|
||||
In this case, your runner's credentials must have permissions to assume the role.
|
||||
|
||||
You can also assume a role using a web identity token file, such as if using [Amazon EKS IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html).
|
||||
Pods running in EKS worker nodes that do not run as root can use this file to assume a role with a web identity.
|
||||
|
||||
You can configure your workflow as follows in order to use this file:
|
||||
```yaml
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: my-github-actions-role
|
||||
web-identity-token-file: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
|
||||
```
|
||||
|
||||
### Use with the AWS CLI
|
||||
|
||||
This workflow does _not_ install the [AWS CLI](https://aws.amazon.com/cli/) into your environment. Self-hosted runners that intend to run this action prior to executing `aws` commands need to have the AWS CLI [installed](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) if it's not already present.
|
||||
Most [GitHub hosted runner environments](https://github.com/actions/virtual-environments) should include the AWS CLI by default.
|
||||
|
||||
## License Summary
|
||||
|
||||
This code is made available under the MIT license.
|
||||
|
||||
## Security Disclosures
|
||||
|
||||
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 [here](https://aws.amazon.com/security/vulnerability-reporting/) or [email AWS security directly](mailto:aws-security@amazon.com).
|
||||
|
||||
+42
-5
@@ -4,12 +4,22 @@ branding:
|
||||
icon: 'cloud'
|
||||
color: 'orange'
|
||||
inputs:
|
||||
audience:
|
||||
default: 'sts.amazonaws.com'
|
||||
description: 'The audience to use for the OIDC provider'
|
||||
required: false
|
||||
aws-access-key-id:
|
||||
description: 'AWS Access Key ID'
|
||||
required: true
|
||||
description: >-
|
||||
AWS Access Key ID. This input is required if running in the GitHub hosted environment.
|
||||
It is optional if running in a self-hosted environment that already has AWS credentials,
|
||||
for example on an EC2 instance.
|
||||
required: false
|
||||
aws-secret-access-key:
|
||||
description: 'AWS Secret Access Key'
|
||||
required: true
|
||||
description: >-
|
||||
AWS Secret Access Key. This input is required if running in the GitHub hosted environment.
|
||||
It is optional if running in a self-hosted environment that already has AWS credentials,
|
||||
for example on an EC2 instance.
|
||||
required: false
|
||||
aws-session-token:
|
||||
description: 'AWS Session Token'
|
||||
required: false
|
||||
@@ -17,7 +27,33 @@ inputs:
|
||||
description: 'AWS Region, e.g. us-east-2'
|
||||
required: true
|
||||
mask-aws-account-id:
|
||||
description: "Whether to set the AWS account ID for these credentials as a secret value, so that it is masked in logs. Valid values are 'true' and 'false'. Defaults to true"
|
||||
description: >-
|
||||
Whether to set the AWS account ID for these credentials as a secret value,
|
||||
so that it is masked in logs. Valid values are 'true' and 'false'.
|
||||
Defaults to true
|
||||
required: false
|
||||
role-to-assume:
|
||||
description: >-
|
||||
Use the provided credentials to assume an IAM role and configure the Actions
|
||||
environment with the assumed role credentials rather than with the provided
|
||||
credentials
|
||||
required: false
|
||||
web-identity-token-file:
|
||||
description: >-
|
||||
Use the web identity token file from the provided file system path in order to
|
||||
assume an IAM role using a web identity. E.g., from within an Amazon EKS worker node
|
||||
required: false
|
||||
role-duration-seconds:
|
||||
description: "Role duration in seconds (default: 6 hours)"
|
||||
required: false
|
||||
role-session-name:
|
||||
description: 'Role session name (default: GitHubActions)'
|
||||
required: false
|
||||
role-external-id:
|
||||
description: 'The external ID of the role to assume'
|
||||
required: false
|
||||
role-skip-session-tagging:
|
||||
description: 'Skip session tagging during role assumption'
|
||||
required: false
|
||||
outputs:
|
||||
aws-account-id:
|
||||
@@ -25,3 +61,4 @@ outputs:
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'dist/index.js'
|
||||
post: 'dist/cleanup/index.js'
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
const core = require('@actions/core');
|
||||
|
||||
/**
|
||||
* When the GitHub Actions job is done, clean up any environment variables that
|
||||
* may have been set by the configure-aws-credentials steps in the job.
|
||||
*
|
||||
* Environment variables are not intended to be shared across different jobs in
|
||||
* the same GitHub Actions workflow: GitHub Actions documentation states that
|
||||
* each job runs in a fresh instance. However, doing our own cleanup will
|
||||
* give us additional assurance that these environment variables are not shared
|
||||
* with any other jobs.
|
||||
*/
|
||||
|
||||
async function cleanup() {
|
||||
try {
|
||||
// The GitHub Actions toolkit does not have an option to completely unset
|
||||
// environment variables, so we overwrite the current value with an empty
|
||||
// string. The AWS CLI and AWS SDKs will behave correctly: they treat an
|
||||
// empty string value as if the environment variable does not exist.
|
||||
core.exportVariable('AWS_ACCESS_KEY_ID', '');
|
||||
core.exportVariable('AWS_SECRET_ACCESS_KEY', '');
|
||||
core.exportVariable('AWS_SESSION_TOKEN', '');
|
||||
core.exportVariable('AWS_DEFAULT_REGION', '');
|
||||
core.exportVariable('AWS_REGION', '');
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = cleanup;
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (require.main === module) {
|
||||
cleanup();
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
const core = require('@actions/core');
|
||||
const cleanup = require('./cleanup.js');
|
||||
|
||||
jest.mock('@actions/core');
|
||||
|
||||
const FAKE_ACCESS_KEY_ID = 'MY-AWS-ACCESS-KEY-ID';
|
||||
const FAKE_SECRET_ACCESS_KEY = 'MY-AWS-SECRET-ACCESS-KEY';
|
||||
const FAKE_SESSION_TOKEN = 'MY-AWS-SESSION-TOKEN';
|
||||
const FAKE_REGION = 'fake-region-1';
|
||||
const ACTION_ENVIRONMENT_VARIABLES = {
|
||||
AWS_ACCESS_KEY_ID: FAKE_ACCESS_KEY_ID,
|
||||
AWS_SECRET_ACCESS_KEY: FAKE_SECRET_ACCESS_KEY,
|
||||
AWS_SESSION_TOKEN: FAKE_SESSION_TOKEN,
|
||||
AWS_DEFAULT_REGION: FAKE_REGION,
|
||||
AWS_REGION: FAKE_REGION,
|
||||
};
|
||||
|
||||
describe('Configure AWS Credentials', () => {
|
||||
const OLD_ENV = process.env;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
process.env = {...OLD_ENV, ...ACTION_ENVIRONMENT_VARIABLES};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env = OLD_ENV;
|
||||
});
|
||||
|
||||
test('replaces AWS credential and region env vars with empty strings', async () => {
|
||||
await cleanup();
|
||||
expect(core.setFailed).toHaveBeenCalledTimes(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', '');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', '');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', '');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', '');
|
||||
});
|
||||
|
||||
test('error is caught and fails the action', async () => {
|
||||
core.exportVariable.mockReset();
|
||||
core.exportVariable.mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
|
||||
await cleanup();
|
||||
|
||||
expect(core.setFailed).toBeCalled();
|
||||
});
|
||||
});
|
||||
Vendored
+1719
File diff suppressed because it is too large
Load Diff
Vendored
+9238
-6715
File diff suppressed because one or more lines are too long
@@ -1,53 +1,375 @@
|
||||
const core = require('@actions/core');
|
||||
const aws = require('aws-sdk');
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// The max time that a GitHub action is allowed to run is 6 hours.
|
||||
// That seems like a reasonable default to use if no role duration is defined.
|
||||
const MAX_ACTION_RUNTIME = 6 * 3600;
|
||||
const DEFAULT_ROLE_DURATION_FOR_OIDC_ROLES = 3600;
|
||||
const USER_AGENT = 'configure-aws-credentials-for-github-actions';
|
||||
const MAX_TAG_VALUE_LENGTH = 256;
|
||||
const SANITIZATION_CHARACTER = '_';
|
||||
const ROLE_SESSION_NAME = 'GitHubActions';
|
||||
const REGION_REGEX = /^[a-z0-9-]+$/g;
|
||||
|
||||
async function assumeRole(params) {
|
||||
// Assume a role to get short-lived credentials using longer-lived credentials.
|
||||
const isDefined = i => !!i;
|
||||
|
||||
const {
|
||||
sourceAccountId,
|
||||
roleToAssume,
|
||||
roleExternalId,
|
||||
roleDurationSeconds,
|
||||
roleSessionName,
|
||||
region,
|
||||
roleSkipSessionTagging,
|
||||
webIdentityTokenFile,
|
||||
webIdentityToken
|
||||
} = params;
|
||||
assert(
|
||||
[roleToAssume, roleDurationSeconds, roleSessionName, region].every(isDefined),
|
||||
"Missing required input when assuming a Role."
|
||||
);
|
||||
|
||||
const {GITHUB_REPOSITORY, GITHUB_WORKFLOW, GITHUB_ACTION, GITHUB_ACTOR, GITHUB_SHA} = process.env;
|
||||
assert(
|
||||
[GITHUB_REPOSITORY, GITHUB_WORKFLOW, GITHUB_ACTION, GITHUB_ACTOR, GITHUB_SHA].every(isDefined),
|
||||
'Missing required environment value. Are you running in GitHub Actions?'
|
||||
);
|
||||
|
||||
const sts = getStsClient(region);
|
||||
|
||||
let roleArn = roleToAssume;
|
||||
if (!roleArn.startsWith('arn:aws')) {
|
||||
// Supports only 'aws' partition. Customers in other partitions ('aws-cn') will need to provide full ARN
|
||||
assert(
|
||||
isDefined(sourceAccountId),
|
||||
"Source Account ID is needed if the Role Name is provided and not the Role Arn."
|
||||
);
|
||||
roleArn = `arn:aws:iam::${sourceAccountId}:role/${roleArn}`;
|
||||
}
|
||||
|
||||
const tagArray = [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: sanitizeGithubWorkflowName(GITHUB_WORKFLOW)},
|
||||
{Key: 'Action', Value: GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: sanitizeGithubActor(GITHUB_ACTOR)},
|
||||
{Key: 'Commit', Value: GITHUB_SHA},
|
||||
];
|
||||
|
||||
if (isDefined(process.env.GITHUB_REF)) {
|
||||
tagArray.push({Key: 'Branch', Value: process.env.GITHUB_REF});
|
||||
}
|
||||
|
||||
const roleSessionTags = roleSkipSessionTagging ? undefined : tagArray;
|
||||
|
||||
if(roleSessionTags == undefined){
|
||||
core.debug("Role session tagging has been skipped.")
|
||||
} else {
|
||||
core.debug(roleSessionTags.length + " role session tags are being used.")
|
||||
}
|
||||
|
||||
const assumeRoleRequest = {
|
||||
RoleArn: roleArn,
|
||||
RoleSessionName: roleSessionName,
|
||||
DurationSeconds: roleDurationSeconds,
|
||||
Tags: roleSessionTags
|
||||
};
|
||||
|
||||
if (roleExternalId) {
|
||||
assumeRoleRequest.ExternalId = roleExternalId;
|
||||
}
|
||||
|
||||
let assumeFunction = sts.assumeRole.bind(sts);
|
||||
|
||||
// These are customizations needed for the GH OIDC Provider
|
||||
if(isDefined(webIdentityToken)) {
|
||||
delete assumeRoleRequest.Tags;
|
||||
|
||||
assumeRoleRequest.WebIdentityToken = webIdentityToken;
|
||||
assumeFunction = sts.assumeRoleWithWebIdentity.bind(sts);
|
||||
} else if(isDefined(webIdentityTokenFile)) {
|
||||
core.debug("webIdentityTokenFile provided. Will call sts:AssumeRoleWithWebIdentity and take session tags from token contents.");
|
||||
delete assumeRoleRequest.Tags;
|
||||
|
||||
const webIdentityTokenFilePath = path.isAbsolute(webIdentityTokenFile) ?
|
||||
webIdentityTokenFile :
|
||||
path.join(process.env.GITHUB_WORKSPACE, webIdentityTokenFile);
|
||||
|
||||
if (!fs.existsSync(webIdentityTokenFilePath)) {
|
||||
throw new Error(`Web identity token file does not exist: ${webIdentityTokenFilePath}`);
|
||||
}
|
||||
|
||||
try {
|
||||
assumeRoleRequest.WebIdentityToken = await fs.promises.readFile(webIdentityTokenFilePath, 'utf8');
|
||||
assumeFunction = sts.assumeRoleWithWebIdentity.bind(sts);
|
||||
} catch(error) {
|
||||
throw new Error(`Web identity token file could not be read: ${error.message}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return assumeFunction(assumeRoleRequest)
|
||||
.promise()
|
||||
.then(function (data) {
|
||||
return {
|
||||
accessKeyId: data.Credentials.AccessKeyId,
|
||||
secretAccessKey: data.Credentials.SecretAccessKey,
|
||||
sessionToken: data.Credentials.SessionToken,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function sanitizeGithubActor(actor) {
|
||||
// In some circumstances the actor may contain square brackets. For example, if they're a bot ('[bot]')
|
||||
// Square brackets are not allowed in AWS session tags
|
||||
return actor.replace(/\[|\]/g, SANITIZATION_CHARACTER)
|
||||
}
|
||||
|
||||
function sanitizeGithubWorkflowName(name) {
|
||||
// Workflow names can be almost any valid UTF-8 string, but tags are more restrictive.
|
||||
// This replaces anything not conforming to the tag restrictions by inverting the regular expression.
|
||||
// See the AWS documentation for constraint specifics https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html.
|
||||
const nameWithoutSpecialCharacters = name.replace(/[^\p{L}\p{Z}\p{N}_:/=+.-@-]/gu, SANITIZATION_CHARACTER);
|
||||
const nameTruncated = nameWithoutSpecialCharacters.slice(0, MAX_TAG_VALUE_LENGTH)
|
||||
return nameTruncated
|
||||
}
|
||||
|
||||
function exportCredentials(params){
|
||||
// Configure the AWS CLI and AWS SDKs using environment variables and set them as secrets.
|
||||
// Setting the credentials as secrets masks them in Github Actions logs
|
||||
const {accessKeyId, secretAccessKey, sessionToken} = params;
|
||||
|
||||
// AWS_ACCESS_KEY_ID:
|
||||
// Specifies an AWS access key associated with an IAM user or role
|
||||
core.setSecret(accessKeyId);
|
||||
core.exportVariable('AWS_ACCESS_KEY_ID', accessKeyId);
|
||||
|
||||
// AWS_SECRET_ACCESS_KEY:
|
||||
// Specifies the secret key associated with the access key. This is essentially the "password" for the access key.
|
||||
core.setSecret(secretAccessKey);
|
||||
core.exportVariable('AWS_SECRET_ACCESS_KEY', secretAccessKey);
|
||||
|
||||
// AWS_SESSION_TOKEN:
|
||||
// Specifies the session token value that is required if you are using temporary security credentials.
|
||||
if (sessionToken) {
|
||||
core.setSecret(sessionToken);
|
||||
core.exportVariable('AWS_SESSION_TOKEN', sessionToken);
|
||||
} else if (process.env.AWS_SESSION_TOKEN) {
|
||||
// clear session token from previous credentials action
|
||||
core.exportVariable('AWS_SESSION_TOKEN', '');
|
||||
}
|
||||
}
|
||||
|
||||
function exportRegion(region) {
|
||||
// AWS_DEFAULT_REGION and AWS_REGION:
|
||||
// Specifies the AWS Region to send requests to
|
||||
core.exportVariable('AWS_DEFAULT_REGION', region);
|
||||
core.exportVariable('AWS_REGION', region);
|
||||
}
|
||||
|
||||
async function exportAccountId(maskAccountId, region) {
|
||||
// Get the AWS account ID
|
||||
const sts = getStsClient(region);
|
||||
const identity = await sts.getCallerIdentity().promise();
|
||||
const accountId = identity.Account;
|
||||
if (!maskAccountId || maskAccountId.toLowerCase() == 'true') {
|
||||
core.setSecret(accountId);
|
||||
}
|
||||
core.setOutput('aws-account-id', accountId);
|
||||
return accountId;
|
||||
}
|
||||
|
||||
function loadCredentials() {
|
||||
// Force the SDK to re-resolve credentials with the default provider chain.
|
||||
//
|
||||
// This action typically sets credentials in the environment via environment variables.
|
||||
// The SDK never refreshes those env-var-based credentials after initial load.
|
||||
// In case there were already env-var creds set in the actions environment when this action
|
||||
// loaded, this action needs to refresh the SDK creds after overwriting those environment variables.
|
||||
//
|
||||
// The credentials object needs to be entirely recreated (instead of simply refreshed),
|
||||
// because the credential object type could change when this action writes env var creds.
|
||||
// For example, the first load could return EC2 instance metadata credentials
|
||||
// in a self-hosted runner, and the second load could return environment credentials
|
||||
// from an assume-role call in this action.
|
||||
aws.config.credentials = null;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
aws.config.getCredentials((err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve(aws.config.credentials);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
async function validateCredentials(expectedAccessKeyId) {
|
||||
let credentials;
|
||||
try {
|
||||
credentials = await loadCredentials();
|
||||
|
||||
if (!credentials.accessKeyId) {
|
||||
throw new Error('Access key ID empty after loading credentials');
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Credentials could not be loaded, please check your action inputs: ${error.message}`);
|
||||
}
|
||||
|
||||
const actualAccessKeyId = credentials.accessKeyId;
|
||||
|
||||
if (expectedAccessKeyId && expectedAccessKeyId != actualAccessKeyId) {
|
||||
throw new Error('Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action');
|
||||
}
|
||||
}
|
||||
|
||||
function getStsClient(region) {
|
||||
return new aws.STS({
|
||||
region,
|
||||
stsRegionalEndpoints: 'regional',
|
||||
customUserAgent: USER_AGENT
|
||||
});
|
||||
}
|
||||
|
||||
let defaultSleep = function (ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
};
|
||||
let sleep = defaultSleep;
|
||||
|
||||
// retryAndBackoff retries with exponential backoff the promise if the error isRetryable upto maxRetries time.
|
||||
const retryAndBackoff = async (fn, isRetryable, retries = 0, maxRetries = 12, base = 50) => {
|
||||
try {
|
||||
return await fn();
|
||||
} catch (err) {
|
||||
if (!isRetryable) {
|
||||
throw err;
|
||||
}
|
||||
// It's retryable, so sleep and retry.
|
||||
await sleep(Math.random() * (Math.pow(2, retries) * base) );
|
||||
retries += 1;
|
||||
if (retries === maxRetries) {
|
||||
throw err;
|
||||
}
|
||||
return await retryAndBackoff(fn, isRetryable, retries, maxRetries, base);
|
||||
}
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
// Get inputs
|
||||
const accessKeyId = core.getInput('aws-access-key-id', { required: true });
|
||||
const secretAccessKey = core.getInput('aws-secret-access-key', { required: true });
|
||||
const accessKeyId = core.getInput('aws-access-key-id', { required: false });
|
||||
const audience = core.getInput('audience', { required: false });
|
||||
const secretAccessKey = core.getInput('aws-secret-access-key', { required: false });
|
||||
const region = core.getInput('aws-region', { required: true });
|
||||
const sessionToken = core.getInput('aws-session-token', { required: false });
|
||||
const maskAccountId = core.getInput('mask-aws-account-id', { required: false });
|
||||
const roleToAssume = core.getInput('role-to-assume', {required: false});
|
||||
const roleExternalId = core.getInput('role-external-id', { required: false });
|
||||
let roleDurationSeconds = core.getInput('role-duration-seconds', {required: false}) || MAX_ACTION_RUNTIME;
|
||||
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
|
||||
const roleSkipSessionTaggingInput = core.getInput('role-skip-session-tagging', { required: false })|| 'false';
|
||||
const roleSkipSessionTagging = roleSkipSessionTaggingInput.toLowerCase() === 'true';
|
||||
const webIdentityTokenFile = core.getInput('web-identity-token-file', { required: false });
|
||||
|
||||
// Configure the AWS CLI and AWS SDKs using environment variables
|
||||
|
||||
// AWS_ACCESS_KEY_ID:
|
||||
// Specifies an AWS access key associated with an IAM user or role
|
||||
core.exportVariable('AWS_ACCESS_KEY_ID', accessKeyId);
|
||||
|
||||
// AWS_SECRET_ACCESS_KEY:
|
||||
// Specifies the secret key associated with the access key. This is essentially the "password" for the access key.
|
||||
core.exportVariable('AWS_SECRET_ACCESS_KEY', secretAccessKey);
|
||||
|
||||
// AWS_SESSION_TOKEN:
|
||||
// Specifies the session token value that is required if you are using temporary security credentials.
|
||||
if (sessionToken) {
|
||||
core.exportVariable('AWS_SESSION_TOKEN', sessionToken);
|
||||
if (!region.match(REGION_REGEX)) {
|
||||
throw new Error(`Region is not valid: ${region}`);
|
||||
}
|
||||
|
||||
// AWS_DEFAULT_REGION and AWS_REGION:
|
||||
// Specifies the AWS Region to send requests to
|
||||
core.exportVariable('AWS_DEFAULT_REGION', region);
|
||||
core.exportVariable('AWS_REGION', region);
|
||||
exportRegion(region);
|
||||
|
||||
// Get the AWS account ID
|
||||
const sts = new aws.STS({
|
||||
customUserAgent: 'configure-aws-credentials-for-github-actions'
|
||||
});
|
||||
const identity = await sts.getCallerIdentity().promise();
|
||||
const accountId = identity.Account;
|
||||
core.setOutput('aws-account-id', accountId);
|
||||
if (!maskAccountId || maskAccountId.toLowerCase() == 'true') {
|
||||
core.setSecret(accountId);
|
||||
// This wraps the logic for deciding if we should rely on the GH OIDC provider since we may need to reference
|
||||
// the decision in a few differennt places. Consolidating it here makes the logic clearer elsewhere.
|
||||
const useGitHubOIDCProvider = () => {
|
||||
// The assumption here is that self-hosted runners won't be populating the `ACTIONS_ID_TOKEN_REQUEST_TOKEN`
|
||||
// environment variable and they won't be providing a web idenity token file or access key either.
|
||||
// V2 of the action might relax this a bit and create an explicit precedence for these so that customers
|
||||
// can provide as much info as they want and we will follow the established credential loading precedence.
|
||||
return roleToAssume && process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN && !accessKeyId && !webIdentityTokenFile
|
||||
}
|
||||
|
||||
// Always export the source credentials and account ID.
|
||||
// The STS client for calling AssumeRole pulls creds from the environment.
|
||||
// Plus, in the assume role case, if the AssumeRole call fails, we want
|
||||
// the source credentials and account ID to already be masked as secrets
|
||||
// in any error messages.
|
||||
if (accessKeyId) {
|
||||
if (!secretAccessKey) {
|
||||
throw new Error("'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided");
|
||||
}
|
||||
|
||||
exportCredentials({accessKeyId, secretAccessKey, sessionToken});
|
||||
}
|
||||
|
||||
// Attempt to load credentials from the GitHub OIDC provider.
|
||||
// If a user provides an IAM Role Arn and DOESN'T provide an Access Key Id
|
||||
// The only way to assume the role is via GitHub's OIDC provider.
|
||||
let sourceAccountId;
|
||||
let webIdentityToken;
|
||||
if(useGitHubOIDCProvider()) {
|
||||
webIdentityToken = await core.getIDToken(audience);
|
||||
roleDurationSeconds = core.getInput('role-duration-seconds', {required: false}) || DEFAULT_ROLE_DURATION_FOR_OIDC_ROLES;
|
||||
// We don't validate the credentials here because we don't have them yet when using OIDC.
|
||||
} else {
|
||||
// Regardless of whether any source credentials were provided as inputs,
|
||||
// validate that the SDK can actually pick up credentials. This validates
|
||||
// cases where this action is on a self-hosted runner that doesn't have credentials
|
||||
// configured correctly, and cases where the user intended to provide input
|
||||
// credentials but the secrets inputs resolved to empty strings.
|
||||
await validateCredentials(accessKeyId);
|
||||
|
||||
sourceAccountId = await exportAccountId(maskAccountId, region);
|
||||
}
|
||||
|
||||
// Get role credentials if configured to do so
|
||||
if (roleToAssume) {
|
||||
const roleCredentials = await retryAndBackoff(
|
||||
async () => { return await assumeRole({
|
||||
sourceAccountId,
|
||||
region,
|
||||
roleToAssume,
|
||||
roleExternalId,
|
||||
roleDurationSeconds,
|
||||
roleSessionName,
|
||||
roleSkipSessionTagging,
|
||||
webIdentityTokenFile,
|
||||
webIdentityToken
|
||||
}) }, true);
|
||||
exportCredentials(roleCredentials);
|
||||
// We need to validate the credentials in 2 of our use-cases
|
||||
// First: self-hosted runners. If the GITHUB_ACTIONS environment variable
|
||||
// is set to `true` then we are NOT in a self-hosted runner.
|
||||
// Second: Customer provided credentials manually (IAM User keys stored in GH Secrets)
|
||||
if (!process.env.GITHUB_ACTIONS || accessKeyId) {
|
||||
await validateCredentials(roleCredentials.accessKeyId);
|
||||
}
|
||||
await exportAccountId(maskAccountId, region);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
|
||||
const showStackTrace = process.env.SHOW_STACK_TRACE;
|
||||
|
||||
if (showStackTrace === 'true') {
|
||||
throw(error)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = run;
|
||||
exports.withSleep = function (s) {
|
||||
sleep = s;
|
||||
};
|
||||
exports.reset = function () {
|
||||
sleep = defaultSleep;
|
||||
};
|
||||
|
||||
exports.run = run
|
||||
|
||||
/* istanbul ignore next */
|
||||
if (require.main === module) {
|
||||
|
||||
+706
-35
@@ -1,89 +1,379 @@
|
||||
const core = require('@actions/core');
|
||||
|
||||
const run = require('.');
|
||||
const assert = require('assert');
|
||||
const aws = require('aws-sdk');
|
||||
const { run, withSleep, reset } = require('./index.js');
|
||||
|
||||
jest.mock('@actions/core');
|
||||
|
||||
const FAKE_ACCESS_KEY_ID = 'MY-AWS-ACCESS-KEY-ID';
|
||||
const FAKE_SECRET_ACCESS_KEY = 'MY-AWS-SECRET-ACCESS-KEY';
|
||||
const FAKE_SESSION_TOKEN = 'MY-AWS-SESSION-TOKEN';
|
||||
const FAKE_STS_ACCESS_KEY_ID = 'STS-AWS-ACCESS-KEY-ID';
|
||||
const FAKE_STS_SECRET_ACCESS_KEY = 'STS-AWS-SECRET-ACCESS-KEY';
|
||||
const FAKE_STS_SESSION_TOKEN = 'STS-AWS-SESSION-TOKEN';
|
||||
const FAKE_REGION = 'fake-region-1';
|
||||
const FAKE_ACCOUNT_ID = '123456789012';
|
||||
const FAKE_ROLE_ACCOUNT_ID = '111111111111';
|
||||
const ROLE_NAME = 'MY-ROLE';
|
||||
const ROLE_ARN = 'arn:aws:iam::111111111111:role/MY-ROLE';
|
||||
const ENVIRONMENT_VARIABLE_OVERRIDES = {
|
||||
SHOW_STACK_TRACE: 'true',
|
||||
GITHUB_REPOSITORY: 'MY-REPOSITORY-NAME',
|
||||
GITHUB_WORKFLOW: 'MY-WORKFLOW-ID',
|
||||
GITHUB_ACTION: 'MY-ACTION-NAME',
|
||||
GITHUB_ACTOR: 'MY-USERNAME[bot]',
|
||||
GITHUB_SHA: 'MY-COMMIT-ID',
|
||||
GITHUB_REF: 'MY-BRANCH',
|
||||
GITHUB_WORKSPACE: '/home/github'
|
||||
};
|
||||
const GITHUB_ACTOR_SANITIZED = 'MY-USERNAME_bot_'
|
||||
|
||||
function mockGetInput(requestResponse) {
|
||||
return function (name, options) { // eslint-disable-line no-unused-vars
|
||||
return requestResponse[name]
|
||||
}
|
||||
}
|
||||
const CREDS_INPUTS = {
|
||||
'aws-access-key-id': FAKE_ACCESS_KEY_ID,
|
||||
'aws-secret-access-key': FAKE_SECRET_ACCESS_KEY
|
||||
};
|
||||
const DEFAULT_INPUTS = {
|
||||
...CREDS_INPUTS,
|
||||
'aws-session-token': FAKE_SESSION_TOKEN,
|
||||
'aws-region': FAKE_REGION,
|
||||
'mask-aws-account-id': 'TRUE'
|
||||
};
|
||||
const ASSUME_ROLE_INPUTS = {...CREDS_INPUTS, 'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION};
|
||||
|
||||
const mockStsCallerIdentity = jest.fn();
|
||||
const mockStsAssumeRole = jest.fn();
|
||||
const mockStsAssumeRoleWithWebIdentity = jest.fn();
|
||||
|
||||
jest.mock('aws-sdk', () => {
|
||||
return {
|
||||
config: {
|
||||
getCredentials: jest.fn()
|
||||
},
|
||||
STS: jest.fn(() => ({
|
||||
getCallerIdentity: mockStsCallerIdentity
|
||||
getCallerIdentity: mockStsCallerIdentity,
|
||||
assumeRole: mockStsAssumeRole,
|
||||
assumeRoleWithWebIdentity: mockStsAssumeRoleWithWebIdentity
|
||||
}))
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('fs', () => {
|
||||
return {
|
||||
promises: {
|
||||
readFile: jest.fn(() => Promise.resolve('testpayload')),
|
||||
},
|
||||
existsSync: jest.fn(() => true)
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
jest.mock('axios', () => ({
|
||||
get: jest.fn(() => Promise.resolve({ data: { value: "testtoken" }})),
|
||||
}));
|
||||
|
||||
describe('Configure AWS Credentials', () => {
|
||||
const OLD_ENV = process.env;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
process.env = {...OLD_ENV, ...ENVIRONMENT_VARIABLE_OVERRIDES};
|
||||
|
||||
jest.clearAllMocks();
|
||||
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce('MY-AWS-ACCESS-KEY-ID') // aws-access-key-id
|
||||
.mockReturnValueOnce('MY-AWS-SECRET-ACCESS-KEY') // aws-secret-access-key
|
||||
.mockReturnValueOnce('us-east-2') // aws-default-region
|
||||
.mockReturnValueOnce('MY-AWS-SESSION-TOKEN') // aws-session-token
|
||||
.mockReturnValueOnce('TRUE'); // mask-aws-account-id
|
||||
.mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||
|
||||
mockStsCallerIdentity.mockImplementation(() => {
|
||||
core.getIDToken = jest
|
||||
.fn()
|
||||
.mockImplementation(() => {
|
||||
return "testtoken"
|
||||
});
|
||||
|
||||
mockStsCallerIdentity.mockReset();
|
||||
mockStsCallerIdentity
|
||||
.mockReturnValueOnce({
|
||||
promise() {
|
||||
return Promise.resolve({ Account: FAKE_ACCOUNT_ID });
|
||||
}
|
||||
})
|
||||
.mockReturnValueOnce({
|
||||
promise() {
|
||||
return Promise.resolve({ Account: FAKE_ROLE_ACCOUNT_ID });
|
||||
}
|
||||
});
|
||||
|
||||
aws.config.getCredentials.mockReset();
|
||||
aws.config.getCredentials
|
||||
.mockImplementationOnce(callback => {
|
||||
if (!aws.config.credentials) {
|
||||
aws.config.credentials = {
|
||||
accessKeyId: FAKE_ACCESS_KEY_ID,
|
||||
secretAccessKey: FAKE_SECRET_ACCESS_KEY
|
||||
}
|
||||
}
|
||||
callback(null);
|
||||
})
|
||||
.mockImplementationOnce(callback => {
|
||||
if (!aws.config.credentials) {
|
||||
aws.config.credentials = {
|
||||
accessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
secretAccessKey: FAKE_STS_SECRET_ACCESS_KEY
|
||||
}
|
||||
}
|
||||
callback(null);
|
||||
});
|
||||
|
||||
mockStsAssumeRole.mockImplementation(() => {
|
||||
return {
|
||||
promise() {
|
||||
return Promise.resolve({ Account: '123456789012' });
|
||||
return Promise.resolve({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
mockStsAssumeRoleWithWebIdentity.mockImplementation(() => {
|
||||
return {
|
||||
promise() {
|
||||
return Promise.resolve({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
withSleep(() => {
|
||||
return Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env = OLD_ENV;
|
||||
reset();
|
||||
});
|
||||
|
||||
test('exports env vars', async () => {
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', 'MY-AWS-ACCESS-KEY-ID');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', 'MY-AWS-SECRET-ACCESS-KEY');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', 'MY-AWS-SESSION-TOKEN');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'us-east-2');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'us-east-2');
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', '123456789012');
|
||||
expect(core.setSecret).toHaveBeenCalledWith('123456789012');
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(4);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', FAKE_SESSION_TOKEN);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SESSION_TOKEN);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('action fails when github env vars are not set', async () => {
|
||||
process.env.SHOW_STACK_TRACE = 'false';
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
delete process.env.GITHUB_SHA;
|
||||
|
||||
await run();
|
||||
expect(core.setFailed).toHaveBeenCalledWith('Missing required environment value. Are you running in GitHub Actions?');
|
||||
});
|
||||
|
||||
test('action does not require GITHUB_REF env var', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
delete process.env.GITHUB_REF;
|
||||
|
||||
await run();
|
||||
});
|
||||
|
||||
test('hosted runners can pull creds from a self-hosted environment', async () => {
|
||||
const mockInputs = {'aws-region': FAKE_REGION};
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(mockInputs));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(2);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(1);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', FAKE_REGION);
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('action with no accessible credentials fails', async () => {
|
||||
process.env.SHOW_STACK_TRACE = 'false';
|
||||
const mockInputs = {'aws-region': FAKE_REGION};
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(mockInputs));
|
||||
aws.config.getCredentials.mockReset();
|
||||
aws.config.getCredentials.mockImplementation(callback => {
|
||||
callback(new Error('No credentials to load'));
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith("Credentials could not be loaded, please check your action inputs: No credentials to load");
|
||||
});
|
||||
|
||||
test('action with empty credentials fails', async () => {
|
||||
process.env.SHOW_STACK_TRACE = 'false';
|
||||
const mockInputs = {'aws-region': FAKE_REGION};
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(mockInputs));
|
||||
aws.config.getCredentials.mockReset();
|
||||
aws.config.getCredentials.mockImplementation(callback => {
|
||||
aws.config.credentials = {
|
||||
accessKeyId: ''
|
||||
}
|
||||
callback(null);
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith("Credentials could not be loaded, please check your action inputs: Access key ID empty after loading credentials");
|
||||
});
|
||||
|
||||
test('action fails when credentials are not set in the SDK correctly', async () => {
|
||||
process.env.SHOW_STACK_TRACE = 'false';
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
aws.config.getCredentials.mockReset();
|
||||
aws.config.getCredentials.mockImplementation(callback => {
|
||||
aws.config.credentials = {
|
||||
accessKeyId: FAKE_ACCESS_KEY_ID
|
||||
}
|
||||
callback(null);
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith("Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action");
|
||||
});
|
||||
|
||||
test('session token is optional', async () => {
|
||||
const mockInputs = {...CREDS_INPUTS, 'aws-region': 'eu-west-1'};
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce('MY-AWS-ACCESS-KEY-ID') // aws-access-key-id
|
||||
.mockReturnValueOnce('MY-AWS-SECRET-ACCESS-KEY') // aws-secret-access-key
|
||||
.mockReturnValueOnce('eu-west-1'); // aws-default-region
|
||||
.mockImplementation(mockGetInput(mockInputs));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', 'MY-AWS-ACCESS-KEY-ID');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', 'MY-AWS-SECRET-ACCESS-KEY');
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(3);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', '123456789012');
|
||||
expect(core.setSecret).toHaveBeenCalledWith('123456789012');
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('existing env var creds are cleared', async () => {
|
||||
const mockInputs = {...CREDS_INPUTS, 'aws-region': 'eu-west-1'};
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(mockInputs));
|
||||
process.env.AWS_ACCESS_KEY_ID = 'foo';
|
||||
process.env.AWS_SECRET_ACCESS_KEY = 'bar';
|
||||
process.env.AWS_SESSION_TOKEN = 'helloworld';
|
||||
aws.config.credentials = {
|
||||
accessKeyId: 'foo',
|
||||
secretAccessKey: 'bar',
|
||||
sessionToken: 'helloworld'
|
||||
};
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(3);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SESSION_TOKEN', '');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'eu-west-1');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'eu-west-1');
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCOUNT_ID);
|
||||
expect(aws.config.credentials.accessKeyId).toBe(FAKE_ACCESS_KEY_ID);
|
||||
expect(aws.config.credentials.secretAccessKey).toBe(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(aws.config.credentials.sessionToken).toBeUndefined();
|
||||
});
|
||||
|
||||
test('validates region name', async () => {
|
||||
process.env.SHOW_STACK_TRACE = 'false';
|
||||
|
||||
const mockInputs = {...CREDS_INPUTS, 'aws-region': '$AWS_REGION'};
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(mockInputs));
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith('Region is not valid: $AWS_REGION');
|
||||
});
|
||||
|
||||
test('throws error if access key id exists but missing secret access key', async () => {
|
||||
process.env.SHOW_STACK_TRACE = 'false';
|
||||
const inputsWIthoutSecretKey = {...ASSUME_ROLE_INPUTS}
|
||||
inputsWIthoutSecretKey["aws-secret-access-key"] = undefined
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(inputsWIthoutSecretKey));
|
||||
|
||||
await run();
|
||||
expect(core.setFailed).toHaveBeenCalledWith("'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided");
|
||||
|
||||
});
|
||||
|
||||
test('can opt out of masking account ID', async () => {
|
||||
const mockInputs = {...CREDS_INPUTS, 'aws-region': 'us-east-1', 'mask-aws-account-id': 'false'};
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce('MY-AWS-ACCESS-KEY-ID') // aws-access-key-id
|
||||
.mockReturnValueOnce('MY-AWS-SECRET-ACCESS-KEY') // aws-secret-access-key
|
||||
.mockReturnValueOnce('us-east-1') // aws-default-region
|
||||
.mockReturnValueOnce('') // aws-session-token
|
||||
.mockReturnValueOnce('false'); // mask-aws-account-id
|
||||
.mockImplementation(mockGetInput(mockInputs));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledTimes(0);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(4);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', 'MY-AWS-ACCESS-KEY-ID');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', 'MY-AWS-SECRET-ACCESS-KEY');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenCalledWith(FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', 'us-east-1');
|
||||
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', 'us-east-1');
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', '123456789012');
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(0);
|
||||
expect(core.setOutput).toHaveBeenCalledWith('aws-account-id', FAKE_ACCOUNT_ID);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
test('error is caught by core.setFailed', async () => {
|
||||
test('error is caught by core.setFailed and caught', async () => {
|
||||
process.env.SHOW_STACK_TRACE = 'false';
|
||||
|
||||
mockStsCallerIdentity.mockReset();
|
||||
mockStsCallerIdentity.mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
@@ -92,4 +382,385 @@ describe('Configure AWS Credentials', () => {
|
||||
|
||||
expect(core.setFailed).toBeCalled();
|
||||
});
|
||||
|
||||
test('error is caught by core.setFailed and passed', async () => {
|
||||
|
||||
mockStsCallerIdentity.mockReset();
|
||||
mockStsCallerIdentity.mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
|
||||
await assert.rejects(() => run());
|
||||
|
||||
expect(core.setFailed).toBeCalled();
|
||||
});
|
||||
|
||||
test('basic role assumption exports', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledTimes(1);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(7);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(7);
|
||||
expect(core.setOutput).toHaveBeenCalledTimes(2);
|
||||
|
||||
// first the source credentials are exported and masked
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_ACCOUNT_ID);
|
||||
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(1, 'AWS_DEFAULT_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(2, 'AWS_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(3, 'AWS_ACCESS_KEY_ID', FAKE_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(4, 'AWS_SECRET_ACCESS_KEY', FAKE_SECRET_ACCESS_KEY);
|
||||
|
||||
expect(core.setOutput).toHaveBeenNthCalledWith(1, 'aws-account-id', FAKE_ACCOUNT_ID);
|
||||
|
||||
// then the role credentials are exported and masked
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(4, FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(5, FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(6, FAKE_STS_SESSION_TOKEN);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(7, FAKE_ROLE_ACCOUNT_ID);
|
||||
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(5, 'AWS_ACCESS_KEY_ID', FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(6, 'AWS_SECRET_ACCESS_KEY', FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(7, 'AWS_SESSION_TOKEN', FAKE_STS_SESSION_TOKEN);
|
||||
|
||||
expect(core.setOutput).toHaveBeenNthCalledWith(2, 'aws-account-id', FAKE_ROLE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('assume role can pull source credentials from self-hosted environment', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledTimes(1);
|
||||
expect(core.exportVariable).toHaveBeenCalledTimes(5);
|
||||
expect(core.setSecret).toHaveBeenCalledTimes(5);
|
||||
expect(core.setOutput).toHaveBeenCalledTimes(2);
|
||||
|
||||
// first the source account is exported and masked
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_ACCOUNT_ID);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(1, 'AWS_DEFAULT_REGION', FAKE_REGION);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(2, 'AWS_REGION', FAKE_REGION);
|
||||
expect(core.setOutput).toHaveBeenNthCalledWith(1, 'aws-account-id', FAKE_ACCOUNT_ID);
|
||||
|
||||
// then the role credentials are exported and masked
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(4, FAKE_STS_SESSION_TOKEN);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(5, FAKE_ROLE_ACCOUNT_ID);
|
||||
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(3, 'AWS_ACCESS_KEY_ID', FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(4, 'AWS_SECRET_ACCESS_KEY', FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.exportVariable).toHaveBeenNthCalledWith(5, 'AWS_SESSION_TOKEN', FAKE_STS_SESSION_TOKEN);
|
||||
|
||||
expect(core.setOutput).toHaveBeenNthCalledWith(2, 'aws-account-id', FAKE_ROLE_ACCOUNT_ID);
|
||||
});
|
||||
|
||||
test('role assumption tags', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
test('role assumption duration provided', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-duration-seconds': 5}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 5,
|
||||
Tags: [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
test('role assumption session name provided', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-session-name': 'MySessionName'}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'MySessionName',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
test('role name provided instead of ARN', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({...CREDS_INPUTS, 'role-to-assume': ROLE_NAME, 'aws-region': FAKE_REGION}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: 'arn:aws:iam::123456789012:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
test('web identity token file provided with absolute path', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION, 'web-identity-token-file': '/fake/token/file'}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRoleWithWebIdentity).toHaveBeenCalledWith({
|
||||
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
WebIdentityToken: 'testpayload'
|
||||
})
|
||||
});
|
||||
|
||||
test('web identity token file provided with relative path', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION, 'web-identity-token-file': 'fake/token/file'}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRoleWithWebIdentity).toHaveBeenCalledWith({
|
||||
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
WebIdentityToken: 'testpayload'
|
||||
})
|
||||
});
|
||||
|
||||
test('only role arn and region provided to use GH OIDC Token', async () => {
|
||||
process.env.GITHUB_ACTIONS = 'true';
|
||||
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'test-token';
|
||||
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRoleWithWebIdentity).toHaveBeenCalledWith({
|
||||
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 3600,
|
||||
WebIdentityToken: 'testtoken'
|
||||
});
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SESSION_TOKEN);
|
||||
});
|
||||
|
||||
test('GH OIDC With custom role duration', async () => {
|
||||
const CUSTOM_ROLE_DURATION = 1234;
|
||||
process.env.GITHUB_ACTIONS = 'true';
|
||||
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'test-token';
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION, 'role-duration-seconds': CUSTOM_ROLE_DURATION}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRoleWithWebIdentity).toHaveBeenCalledWith({
|
||||
RoleArn: 'arn:aws:iam::111111111111:role/MY-ROLE',
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: CUSTOM_ROLE_DURATION,
|
||||
WebIdentityToken: 'testtoken'
|
||||
});
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(1, FAKE_STS_ACCESS_KEY_ID);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(2, FAKE_STS_SECRET_ACCESS_KEY);
|
||||
expect(core.setSecret).toHaveBeenNthCalledWith(3, FAKE_STS_SESSION_TOKEN);
|
||||
});
|
||||
|
||||
test('role assumption fails after maximun trials using OIDC Provider', async () => {
|
||||
process.env.GITHUB_ACTIONS = 'true';
|
||||
process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN = 'test-token';
|
||||
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({'role-to-assume': ROLE_ARN, 'aws-region': FAKE_REGION}));
|
||||
|
||||
mockStsAssumeRoleWithWebIdentity.mockReset();
|
||||
mockStsAssumeRoleWithWebIdentity.mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
|
||||
await assert.rejects(() => run());
|
||||
expect(mockStsAssumeRoleWithWebIdentity).toHaveBeenCalledTimes(12)
|
||||
});
|
||||
|
||||
test('role external ID provided', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-external-id': 'abcdef'}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||
],
|
||||
ExternalId: 'abcdef'
|
||||
})
|
||||
});
|
||||
|
||||
test('workflow name sanitized in role assumption tags', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
process.env = {...process.env, GITHUB_WORKFLOW: 'Workflow!"#$%&\'()*+, -./:;<=>?@[]^_`{|}~🙂💥🍌1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZai9D2AN2RlWCxtMqChNtxuxjqeqhoQZo0oaq39sjcRZgAAAAAAA'};
|
||||
|
||||
const sanitizedWorkflowName = 'Workflow__________+_ -./:;<=>?@____________1yFvMOeD3ZHYsHrGjCceOboMYzBPo0CRNFdcsVRG6UgR3A912a8KfcBtEVvkAS7kRBq80umGff8mux5IN1y55HQWPNBNyaruuVr4islFXte4FDQZexGJRUSMyHQpxJ8OmZnET84oDmbvmIjgxI6IBrdihX9PHMapT4gQvRYnLqNiKb18rEMWDNoZRy51UPX5sWK2GKPipgKSO9kqLckZa'
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 6 * 3600,
|
||||
Tags: [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: sanitizedWorkflowName},
|
||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
test('skip tagging provided as true', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': 'true'}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 21600,
|
||||
Tags: undefined
|
||||
})
|
||||
});
|
||||
|
||||
test('skip tagging provided as false', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS, 'role-skip-session-tagging': 'false'}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 21600,
|
||||
Tags: [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
test('skip tagging not provided', async () => {
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput({...ASSUME_ROLE_INPUTS}));
|
||||
|
||||
await run();
|
||||
expect(mockStsAssumeRole).toHaveBeenCalledWith({
|
||||
RoleArn: ROLE_ARN,
|
||||
RoleSessionName: 'GitHubActions',
|
||||
DurationSeconds: 21600,
|
||||
Tags: [
|
||||
{Key: 'GitHub', Value: 'Actions'},
|
||||
{Key: 'Repository', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REPOSITORY},
|
||||
{Key: 'Workflow', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_WORKFLOW},
|
||||
{Key: 'Action', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_ACTION},
|
||||
{Key: 'Actor', Value: GITHUB_ACTOR_SANITIZED},
|
||||
{Key: 'Commit', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_SHA},
|
||||
{Key: 'Branch', Value: ENVIRONMENT_VARIABLE_OVERRIDES.GITHUB_REF},
|
||||
]
|
||||
})
|
||||
});
|
||||
|
||||
test('masks variables before exporting', async () => {
|
||||
let maskedValues = [];
|
||||
const publicFields = ['AWS_REGION', 'AWS_DEFAULT_REGION'];
|
||||
core.setSecret.mockReset();
|
||||
core.setSecret.mockImplementation((secret) => {
|
||||
maskedValues.push(secret);
|
||||
});
|
||||
|
||||
core.exportVariable.mockReset();
|
||||
core.exportVariable.mockImplementation((name, value) => {
|
||||
if (!maskedValues.includes(value) && !publicFields.includes(name)) {
|
||||
throw new Error(value + " for variable " + name + " is not masked yet!");
|
||||
}
|
||||
});
|
||||
|
||||
core.getInput = jest
|
||||
.fn()
|
||||
.mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
await run();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Generated
+2119
-3835
File diff suppressed because it is too large
Load Diff
+9
-8
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "aws-actions-configure-aws-credentials",
|
||||
"version": "0.0.0",
|
||||
"version": "1.7.0",
|
||||
"description": "Configure AWS Credentials",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint **.js",
|
||||
"package": "ncc build index.js -o dist",
|
||||
"test": "eslint **.js && jest --coverage"
|
||||
"package": "ncc build index.js -o dist && ncc build cleanup.js -o dist/cleanup",
|
||||
"test": "npm run lint && jest --coverage --verbose"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,12 +25,13 @@
|
||||
},
|
||||
"homepage": "https://github.com/aws-actions/configure-aws-credentials#readme",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.0",
|
||||
"aws-sdk": "^2.567.0"
|
||||
"@actions/core": "^1.6.0",
|
||||
"aws-sdk": "^2.1112.0",
|
||||
"axios": "^0.26.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@zeit/ncc": "^0.20.5",
|
||||
"eslint": "^6.6.0",
|
||||
"jest": "^24.9.0"
|
||||
"@zeit/ncc": "^0.22.3",
|
||||
"eslint": "^8.13.0",
|
||||
"jest": "^27.5.1"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user