Compare commits

..

1 Commits

Author SHA1 Message Date
peterwoodworth 27bc1c5cc5 chore: run using node20 2023-09-08 14:13:04 -07:00
50 changed files with 52058 additions and 98872 deletions
+2
View File
@@ -0,0 +1,2 @@
build
dist
+168
View File
@@ -0,0 +1,168 @@
env:
jest: true
node: true
root: true
plugins:
- import
- prettier
parserOptions:
ecmaVersion: 2021
sourceType: module
extends:
- plugin:prettier/recommended
- prettier
rules:
prettier/prettier: [error]
import/no-extraneous-dependencies:
- error
- devDependencies:
- "**/test/**"
- "**/build-tools/**"
optionalDependencies: false
peerDependencies: true
import/no-unresolved: [error]
import/order:
- warn
- groups:
- builtin
- external
alphabetize:
order: asc
caseInsensitive: true
array-callback-return: [warn]
no-await-in-loop: [warn]
no-constant-binary-expression: [error]
no-constructor-return: [error]
no-duplicate-imports: [error]
no-self-compare: [warn]
no-template-curly-in-string: [error]
no-unmodified-loop-condition: [error]
no-unreachable-loop: [error]
no-unused-private-class-members: [error]
no-use-before-define: [error]
require-atomic-updates: [error]
block-scoped-var: [warn]
camelcase: [warn]
class-methods-use-this: [error]
consistent-return: [warn]
consistent-this: [warn]
default-case-last: [warn]
default-param-last: [warn]
dot-notation: [error]
eqeqeq: [error]
guard-for-in: [warn]
logical-assignment-operators:
- error
- always
- enforceForIfStatements: false
no-array-constructor: [error]
no-bitwise: [error]
no-console: [warn]
no-empty-function: [warn]
no-eval: [error]
no-extra-bind: [error]
no-labels: [error]
no-implicit-globals: [error]
no-invalid-this: [error]
key-spacing: [error]
no-multiple-empty-lines: [error]
no-return-await: [warn]
no-trailing-spaces: [error]
no-lonely-if: [error]
no-nested-ternary: [warn]
no-mixed-operators: [warn]
no-proto: [error]
no-sequences: [error]
no-throw-literal: [error]
no-useless-call: [error]
no-useless-concat: [warn]
no-var: [error]
one-var-declaration-per-line: [error]
prefer-const: [warn]
prefer-arrow-callback: [warn]
prefer-regex-literals: [warn]
prefer-promise-reject-errors: [warn]
prefer-spread: [warn]
prefer-template: [warn]
require-await: [error]
overrides:
- files:
- '**/*.ts'
parser: '@typescript-eslint/parser'
parserOptions:
ecmaVersion: 2021
sourceType: module
project: ./tsconfig.json
extends:
- plugin:@typescript-eslint/recommended
- plugin:@typescript-eslint/recommended-requiring-type-checking
- plugin:import/typescript
rules:
'@typescript-eslint/array-type':
- warn
- default: array-simple
'@typescript-eslint/ban-tslint-comment': [error]
'@typescript-eslint/consistent-indexed-object-style': [warn]
'@typescript-eslint/consistent-type-assertions': [warn]
'@typescript-eslint/prefer-includes': [warn]
dot-notation: [off]
'@typescript-eslint/dot-notation': [error]
'@typescript-eslint/no-explicit-any': [off]
'@typescript-eslint/consistent-type-exports': [warn]
'@typescript-eslint/consistent-type-imports': [warn]
'@typescript-eslint/no-base-to-string': [error]
'@typescript-eslint/no-confusing-non-null-assertion': [warn]
'@typescript-eslint/no-invalid-void-type': [error]
'@typescript-eslint/no-meaningless-void-operator': [warn]
'@typescript-eslint/no-redundant-type-constituents': [warn]
'@typescript-eslint/no-unnecessary-boolean-literal-compare': [warn]
'@typescript-eslint/no-unnecessary-condition': [warn]
'@typescript-eslint/no-unnecessary-qualifier': [warn]
'@typescript-eslint/no-unnecessary-type-arguments': [warn]
'@typescript-eslint/non-nullable-type-assertion-style': [warn]
'@typescript-eslint/prefer-for-of': [error]
'@typescript-eslint/prefer-literal-enum-member': [warn]
'@typescript-eslint/prefer-optional-chain': [warn]
'@typescript-eslint/prefer-readonly': [warn]
'@typescript-eslint/prefer-regexp-exec': [warn]
'@typescript-eslint/prefer-string-starts-ends-with': [warn]
'@typescript-eslint/prefer-ts-expect-error': [error]
'@typescript-eslint/promise-function-async': [warn]
'@typescript-eslint/require-array-sort-compare': [error]
default-param-last: [off]
'@typescript-eslint/default-param-last': [warn]
no-array-constructor: [off]
'@typescript-eslint/no-array-constructor': [error]
no-dupe-class-members: [off]
'@typescript-eslint/no-dupe-class-members': [warn]
no-invalid-this: [off]
'@typescript-eslint/no-invalid-this': [warn]
no-unused-vars: [off]
'@typescript-eslint/no-unused-vars':
- error
- varsIgnorePattern: '^_'
argsIgnorePattern: '^_'
caughtErrorsIgnorePattern: '^_'
'@typescript-eslint/no-non-null-assertion': [off]
'@typescript-eslint/no-require-imports':
- error
no-return-await: [off]
'@typescript-eslint/return-await': [error]
no-shadow: [off]
'@typescript-eslint/no-shadow': [error]
'@typescript-eslint/no-floating-promises': [error]
"@typescript-eslint/member-ordering":
- error
- default:
- public-static-field
- public-static-method
- protected-static-field
- protected-static-method
- private-static-field
- private-static-method
- field
- constructor
- method
no-use-before-define: [off]
'@typescript-eslint/no-use-before-define': [error]
no-duplicate-imports: [off]
-8
View File
@@ -12,14 +12,6 @@ body:
description: What is the problem? A clear and concise description of the bug.
validations:
required: true
- type: checkboxes
id: regression
attributes:
label: Regression Issue
description: What is a regression? If it worked in a previous version but doesn't in the latest version, it's considered a regression. In this case, please provide specific version number in the report.
options:
- label: Select this option if this issue appears to be a regression.
required: false
- type: textarea
id: expected
attributes:
@@ -1,32 +0,0 @@
on:
pull_request_review:
types: submitted
jobs:
approved_pr:
name: Automerge approved PRs
permissions:
contents: write
pull-requests: write
id-token: write
if: ${{ github.event.review.state == 'approved' && github.repository == 'aws-actions/configure-aws-credentials' && (github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'MEMBER' || github.event.review.user.login == 'aws-sdk-osds') }}
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
role-duration-seconds: 900
role-session-name: SecretsManagerFetch
- name: Get bot user token
uses: aws-actions/aws-secretsmanager-get-secrets@v2
with:
parse-json-secrets: true
secret-ids: |
${{ secrets.OSDS_PACKAGING_ROLE }}
- name: Enable PR automerge
run: gh pr merge --auto --squash "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GITHUB_TOKEN: ${{ env.OSDS_ACCESS_TOKEN }}
-20
View File
@@ -1,20 +0,0 @@
name: Test Configure AWS Credential
on:
workflow_dispatch:
jobs:
cawsc:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- name: CAWSC
uses: aws-actions/configure-aws-credentials@main
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
role-duration-seconds: 900
role-session-name: TestCAWSC
- name: Whoami
run: |
aws sts get-caller-identity
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
name: Stale issue job
steps:
- uses: aws-actions/stale-issue-cleanup@v6
- uses: aws-actions/stale-issue-cleanup@v5
with:
# Setting messages to an empty string will cause the automation to skip
# that category
@@ -1,41 +0,0 @@
name: Dependabot auto-approve
on:
pull_request_target:
workflow_dispatch:
permissions:
pull-requests: write
id-token: write
contents: read
jobs:
dependabot:
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'aws-actions/configure-aws-credentials' }}
steps:
- name: Get Metadata
id: dependabot-metadata
uses: dependabot/fetch-metadata@v2
- uses: actions/checkout@v4
name: Clone repo
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.CONFIGUREAWSCREDENTIALSPACKAGEROLEARN }}
role-duration-seconds: 900
- name: Get bot user token
uses: aws-actions/aws-secretsmanager-get-secrets@v2
with:
parse-json-secrets: true
secret-ids: |
${{ secrets.OSDS_PACKAGING_ROLE }}
- name: Approve PR if not already approved
run: |
gh pr checkout "$PR_URL"
if [ "$(gh pr status --json reviewDecision - q .currentBranch.reviewDecision)" != "APPROVED" ]; then
gh pr review "$PR_URL" --approve
else echo "PR already approved"
fi
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GITHUB_TOKEN: ${{ env.OSDS_ACCESS_TOKEN }}
@@ -1,32 +0,0 @@
# Apply potential regression label on issues
name: issue-regression-label
on:
issues:
types: [opened, edited]
jobs:
add-regression-label:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Fetch template body
id: check_regression
uses: actions/github-script@v7
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TEMPLATE_BODY: ${{ github.event.issue.body }}
with:
script: |
const regressionPattern = /\[x\] Select this option if this issue appears to be a regression\./i;
const template = `${process.env.TEMPLATE_BODY}`
const match = regressionPattern.test(template);
core.setOutput('is_regression', match);
- name: Manage regression label
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if [ "${{ steps.check_regression.outputs.is_regression }}" == "true" ]; then
gh issue edit ${{ github.event.issue.number }} --add-label "potential-regression" -R ${{ github.repository }}
else
gh issue edit ${{ github.event.issue.number }} --remove-label "potential-regression" -R ${{ github.repository }}
fi
@@ -17,7 +17,7 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.ref_name }}
@@ -28,18 +28,18 @@ jobs:
npm test
npm run package
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
role-duration-seconds: 900
role-session-name: SecretsManagerFetch
- name: Get bot user token
uses: aws-actions/aws-secretsmanager-get-secrets@v2
uses: aws-actions/aws-secretsmanager-get-secrets@v1
with:
parse-json-secrets: true
secret-ids: |
${{ secrets.OSDS_PACKAGING_ROLE }}
OSDS,arn:aws:secretsmanager:us-west-2:206735643321:secret:github-aws-sdk-osds-automation-gebs9n
- name: Commit
run: |
echo "::add-mask::${{ env.OSDS_ACCESS_TOKEN }}"
@@ -48,4 +48,4 @@ jobs:
git remote set-url origin https://${{ env.OSDS_ACCESS_TOKEN }}@github.com/aws-actions/configure-aws-credentials.git
git add dist
git commit -m "chore: Update dist" || echo "No changes to commit"
git push --force origin
git push origin
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
permissions:
pull-requests: write
steps:
- uses: amannn/action-semantic-pull-request@v5.5.3
- uses: amannn/action-semantic-pull-request@v4.5.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
-43
View File
@@ -1,43 +0,0 @@
---
name: Release Please
on:
push:
branches:
- main
permissions:
id-token: write
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
role-duration-seconds: 900
role-session-name: ${{ github.run_id }}
- name: Get git credentials
uses: aws-actions/aws-secretsmanager-get-secrets@v2
with:
parse-json-secrets: true
secret-ids: |
${{ secrets.OSDS_PACKAGING_ROLE }}
- name: Run release-please
uses: googleapis/release-please-action@v4
with:
release-type: node
token: ${{ env.OSDS_ACCESS_TOKEN }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
+117
View File
@@ -0,0 +1,117 @@
name: Run Integ tests
on:
workflow_dispatch:
jobs:
integ-oidc:
permissions:
contents: read
id-token: write
strategy:
fail-fast: false
matrix:
os: [[self-hosted, linux-fargate], windows-latest, ubuntu-latest, macos-latest]
node: [14, 16, 18]
name: Run OIDC integ tests
runs-on: ${{ matrix.os }}
timeout-minutes: 30
steps:
- name: "Checkout repository"
uses: actions/checkout@v3
- name: Integ test for OIDC
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_OIDC_AWS_ROLE_TO_ASSUME }}
role-duration-seconds: 900
role-session-name: IntegOidcAssumeRole
role-external-id: ${{ secrets.SECRETS_OIDC_AWS_ROLE_EXTERNAL_ID }}
integ-oidc-env:
permissions:
contents: read
id-token: write
strategy:
fail-fast: false
matrix:
os: [[self-hosted, linux-fargate], windows-latest, ubuntu-latest, macos-latest]
node: [14, 16, 18]
name: Run OIDC integ tests with existing invalid env vars
runs-on: ${{ matrix.os }}
env:
AWS_ACCESS_KEY_ID: dummyaccesskeyid
AWS_SECRET_ACCESS_KEY: dummysecretkey
AWS_SESSION_TOKEN: dummytoken
timeout-minutes: 30
steps:
- name: "Checkout repository"
uses: actions/checkout@v3
- name: Integ test for OIDC
uses: ./
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_OIDC_AWS_ROLE_TO_ASSUME }}
role-duration-seconds: 900
role-session-name: IntegOidcAssumeRole
role-external-id: ${{ secrets.SECRETS_OIDC_AWS_ROLE_EXTERNAL_ID }}
integ-access-keys:
strategy:
fail-fast: false
matrix:
os: [[self-hosted, linux-fargate], windows-latest, ubuntu-latest, macos-latest]
node: [14, 16, 18]
name: Run access key integ tests
runs-on: ${{ matrix.os }}
timeout-minutes: 30
steps:
- name: "Checkout repository"
uses: actions/checkout@v3
- name: Integ test for access keys
uses: ./
with:
aws-region: us-west-2
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
role-to-assume: ${{ secrets.SECRETS_AWS_ROLE_TO_ASSUME }}
role-session-name: IntegAccessKeysAssumeRole
role-external-id: ${{ secrets.SECRETS_AWS_ROLE_EXTERNAL_ID }}
integ-access-keys-env:
strategy:
fail-fast: false
matrix:
os: [[self-hosted, linux-fargate], windows-latest, ubuntu-latest, macos-latest]
node: [14, 16, 18]
name: Run access key from env integ tests
runs-on: ${{ matrix.os }}
timeout-minutes: 30
steps:
- name: "Checkout repository"
uses: actions/checkout@v3
- name: Integ test for access keys
uses: ./
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
with:
aws-region: us-west-2
role-to-assume: ${{ secrets.SECRETS_AWS_ROLE_TO_ASSUME }}
role-session-name: IntegAccessKeysAssumeRole
role-external-id: ${{ secrets.SECRETS_AWS_ROLE_EXTERNAL_ID }}
integ-iam-user:
strategy:
fail-fast: false
matrix:
os: [[self-hosted, linux-fargate], windows-latest, ubuntu-latest, macos-latest]
node: [14, 16, 18]
name: Run IAM User integ tests
runs-on: ${{ matrix.os }}
timeout-minutes: 30
steps:
- name: "Checkout repository"
uses: actions/checkout@v3
- name: Integ test for IAM user
uses: ./
with:
aws-region: us-west-2
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+7 -6
View File
@@ -9,16 +9,17 @@ jobs:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
node: [14, 16, 18]
name: Run unit tests
runs-on: ${{ matrix.os }}
timeout-minutes: 5
steps:
- name: "Checkout repository"
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: "Setup node"
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version: 20
node-version: ${{ matrix.node }}
- name: "Install dependencies"
uses: bahmutov/npm-install@v1
- name: "Run tests"
@@ -29,11 +30,11 @@ jobs:
timeout-minutes: 5
steps:
- name: "Checkout repostiory"
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: "Setup node"
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version: 20
node-version: 16
- name: "Install dependencies"
uses: bahmutov/npm-install@v1
- name: "Lint code"
+64
View File
@@ -0,0 +1,64 @@
queue_rules:
- name: default
conditions:
# Conditions to merge a queued PR
- check-success=Run unit tests (windows-latest, 14)
- check-success=Run unit tests (windows-latest, 16)
- check-success=Run unit tests (windows-latest, 18)
- check-success=Run unit tests (ubuntu-latest, 14)
- check-success=Run unit tests (ubuntu-latest, 16)
- check-success=Run unit tests (ubuntu-latest, 18)
- check-success=Run unit tests (macos-latest, 14)
- check-success=Run unit tests (macos-latest, 16)
- check-success=Run unit tests (macos-latest, 18)
- "#approved-reviews-by>=1"
- -approved-reviews-by~=author
pull_request_rules:
- name: Automatically merge on CI success and review approval
conditions:
- base~=main|integ-tests
- "#approved-reviews-by>=1"
- -approved-reviews-by~=author
- check-success=Run unit tests (windows-latest, 14)
- check-success=Run unit tests (windows-latest, 16)
- check-success=Run unit tests (windows-latest, 18)
- check-success=Run unit tests (ubuntu-latest, 14)
- check-success=Run unit tests (ubuntu-latest, 16)
- check-success=Run unit tests (ubuntu-latest, 18)
- check-success=Run unit tests (macos-latest, 14)
- check-success=Run unit tests (macos-latest, 16)
- check-success=Run unit tests (macos-latest, 18)
- 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~=main
- author=dependabot[bot]
- check-success=Run unit tests (windows-latest, 14)
- check-success=Run unit tests (windows-latest, 16)
- check-success=Run unit tests (windows-latest, 18)
- check-success=Run unit tests (ubuntu-latest, 14)
- check-success=Run unit tests (ubuntu-latest, 16)
- check-success=Run unit tests (ubuntu-latest, 18)
- check-success=Run unit tests (macos-latest, 14)
- check-success=Run unit tests (macos-latest, 16)
- check-success=Run unit tests (macos-latest, 18)
- -title~=(WIP|wip)
- -label~=(blocked|do-not-merge)
- -merged
- -closed
actions:
review:
type: APPROVE
queue:
method: squash
name: default
+8
View File
@@ -0,0 +1,8 @@
{
"printWidth": 120,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"overrides": []
}
-5
View File
@@ -1,5 +0,0 @@
{
".release-please-manifest.json": "4.0.2",
"package.json": "4.0.2",
".": "4.3.0"
}
-96
View File
@@ -2,102 +2,6 @@
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.
## [4.3.0](https://github.com/aws-actions/configure-aws-credentials/compare/v4.3.0...v4.3.0) (2025-08-04)
### Bug Fixes
* properly set proxy environment variable ([cbea708](https://github.com/aws-actions/configure-aws-credentials/commit/cbea70821e4ab985ad3be0e5a93390523e257cde))
### Miscellaneous Chores
* release 4.3.0 ([3f7c218](https://github.com/aws-actions/configure-aws-credentials/commit/3f7c2187213bafaa1ea60a850b27082cbf55dda0))
## [4.3.0](https://github.com/aws-actions/configure-aws-credentials/compare/v4.2.1...v4.3.0) (2025-08-04)
### Features
* depenency update and feature cleanup ([#1414](https://github.com/aws-actions/configure-aws-credentials/issues/1414)) ([59489ba](https://github.com/aws-actions/configure-aws-credentials/commit/59489ba544930000b7b67412c167f5fe816568cf)), closes [#1062](https://github.com/aws-actions/configure-aws-credentials/issues/1062) [#1191](https://github.com/aws-actions/configure-aws-credentials/issues/1191)
* Optional environment variable output ([c3b3ce6](https://github.com/aws-actions/configure-aws-credentials/commit/c3b3ce61b02510937ff02916a4eb153874bc5085))
### Bug Fixes
* **docs:** readme samples versioning ([5b3c895](https://github.com/aws-actions/configure-aws-credentials/commit/5b3c89504689ea1ea2b6000b23a6a2aac463662a))
* the wrong example region for China partition in README ([37fe9a7](https://github.com/aws-actions/configure-aws-credentials/commit/37fe9a740bcb30ee8cccd96feb90666c937311f2))
## [4.2.1](https://github.com/aws-actions/configure-aws-credentials/compare/v4.2.0...v4.2.1) (2025-05-14)
### Bug Fixes
* ensure explicit inputs take precedence over environment variables ([e56e6c4](https://github.com/aws-actions/configure-aws-credentials/commit/e56e6c4038915cd5a7238a671fe97f44c98a40b0))
* prioritize explicit inputs over environment variables ([df9c8fe](https://github.com/aws-actions/configure-aws-credentials/commit/df9c8fed6b364f0d1fb0e6e03a0ec26f1ea4e3fc))
## [4.2.0](https://github.com/aws-actions/configure-aws-credentials/compare/v4.1.0...v4.2.0) (2025-05-06)
### Features
* add Expiration field to Outputs ([a4f3267](https://github.com/aws-actions/configure-aws-credentials/commit/a4f326760c1c1bf49ab86051c658d6501816b930))
* Document role-duration-seconds range ([5a0cf01](https://github.com/aws-actions/configure-aws-credentials/commit/5a0cf0167f837dfa7af7d951ba6a78a38dc2b79e))
* support action inputs as environment variables ([#1338](https://github.com/aws-actions/configure-aws-credentials/issues/1338)) ([2c168ad](https://github.com/aws-actions/configure-aws-credentials/commit/2c168adcae62d67531ba83842723c8f30695116a))
### Bug Fixes
* make sure action builds, also fix dependabot autoapprove ([c401b8a](https://github.com/aws-actions/configure-aws-credentials/commit/c401b8a98c5067672f52e0387cdd87d54acfe1fd))
* role chaning on mulitple runs ([#1340](https://github.com/aws-actions/configure-aws-credentials/issues/1340)) ([9e38641](https://github.com/aws-actions/configure-aws-credentials/commit/9e386419117a9edd458297e4f1822a5df7506a03))
## [4.1.0](https://github.com/aws-actions/configure-aws-credentials/compare/v4.0.3...v4.1.0) (2025-02-08)
### Features
* idempotent fetch ([#1289](https://github.com/aws-actions/configure-aws-credentials/issues/1289)) ([eb70354](https://github.com/aws-actions/configure-aws-credentials/commit/eb70354fb423a380b6e4ab4b9f15d2ee9ffae911))
### Bug Fixes
* build failure due to tests ([#1283](https://github.com/aws-actions/configure-aws-credentials/issues/1283)) ([134d71e](https://github.com/aws-actions/configure-aws-credentials/commit/134d71efe0ecbe9ad6965f2f766c0cae63a7685f))
* Dependabot autoapprove ([#1284](https://github.com/aws-actions/configure-aws-credentials/issues/1284)) ([b9ee51d](https://github.com/aws-actions/configure-aws-credentials/commit/b9ee51dc600fe38c892e24f60ca26476e0e0b6de))
* Dependabot autoapprove id-token write permission ([#1285](https://github.com/aws-actions/configure-aws-credentials/issues/1285)) ([f0af89b](https://github.com/aws-actions/configure-aws-credentials/commit/f0af89b102390dcf10ce402195d74a98f24861f3))
* typo ([#1281](https://github.com/aws-actions/configure-aws-credentials/issues/1281)) ([39fd91c](https://github.com/aws-actions/configure-aws-credentials/commit/39fd91c08ed8bf770034de4e62662503e8007d76))
## [4.0.3](https://github.com/aws-actions/configure-aws-credentials/compare/v4.0.2...v4.0.3) (2025-01-27)
### Features
* added release-please action config ([0f88004](https://github.com/aws-actions/configure-aws-credentials/commit/0f88004d9c27e0bdbbc254b3f7c8053cb38f04d7))
### Bug Fixes
* add id-token permission to automerge ([97834a4](https://github.com/aws-actions/configure-aws-credentials/commit/97834a484a5ab3c40fa9e2eb40fcf8041105a573))
* cpy syntax on npm package ([#1195](https://github.com/aws-actions/configure-aws-credentials/issues/1195)) ([83b5a56](https://github.com/aws-actions/configure-aws-credentials/commit/83b5a565471214aec459e234bef606339fe07111))
* force push packaged files to main ([bfd2185](https://github.com/aws-actions/configure-aws-credentials/commit/bfd218503eb87938c29603a551e19c6b594f5fe5))
### Miscellaneous Chores
* release 4.0.3 ([ca00fd4](https://github.com/aws-actions/configure-aws-credentials/commit/ca00fd4d3842ad58c3c21ebfe69defa1f0e7bdc4))
## [4.0.2](https://github.com/aws-actions/configure-aws-credentials/compare/v4.0.1...v4.0.2) (2024-02-09)
* Revert 4.0.1 to remove warning
## [4.0.1](https://github.com/aws-actions/configure-aws-credentials/compare/v4.0.0...v4.0.1) (2023-10-03)
### Documentation
* Throw a warning when customers use long-term credentials.
## [4.0.0](https://github.com/aws-actions/configure-aws-credentials/compare/v3.0.2...v4.0.0) (2023-09-11)
* Upgraded runtime to `node20` from `node16`
## [3.0.2](https://github.com/aws-actions/configure-aws-credentials/compare/v3.0.1...v3.0.2) (2023-09-07)
### Bug Fixes
+388 -334
View File
@@ -1,220 +1,188 @@
Configure AWS Credentials
=========================
Authenticate to AWS in GitHub Actions! Works especially well with [AWS Secrets
Manager](https://github.com/aws-actions/aws-secretsmanager-get-secrets).
## Configure AWS Credentials for GitHub Actions
Configure your AWS credentials and region environment variables for use in other
GitHub Actions. This action implements the AWS SDK credential resolution chain
and exports environment variables for your other Actions to use. Environment
variable exports are detected by both the AWS SDKs and the AWS CLI for AWS API
calls.
Quick Start (OIDC, recommended)
-------------------------------
1. Create an IAM Identity Provider in your AWS account for GitHub OIDC. (See
[OIDC configuration](#oidc-configuration) below for details.)
2. Create an IAM Role in your AWS account with a trust policy that allows GitHub
Actions to assume it:
<details>
<summary>GitHub OIDC Trust Policy</summary>
---
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:<GITHUB_ORG>/<GITHUB_REPOSITORY>:ref:refs/heads/<GITHUB_BRANCH>"
}
}
}
]
}
```
</details>
3. Attach permissions to the IAM Role that allow it to access the AWS resources
you need.
4. Add the following to your GitHub Actions workflow:
<details>
<summary>Example Workflow</summary>
### News
```yaml
# Need ID token write permission to use OIDC
We have recently released `v3` of Configure AWS Credentials! With this new
release we have migrated the code to TypeScript, and have also migrated away
from using `v2` of the JavaScript AWS SDK. This should eliminate the warning you
have seen in your workflow logs about `v2` deprecation.
In addition to the refactored codebase, we have also introduced some changes to
existing functionality, added some new features, and fixed some bugs. These
changes should be backwards compatible with your existing workflows.
**Notable changes to existing functionality**
- By default, the assumed role credentials will only be valid for one hour in
_all_ use cases. This is changed from 6 hours in `v2`. You can adjust this value
with the `role-duration-seconds` input.
- By default, your account ID will not be masked in workflow logs. This was
changed from being masked by default in the previous version. AWS does not consider
account IDs as sensitive information, so this change reflects that stance. You
can revert to the old default and mask your account ID in workflow logs by
setting the `mask-aws-account-id` input to `true`.
**New features**
- You can now configure retry settings in case your STS call fails. By default,
we retry with exponential backoff twelve times. You can disable this behavior
altogether by setting the `disable-retry` input to `true`, or you can configure
the number of times the action will retry with the `retry-max-attempts` input.
- You can now set the returned credentials as action step outputs. To do this,
you can set the `output-credentials` prop to `true`.
- There's now an option to clear the AWS-related environment variables at the
start of the action. Clearing these variables is often a workaround for
problems, so enabling this can be helpful if existing credentials or environment
variables are interfering with the action. You can enable this by setting the
`unset-current-credentials` input to `true`.
**Bug fixes**
You can find a list of bugs that have been fixed in v3 in the
[changelog](./CHANGELOG.md).
---
### Table of Contents
<!-- toc -->
- [Overview](#overview)
- [Security recommendations](#security-recommendations)
- [Using this action](#using-this-action)
+ [Credential Lifetime](#credential-lifetime)
+ [External ID](#external-id)
+ [Session tagging](#session-tagging-and-name)
+ [Sample IAM Role Permissions](#sample-iam-role-cloudformation-template)
+ [Misc](#misc)
- [OIDC](#OIDC)
+ [Audience](#audience)
+ [Sample IAM OIDC CloudFormation Template](#sample-iam-oidc-cloudformation-template)
+ [Claims and scoping permissions](#claims-and-scoping-permissions)
+ [Further info](#further-info)
- [Self-Hosted Runners](#self-hosted-runners)
+ [Proxy Configuration](#proxy-configuration)
+ [Use with the AWS CLI](#use-with-the-aws-cli)
- [Examples](#examples)
- [License Summary](#license-summary)
- [Security Disclosures](#security-disclosures)
<!-- tocstop -->
## Overview
We support five methods for fetching credentials from AWS, but we recommend that
you use GitHub's OIDC provider in conjunction with a configured AWS IAM
Identity Provider endpoint.
To do that, you would add the following step to your workflow:
```yaml
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v3
with:
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
aws-region: us-east-2
```
This will cause the action to perform an [`AssumeRoleWithWebIdentity`](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html) call and
return temporary security credentials for use by other steps in your workflow. In order for
this to work, you'll need to preconfigure the IAM Identity Provider in your AWS account
(see [Assuming a Role](#assuming-a-role) for details).
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) or run this action multiple times
to use different AWS accounts, regions, or IAM roles in the same GitHub Actions
workflow. As an example, here is a complete workflow file that uploads artifacts
to Amazon S3.
```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
jobs:
run_job_with_aws:
runs-on: ubuntu-latest
steps:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@main # Or a specific version
with:
role-to-assume: <Role ARN you created in step 2>
aws-region: <AWS Region you want to use>
- name: Additional steps
run: |
# Your commands that require AWS credentials
aws sts get-caller-identity
```
</details>
That's it! Your GitHub Actions workflow can now access AWS resources using the
IAM Role you created. Other authentication scenarios are also supported (see
below).
Security Recommendations
------------------------
* Use temporary credentials when possible. OIDC is recommended because it
provides temporary credentials and it's easy to set up.
* Do not store credentials in your repository's code. Consider using
[git-secrets](https://github.com/awslabs/git-secrets) to prevent committing
secrets to your repository.
* [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)
to your workflows. Grant only those permissions that are necessary for the
workflow to run.
* [Monitor the activity](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#keep-a-log)
of the credentials used in workflows.
* Periodically rotate any long-lived credentials that you use.
* Store sensitive information in a secure way, such as using
[AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) or
[GitHub Secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets).
Other Authentication Scenarios
------------------------------
This action supports five different authentication methods that are configured
by specifying different inputs.
1. Use a `core.getIDToken()` call to authenticate via OIDC.
2. Re-export existing long-lived IAM credentials (access key ID and secret
access key) as environment variables.
3. Use static credentials stored in GitHub Secrets to fetch temporary
credentials via STS AssumeRole.
4. Use a Web Identity Token to fetch temporary credentials via STS
AssumeRoleWithWebIdentity.
5. Use credentials stored in the Action environment to fetch temporary
credentials via STS AssumeRole.
Because we use the AWS JavaScript SDK, we always will use the [credential
resolution flow for Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html).
Depending on your inputs, the action might override parts of this flow.
<details>
<summary>Inputs and their effects on the credential resolution flow</summary>
| **Identity Used** | `aws-access-key-id` | `role-to-assume` | `web-identity-token-file` | `role-chaining` |
| ---------------------------------------- | ------------------- | ---------------- | ------------------------- | --------------- |
| [✅ Recommended] GitHub OIDC | | ✔ | | |
| IAM User (no AssumeRole) | ✔ | | | |
| AssumeRole using static IAM credentials | ✔ | ✔ | | |
| AssumeWithWebIdentity use a token file | | ✔ | ✔ | |
| AssumeRole using existing credentials | | ✔ | | ✔ |
*Note: `role-chaining` is not always necessary to use existing credentials.
If you're getting a "Credentials loaded by the SDK do not match" error,
try enabling this option.*
</details>
Additionally, **`aws-region`** is always required.
*Note: If you use GitHub Enterprise Server, you must use the you may need to
adjust examples here to match your environment.*
Additional Options
------------------
### Options
See [action.yml](./action.yml) for more detail.
<details>
<summary>Options list and descriptions</summary>
| Option | Description | Required |
|---------------------------|---------------------------------------------------------------------------------------------------|----------|
| aws-region | Which AWS region to use | Yes |
| role-to-assume | Role for which to fetch credentials. Only required for some authentication types. | No |
| aws-access-key-id | AWS access key to use. Only required for some authentication types. | No |
| aws-secret-access-key | AWS secret key to use. Only required for some authentication types. | No |
| aws-session-token | AWS session token to use. Used in uncommon authentication scenarios. | No |
| role-chaining | Use existing credentials from the environment to assume a new role. | No |
| audience | The JWT audience when using OIDC. Used in non-default AWS partitions, like China regions. | No |
| http-proxy | An HTTP proxy to use for API calls. | No |
| mask-aws-account-id | AWS account IDs are not considered secret. Setting this will hide account IDs from output anyway. | No |
| role-duration-seconds | The assumed role duration in seconds, if assuming a role. Defaults to 1 hour (3600 seconds). Acceptable values range from 15 minutes (900 seconds) to 12 hours (43200 seconds). | No |
| role-external-id | The external ID of the role to assume. Only needed if your role requires it. | No |
| role-session-name | Defaults to "GitHubActions", but may be changed if required. | No |
| role-skip-session-tagging | Skips session tagging if set. | No |
| inline-session-policy | You may further restrict the assumed role policy by defining an inline policy here. | No |
| managed-session-policies | You may further restrict the assumed role policy by specifying a managed policy here. | No |
| output-credentials | When set, outputs fetched credentials as action step output. (Outputs aws-access-key-id, aws-secret-access-key, aws-session-token, aws-account-id, and aws-expiration). Defaults to false. | No |
| output-env-credentials | When set, outputs fetched credentials as environment variables (AWS_REGION, AWS_DEFAULT_REGION, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN). Defaults to true. Set to false if you need to avoid setting/changing env variables. You'd probably want to use output-credentials if you disable this. (NOTE: Setting to false will prevent the aws-account-id from being exported as a step output). | No |
| unset-current-credentials | When set, attempts to unset any existing credentials in your action runner. | No |
| disable-retry | Disabled retry/backoff logic for assume role calls. By default, retries are enabled. | No |
| retry-max-attempts | Limits the number of retry attempts before giving up. Defaults to 12. | No |
| special-characters-workaround | Uncommonly, some environments cannot tolerate special characters in a secret key. This option will retry fetching credentials until the secret access key does not contain special characters. This option overrides disable-retry and retry-max-attempts. | No |
| use-existing-credentials | When set, the action will check if existing credentials are valid and exit if they are. Defaults to false. | No |
</details>
#### Adjust the retry mechanism
You can configure retry settings for if the STS call fails. By default, we
retry with exponential backoff `12` times. You can disable this behavior
altogether by setting the `disable-retry` input to `true`, or you can configure
the number of times it retries with the `retry-max-attempts` input.
#### Mask account ID
Your account ID is not masked by default in workflow logs. You can set the
`mask-aws-account-id` input to `true` to mask your account ID in workflow logs
if desired.
#### Unset current credentials
Sometimes, existing credentials in your runner can get in the way of the
intended outcome. You can set the `unset-current-credentials` input to `true` to
work around this issue.
#### Use an HTTP proxy
If need use an HTTP proxy you can set it in the action manually. Additionally
this action will always consider the `HTTP_PROXY` environment variable.
<details>
<summary>Proxy configuration</summary>
Manually configured proxy:
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
with:
aws-region: us-east-2
role-to-assume: my-github-actions-role
http-proxy: "http://companydomain.com:3128"
contents: read
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS credentials from Test account
uses: aws-actions/configure-aws-credentials@v3
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@v3
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
```
Proxy configured in the environment variable:
```bash
# Your environment configuration
HTTP_PROXY="http://companydomain.com:3128"
```
</details>
See [action.yml](action.yml) for the full documentation for this action's inputs
and outputs.
#### Special characters in AWS_SECRET_ACCESS_KEY
Some edge cases are unable to properly parse an `AWS_SECRET_ACCESS_KEY` if it
contains special characters. For more information, please see the
[AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-troubleshooting.html#tshoot-signature-does-not-match).
If you set the `special-characters-workaround` option, this action will
continually retry fetching credentials until we get one that does not have
special characters. This option overrides the `disable-retry` and
`retry-max-attempts` options. We recommend that you do not enable this option
unless required, because retrying APIs infinitely until they succeed is not best
practice.
### Note about GHES
Session Naming and Policies
---------------------------
The default session name is "GitHubActions", and you can modify it by specifying
the desired name in `role-session-name`.
Some of this documentation may be inaccurate if you are using GHES (GitHub Enterprise Servers), please take note to review the GitHub documentation when relevant.
*Note: you might find it helpful to set the `role-session-name` to `${{ github.run_id }}`
so as to clarify in audit logs which AWS actions were performed by which workflow
run.*
For example, the URL that the OIDC JWT is issued from is different than the usual `tokens.actions.githubusercontent.com`, and will be unique to your enterprise server. As a result, you will need to configure this differently when you create the Identity Provider.
The session will be tagged with the
following tags: (Refer to [GitHub's documentation for `GITHUB_` environment
variable definitions](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables))
## Security recommendations
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.
* [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.
* [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.
## Using this action
There are five different supported ways to retrieve credentials:
- Using GitHub's OIDC provider (`AssumeRoleWithWebIdentity`)
- Proceeding as an IAM user (No STS call is made)
- Using access keys as action input (`AssumeRole`)
- Using a WebIdentity Token File (`AssumeRoleWithWebIdentity`)
- Using existing credentials in your runner (`AssumeRole`)
We recommend using [GitHub's OIDC provider](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services) to get short-lived AWS credentials needed for your actions. See [OIDC](#OIDC) for more information on how to setup your AWS account to assume a role with OIDC.
The following table describes which method is used based on which values are supplied to the Action:
| **Identity Used** | `aws-access-key-id` | `role-to-assume` | `web-identity-token-file` | `role-chaining` | `id-token` permission
| --------------------------------------------------------------- | ------------------- | ---------------- | ------------------------- | - | - |
| [✅ Recommended] Assume Role directly using GitHub OIDC provider | | ✔ | | | ✔ |
| IAM User | ✔ | | | | |
| Assume Role using IAM User credentials | ✔ | ✔ | | | |
| Assume Role using WebIdentity Token File credentials | | ✔ | ✔ | | |
| Assume Role using existing credentials | | ✔ | | ✔ | |
*Note: `role-chaining` is not necessary to use existing credentials in every use case. If you're getting a "Credentials loaded by the SDK do not match" error, try enabling this prop.
### Credential Lifetime
The default session duration is **1 hour**.
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.
### External ID
If your role requires an external ID to assume, you can provide the external ID with the `role-external-id` input
### Session tagging and name
The default session name is "GitHubActions", and you can modify it by specifying the desired name in `role-session-name`.
The session will be tagged with the following tags: (`GITHUB_` environment variable definitions can be
[found here](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/using-environment-variables#default-environment-variables))
| Key | Value |
| ---------- | ----------------- |
@@ -227,35 +195,38 @@ variable definitions](https://help.github.com/en/actions/automating-your-workflo
| Commit | GITHUB_SHA |
_Note: all tag values must conform to
[the tag requirements](https://docs.aws.amazon.com/STS/latest/APIReference/API_Tag.html).
[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 unless you are using OIDC.
The action will use session tagging by default during role assumption, unless you are assuming a role with a WebIdentity.
For WebIdentity role assumption, the session tags have to be included
in the encoded WebIdentity token. This means that Tags can only be supplied by
the OIDC provider, and they cannot set during the AssumeRoleWithWebIdentity API call
within the Action. See [issue 419](https://github.com/aws-actions/configure-aws-credentials/issues/419) for more info
You can skip this session tagging by providing
`role-skip-session-tagging` as true in the action's inputs:
```yaml
uses: aws-actions/configure-aws-credentials@v3
with:
role-skip-session-tagging: true
```
### Session policies
Session policies are not required, but they allow you to limit the scope of the
fetched credentials without making changes to IAM roles. You can specify inline
session policies right in your workflow file, or refer to an existing managed
session policy by its ARN.
#### Inline session policies
An IAM policy in stringified JSON format that you want to use as an inline
session policy. Depending on preferences, the JSON could be written on a single
line.
<details>
<summary>Inline session policy examples</summary>
An IAM policy in stringified JSON format that you want to use as an inline session policy.
Depending on preferences, the JSON could be written on a single line like this:
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
inline-session-policy: '{"Version":"2012-10-17","Statement":[{"Sid":"Stmt1","Effect":"Allow","Action":"s3:List*","Resource":"*"}]}'
```
Or we can have a nicely formatted JSON as well:
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
inline-session-policy: >-
{
@@ -270,120 +241,146 @@ Or we can have a nicely formatted JSON as well:
]
}
```
</details>
#### Managed session policies
The Amazon Resource Names (ARNs) of the IAM managed policies that you want to
use as managed session policies. The policies must exist in the same account as
the role.
<details>
<summary>Managed session policy examples</summary>
The Amazon Resource Names (ARNs) of the IAM managed policies that you want to use as managed session policies.
The policies must exist in the same account as the role. You can pass a single managed policy like this:
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
managed-session-policies: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
```
And we can pass multiple managed policies likes this:
```yaml
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
managed-session-policies: |
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
arn:aws:iam::aws:policy/AmazonS3OutpostsReadOnlyAccess
```
</details>
OIDC Configuration
-------------------
We recommend using [GitHub's OIDC
provider](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)
to get short-lived AWS credentials needed for your actions. When using OIDC, you
configure IAM to accept JWTs from GitHub's OIDC endpoint. This action will
then create a JWT unique to the workflow run using the OIDC endpoint, and it
will use the JWT to assume the specified role with short-term credentials.
### Misc
To get this to work
1. Configure your workflow to use the `id-token: write` permission.
2. Configure your audience, if required.
3. In your AWS account, configure IAM to trust GitHub's OIDC identity provider.
4. Configure an IAM role with appropriate claim limits and permission scope.
#### Adjust the retry mechanism
You can now configure retry settings for when the STS call fails. By default, we retry with exponential backoff `12` times. You can disable this behavior altogether by setting the `disable-retry` input to `true`, or you can configure the number of times it retries with the `retry-max-attempts` input.
*Note*: Naming your role "GitHubActions" has been reported to not work. See
[#953](https://github.com/aws-actions/configure-aws-credentials/issues/953).
#### Mask account ID
Your account ID is not masked by default in workflow logs since it's not considered sensitive information. However, you can set the `mask-aws-account-id` input to `true` to mask your account ID in workflow logs if desired.
5. Specify that role's ARN when setting up this action.
#### Unset current credentials
Sometimes, existing credentials in your runner can get in the way of the intended outcome, and the recommended solution is to include another step in your workflow which unsets the environment variables set by this action. Now if you set the `unset-current-credentials` input to `true`, the workaround is made eaiser
### OIDC Audience
#### Special characters in AWS_SECRET_ACCESS_KEY
Some edge cases are unable to properly parse an `AWS_SECRET_ACCESS_KEY` if it
contains special characters. For more information, please see the
[AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-troubleshooting.html#tshoot-signature-does-not-match).
If you set the `special-characters-workaround` option, this action will
continually retry fetching credentials until we get one that does not have
special characters. This option overrides the `disable-retry` and
`retry-max-attempts` options.
When the JWT is created, an audience needs to be specified. Normally, you would
use `sts.amazonaws.com`, and this action uses this by default if you don't
specify one. This will work for most cases. Changing the default audience may
be necessary when using non-default AWS partitions, such as China regions.
You can specify the audience through the `audience` input:
## OIDC
We recommend using [GitHub's OIDC provider](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services) to get short-lived AWS credentials needed for your actions. When using OIDC, this action will create a JWT unique to the workflow run, and it will use this JWT to assume the role. For this action to create the JWT, it is required for your workflow to have the `id-token: write` permission:
```yaml
permissions:
id-token: write
contents: read
```
### Audience
When the JWT is created, an audience needs to be specified. By default, the audience is `sts.amazonaws.com` and this will work for most cases. Changing the default audience may be necessary when using non-default AWS partitions. You can specify the audience through the `audience` input:
```yaml
- name: Configure AWS Credentials for China region audience
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
audience: sts.amazonaws.com.cn
aws-region: cn-northwest-1
role-to-assume: arn:aws-cn:iam::123456789100:role/my-github-actions-role
aws-region: us-east-3
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
```
### Configuring IAM to trust GitHub
To use GitHub's OIDC provider, you must first set up federation in your AWS
account. This involves creating an IAM Identity Provider that trusts GitHub's
OIDC endpoint. You can create an IAM Identity Provider in the AWS Management
Console by specifying the following details:
- **Provider Type**: OIDC
- **Provider URL**: `https://token.actions.githubusercontent.com`
- **Audience**: `sts.amazonaws.com` (or your custom audience if you specified
one in the `audience` input)
### Sample IAM OIDC CloudFormation Template
To use GitHub's OIDC provider, you must first set up federation
with the provider in as an IAM IdP. The GitHub OIDC provider only needs to be
created once per account (i.e. multiple IAM Roles that can be assumed by the
GitHub's OIDC can share a single OIDC Provider).
Prior versions of this documentation gave instructions for specifying the
certificate fingerprint, but this is no longer necessary. The thumbprint, if
specified, will be ignored.
Note that the thumbprint has been set to all F's because the thumbprint is not
used when authenticating `tokens.actions.githubusercontent.com`. Instead, IAM
uses its library of trusted CAs to authenticate. However, this value is still
required by the API.
You can also create the IAM Identity Provider using the AWS CLI:
This CloudFormation template will configure the IdP for you. You can copy the
template below, or load it from here:
https://d38mtn6aq9zhn6.cloudfront.net/configure-aws-credentials-latest.yml
```bash
aws iam create-open-id-connect-provider \
--url https://token.actions.githubusercontent.com \
--client-id-list sts.amazonaws.com
```yaml
Parameters:
GitHubOrg:
Description: Name of GitHub organization/user (case sensitive)
Type: String
RepositoryName:
Description: Name of GitHub repository (case sensitive)
Type: String
OIDCProviderArn:
Description: Arn for the GitHub OIDC Provider.
Default: ""
Type: String
OIDCAudience:
Description: Audience supplied to configure-aws-credentials.
Default: "sts.amazonaws.com"
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:
StringEquals:
token.actions.githubusercontent.com:aud: !Ref OIDCAudience
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:
- ffffffffffffffffffffffffffffffffffffffff
Outputs:
Role:
Value: !GetAtt Role.Arn
```
### Claims and scoping permissions
To align with the Amazon IAM best practice of [granting least
privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege),
the assume role policy document should contain a
[`Condition`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html)
that specifies a subject (`sub`) allowed to assume the role. [GitHub also
recommends](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#defining-trust-conditions-on-cloud-roles-using-oidc-claims)
filtering for the correct audience (`aud`). See [AWS IAM
documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif)
on which claims you can filter for in your trust policies.
To align with the Amazon IAM best practice of [granting least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege), the assume role policy document should contain a [`Condition`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html) that specifies a subject (`sub`) allowed to assume the role. [GitHub also recommends](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#defining-trust-conditions-on-cloud-roles-using-oidc-claims) filtering for the correct audience (`aud`). See [AWS IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-wif) on which claims you can filter for in your trust policies.
Without a subject (`sub`) condition, any GitHub user or repository could
potentially assume the role. The subject can be scoped to a GitHub organization
and repository as shown in the CloudFormation template. However, scoping it down
to your org and repo may cause the role assumption to fail in some cases. See
[Example subject claims](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims)
for specific details on what the subject value will be depending on your
workflow. You can also [customize your subject claim](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#customizing-the-token-claims)
if you want full control over the information you can filter for in your trust
policy. If you aren't sure what your subject (`sub`) key is, you can add the
[`actions-oidc-debugger`](https://github.com/github/actions-oidc-debugger)
action to your workflow to see the value of the subject (`sub`) key, as well as
other claims.
Without a subject (`sub`) condition, any GitHub user or repository could potentially assume the role. The subject can be scoped to a GitHub organization and repository as shown in the CloudFormation template. However, scoping it down to your org and repo may cause the role assumption to fail in some cases. See [Example subject claims](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#example-subject-claims) for specific details on what the subject value will be depending on your workflow. You can also [customize your subject claim](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#customizing-the-token-claims) if you want full control over the information you can filter for in your trust policy. If you aren't sure what your subject (`sub`) key is, you can add the [`actions-oidc-debugger`](https://github.com/github/actions-oidc-debugger) action to your workflow to see the value of the subject (`sub`) key, as well as other claims.
Additional claim conditions can be added for higher specificity as explained in
the [GitHub documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect).
Due to implementation details, not every OIDC claim is presently supported by
IAM.
Additional claim conditions can be added for higher specificity as explained in the [GitHub documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). Due to implementation details, not every OIDC claim is presently supported by IAM.
### Further information about OIDC
### Further info
For further information on OIDC and GitHub Actions, please see:
@@ -393,48 +390,116 @@ For further information on OIDC and GitHub Actions, please see:
* [GitHub docs: Configuring OpenID Connect in Amazon Web Services](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)
* [GitHub changelog: GitHub Actions: Secure cloud deployments with OpenID Connect](https://github.blog/changelog/2021-10-27-github-actions-secure-cloud-deployments-with-openid-connect/)
Examples
--------
## Self-Hosted Runners
### AssumeRoleWithWebIdentity
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. We will use the standard AWS JavaScript SDK credential
resolution methods to find your credentials, so if the AWS JS SDK can
authenticate on your runner, this Action will as well.
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/v3/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@v3
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@v3
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.
### Proxy Configuration
If you run in self-hosted environments and in secured environment where you need
use a specific proxy you can set it in the action manually.
Additionally this action will always consider already configured proxy in the
environment.
Manually configured proxy:
```yaml
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: us-east-2
role-to-assume: my-github-actions-role
http-proxy: "http://companydomain.com:3128"
```
Proxy configured in the environment variable:
```bash
# Your environment configuration
HTTP_PROXY="http://companydomain.com:3128"
```
The action will read the underlying proxy configuration from the environment and
you don't need to configure it in the action.
### 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.
## Examples
### AssumeRoleWithWebIdentity (recommended)
```yaml
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
role-session-name: MySessionName
```
In this example, the Action will load the OIDC token from the GitHub-provided
environment variable and use it to assume the role
`arn:aws:iam::123456789100:role/my-github-actions-role` with the session name
`MySessionName`.
In this example, the Action will load the OIDC token from the GitHub-provided environment variable and use it to assume the role `arn:aws:iam::123456789100:role/my-github-actions-role` with the session name `MySessionName`.
### AssumeRole with role previously assumed by action in same workflow
```yaml
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
role-session-name: MySessionName
- name: Configure other AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::987654321000:role/my-second-role
role-session-name: MySessionName
role-chaining: true
```
In this two-step example, the first step will use OIDC to assume the role
`arn:aws:iam::123456789100:role/my-github-actions-role` just as in the prior
example. Following that, a second step will use this role to assume a different
role, `arn:aws:iam::987654321000:role/my-second-role`.
In this two-step example, the first step will use OIDC to assume the role `arn:aws:iam::123456789100:role/my-github-actions-role` just as in the prior example. Following that, a second step will use this role to assume a different role, `arn:aws:iam::987654321000:role/my-second-role`.
### AssumeRole with static IAM credentials in repository secrets
```yaml
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
@@ -444,16 +509,13 @@ role, `arn:aws:iam::987654321000:role/my-second-role`.
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`.
In this example, the secret `AWS_ROLE_TO_ASSUME` contains a string like `arn:aws:iam::123456789100:role/my-github-actions-role`. To assume a role in the same account as the static credentials, you can simply specify the role name, like `role-to-assume: my-github-actions-role`.
### Retrieving credentials from step output, AssumeRole with temporary credentials
```yaml
- name: Configure AWS Credentials 1
id: creds
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: us-east-2
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
@@ -462,7 +524,7 @@ name, like `role-to-assume: my-github-actions-role`.
run: |
aws sts get-caller-identity
- name: Configure AWS Credentials 2
uses: aws-actions/configure-aws-credentials@v4.2.1
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: us-east-2
aws-access-key-id: ${{ steps.creds.outputs.aws-access-key-id }}
@@ -473,18 +535,10 @@ name, like `role-to-assume: my-github-actions-role`.
run: |
aws sts get-caller-identity
```
This example shows that you can reference the fetched credentials as outputs if
`output-credentials` is set to true. This example also shows that you can use
the `aws-session-token` input in a situation where session tokens are fetched
and passed to this action.
License
-------
This example shows that you can reference the fetched credentials as outputs if `output-credentials` is set to true. This example also shows that you can use the `aws-session-token` input in a situation where session tokens are fetched and passed to this action.
## License Summary
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](mailto:aws-security@amazon.com) directly.
## 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).
+215 -208
View File
@@ -855,9 +855,6 @@ Apache-2.0
limitations under the License.
@aws-sdk/core
Apache-2.0
@aws-sdk/credential-provider-env
Apache-2.0
Apache License
@@ -3310,7 +3307,7 @@ Apache-2.0
limitations under the License.
@aws-sdk/region-config-resolver
@aws-sdk/node-http-handler
Apache-2.0
Apache License
Version 2.0, January 2004
@@ -3718,6 +3715,210 @@ Apache License
See the License for the specific language governing permissions and
limitations under the License.
@aws-sdk/types
Apache-2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@aws-sdk/util-endpoints
Apache-2.0
Apache License
@@ -9850,210 +10051,6 @@ Apache-2.0
limitations under the License.
@smithy/util-endpoints
Apache-2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@smithy/util-hex-encoding
Apache-2.0
Apache License
@@ -11278,6 +11275,16 @@ Apache License
See the License for the specific language governing permissions and
limitations under the License.
@vercel/ncc
MIT
Copyright 2018 ZEIT, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
agent-base
MIT
-2
View File
@@ -1,2 +0,0 @@
const { fs } = require('memfs');
module.exports = fs;
-8
View File
@@ -61,10 +61,6 @@ inputs:
output-credentials:
description: Whether to set credentials as step output
required: false
output-env-credentials:
description: Whether to export credentials as environment variables. If you set this to false, you probably want to use output-credentials.
required: false
default: true
unset-current-credentials:
description: Whether to unset the existing credentials in your runner. May be useful if you run this action multiple times in the same job
required: false
@@ -77,8 +73,6 @@ inputs:
special-characters-workaround:
description: Some environments do not support special characters in AWS_SECRET_ACCESS_KEY. This option will retry fetching credentials until the secret access key does not contain special characters. This option overrides disable-retry and retry-max-attempts. This option is disabled by default
required: false
use-existing-credentials:
description: When enabled, this option will check if there are already valid credentials in the environment. If there are, new credentials will not be fetched. If there are not, the action will run as normal.
outputs:
aws-account-id:
description: The AWS account ID for the provided credentials
@@ -88,5 +82,3 @@ outputs:
description: The AWS secret access key for the provided credentials
aws-session-token:
description: The AWS session token for the provided credentials
aws-expiration:
description: The expiration time for the provided credentials
-34
View File
@@ -1,34 +0,0 @@
{
"formatter": {
"indentStyle": "space",
"lineWidth": 120,
"indentWidth": 2,
"lineEnding": "lf",
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"performance": {
"noDelete": "off"
},
"complexity": {
"noExtraBooleanCast": "off"
}
}
},
"javascript": {
"formatter": {
"trailingCommas": "all",
"jsxQuoteStyle": "double",
"quoteStyle": "single",
"bracketSpacing": true,
"arrowParentheses": "always"
}
},
"json": {
"formatter": {
"trailingCommas": "none"
}
}
}
Generated Vendored
+16903 -45902
View File
File diff suppressed because one or more lines are too long
+14
View File
@@ -0,0 +1,14 @@
import { STSClient } from '@aws-sdk/client-sts';
export interface CredentialsClientProps {
region?: string;
proxyServer?: string;
}
export declare class CredentialsClient {
region?: string;
private _stsClient?;
private readonly requestHandler?;
constructor(props: CredentialsClientProps);
get stsClient(): STSClient;
validateCredentials(expectedAccessKeyId?: string, roleChaining?: boolean): Promise<void>;
private loadCredentials;
}
+15
View File
@@ -0,0 +1,15 @@
import type { CredentialsClient } from './CredentialsClient';
export interface assumeRoleParams {
credentialsClient: CredentialsClient;
roleToAssume: string;
roleDuration: number;
roleSessionName: string;
roleSkipSessionTagging?: boolean;
sourceAccountId?: string;
roleExternalId?: string;
webIdentityTokenFile?: string;
webIdentityToken?: string;
inlineSessionPolicy?: string;
managedSessionPolicies?: any[];
}
export declare function assumeRole(params: assumeRoleParams): Promise<import("@aws-sdk/client-sts").AssumeRoleCommandOutput>;
+11
View File
@@ -0,0 +1,11 @@
/**
* When the GitHub Actions job is done, clean up any environment variables that
* may have been set by the configure-aws-credentials steps in the job.
*
* Environment variables are not intended to be shared across different jobs in
* the same GitHub Actions workflow: GitHub Actions documentation states that
* each job runs in a fresh instance. However, doing our own cleanup will
* give us additional assurance that these environment variables are not shared
* with any other jobs.
*/
export declare function cleanup(): void;
+16
View File
@@ -0,0 +1,16 @@
import type { Credentials } from '@aws-sdk/client-sts';
import type { CredentialsClient } from './CredentialsClient';
export declare function exportCredentials(creds?: Partial<Credentials>, outputCredentials?: boolean): void;
export declare function unsetCredentials(): void;
export declare function exportRegion(region: string): void;
export declare function exportAccountId(credentialsClient: CredentialsClient, maskAccountId?: boolean): Promise<string>;
export declare function sanitizeGitHubVariables(name: string): string;
export declare function defaultSleep(ms: number): Promise<unknown>;
declare let sleep: typeof defaultSleep;
export declare function withsleep(s: typeof sleep): void;
export declare function reset(): void;
export declare function verifyKeys(creds: Partial<Credentials> | undefined): boolean;
export declare function retryAndBackoff<T>(fn: () => Promise<T>, isRetryable: boolean, maxRetries?: number, retries?: number, base?: number): Promise<T>;
export declare function errorMessage(error: unknown): string;
export declare function isDefined<T>(i: T | undefined | null): i is T;
export {};
+1
View File
@@ -0,0 +1 @@
export declare function run(): Promise<void>;
+1
View File
@@ -0,0 +1 @@
export {};
+1
View File
@@ -0,0 +1 @@
export {};
+1
View File
@@ -0,0 +1 @@
export {};
Generated Vendored
+17706 -46819
View File
File diff suppressed because one or more lines are too long
@@ -6,7 +6,7 @@ jobs:
sast-guard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: grolston/guard-action@main
with:
data_directory: './cloudformation/' ## change to your template directory
+3 -3
View File
@@ -18,16 +18,16 @@ jobs:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v3
with:
aws-region: us-east-1
## the following creates an ARN based on the values entered into github secrets
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_DEPLOY_ROLE }}
role-session-name: myGitHubActions
- name: Deploy EC2 Bastion
uses: aws-actions/aws-cloudformation-github-deploy@v1.3.0
uses: aws-actions/aws-cloudformation-github-deploy@v1.0.3
with:
name: myEC2bastion
## change to path to template in your github repo
+15383 -4440
View File
File diff suppressed because it is too large Load Diff
+32 -24
View File
@@ -1,14 +1,11 @@
{
"name": "configure-aws-credentials",
"description": "A GitHub Action to configure AWS credentials",
"version": "4.3.0",
"scripts": {
"build": "tsc",
"lint": "biome check --error-on-warnings ./src",
"lint:fix": "biome check --write ./src",
"package": "npm run build && ncc build --license THIRD-PARTY -o dist && ncc build src/cleanup/index.ts -o dist/cleanup && cpy dist/THIRD-PARTY . && del-cli dist/THIRD-PARTY",
"test": "npm run lint && vitest run && npm run build",
"clean": "del-cli coverage test-reports node_modules"
"build": "tsc --project tsconfig.build.json",
"lint": "eslint .",
"package": "npm run build && ncc build --license THIRD-PARTY -o dist && ncc build src/cleanup/index.ts -o dist/cleanup && copyup -E dist/THIRD-PARTY . && del-cli dist/THIRD-PARTY",
"test": "npm run lint && jest --verbose"
},
"author": {
"name": "Amazon.com, Inc. or its affiliates",
@@ -16,26 +13,36 @@
"organization": true
},
"devDependencies": {
"@aws-sdk/credential-provider-env": "^3.858.0",
"@biomejs/biome": "2.1.3",
"@smithy/property-provider": "^4.0.3",
"@types/node": "^24.1.0",
"@vercel/ncc": "^0.38.3",
"@vitest/coverage-v8": "^3.2.4",
"aws-sdk-client-mock": "^4.1.0",
"cpy-cli": "^5.0.0",
"del-cli": "^6.0.0",
"@aws-sdk/credential-provider-env": "^3.186.0",
"@smithy/property-provider": "^2.0.6",
"@jest/globals": "^29.6.4",
"@types/jest": "^29.5.4",
"@types/node": "^20",
"@typescript-eslint/eslint-plugin": "<=5.62.0",
"@typescript-eslint/parser": "<=5.62.0",
"@vercel/ncc": "^0.38.0",
"aws-sdk-client-mock": "^3.0.0",
"copyfiles": "^2.4.1",
"del-cli": "^5.1.0",
"eslint": "^8",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-node": "^0.3.6",
"eslint-import-resolver-typescript": "^3.5.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.6.4",
"jest-junit": "^16",
"json-schema": "^0.4.0",
"memfs": "^4.25.1",
"standard-version": "^9.5.0",
"typescript": "^5.8.3",
"vitest": "^3.2.4"
"prettier": "^3.0.3",
"standard-version": "^9",
"ts-jest": "^29.0.3",
"typescript": "^5.2.2"
},
"dependencies": {
"@actions/core": "^1.11.1",
"@aws-sdk/client-sts": "^3.858.0",
"@smithy/node-http-handler": "^4.1.0",
"https-proxy-agent": "^7.0.6"
"@actions/core": "^1.10.0",
"@aws-sdk/client-sts": "^3",
"@smithy/node-http-handler": "^2.0.0",
"https-proxy-agent": "^5.0.0"
},
"keywords": [
"aws",
@@ -48,6 +55,7 @@
"main": "build/index.js",
"license": "MIT",
"homepage": "https://github.com/aws-actions/configure-aws-credentials",
"version": "0.0.0",
"bugs": {
"url": "https://github.com/aws-actions/configure-aws-credentials/issues"
},
-13
View File
@@ -1,13 +0,0 @@
{
"packages": {
".": {
"changelog-path": "CHANGELOG.md",
"release-type": "node",
"bump-minor-pre-major": false,
"bump-patch-for-minor-pre-major": false,
"draft": false,
"prerelease": false
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}
+2 -3
View File
@@ -1,6 +1,5 @@
import { info } from '@actions/core';
import { STSClient } from '@aws-sdk/client-sts';
import type { AwsCredentialIdentity } from '@aws-sdk/types';
import { NodeHttpHandler } from '@smithy/node-http-handler';
import { HttpsProxyAgent } from 'https-proxy-agent';
import { errorMessage } from './helpers';
@@ -41,7 +40,7 @@ export class CredentialsClient {
}
public async validateCredentials(expectedAccessKeyId?: string, roleChaining?: boolean) {
let credentials: AwsCredentialIdentity;
let credentials;
try {
credentials = await this.loadCredentials();
if (!credentials.accessKeyId) {
@@ -56,7 +55,7 @@ export class CredentialsClient {
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',
'Unexpected failure: Credentials loaded by the SDK do not match the access key ID configured by the action'
);
}
}
+28 -25
View File
@@ -1,6 +1,6 @@
import assert from 'node:assert';
import fs from 'node:fs';
import path from 'node:path';
import assert from 'assert';
import fs from 'fs';
import path from 'path';
import * as core from '@actions/core';
import type { AssumeRoleCommandInput, STSClient, Tag } from '@aws-sdk/client-sts';
import { AssumeRoleCommand, AssumeRoleWithWebIdentityCommand } from '@aws-sdk/client-sts';
@@ -15,7 +15,7 @@ async function assumeRoleWithOIDC(params: AssumeRoleCommandInput, client: STSCli
new AssumeRoleWithWebIdentityCommand({
...params,
WebIdentityToken: webIdentityToken,
}),
})
);
return creds;
} catch (error) {
@@ -27,10 +27,10 @@ async function assumeRoleWithWebIdentityTokenFile(
params: AssumeRoleCommandInput,
client: STSClient,
webIdentityTokenFile: string,
workspace: string,
workspace: string
) {
core.debug(
'webIdentityTokenFile provided. Will call sts:AssumeRoleWithWebIdentity and take session tags from token contents.',
'webIdentityTokenFile provided. Will call sts:AssumeRoleWithWebIdentity and take session tags from token contents.'
);
const webIdentityTokenFilePath = path.isAbsolute(webIdentityTokenFile)
? webIdentityTokenFile
@@ -46,7 +46,7 @@ async function assumeRoleWithWebIdentityTokenFile(
new AssumeRoleWithWebIdentityCommand({
...params,
WebIdentityToken: webIdentityToken,
}),
})
);
return creds;
} catch (error) {
@@ -75,7 +75,7 @@ export interface assumeRoleParams {
webIdentityTokenFile?: string;
webIdentityToken?: string;
inlineSessionPolicy?: string;
managedSessionPolicies?: { arn: string }[];
managedSessionPolicies?: any[];
}
export async function assumeRole(params: assumeRoleParams) {
@@ -108,11 +108,8 @@ export async function assumeRole(params: assumeRoleParams) {
{ Key: 'Actor', Value: sanitizeGitHubVariables(GITHUB_ACTOR) },
{ Key: 'Commit', Value: GITHUB_SHA },
];
if (process.env.GITHUB_REF) {
tagArray.push({
Key: 'Branch',
Value: sanitizeGitHubVariables(process.env.GITHUB_REF),
});
if (process.env['GITHUB_REF']) {
tagArray.push({ Key: 'Branch', Value: sanitizeGitHubVariables(process.env['GITHUB_REF']) });
}
const tags = roleSkipSessionTagging ? undefined : tagArray;
if (!tags) {
@@ -126,7 +123,7 @@ export async function assumeRole(params: assumeRoleParams) {
if (!roleArn.startsWith('arn:aws')) {
assert(
isDefined(sourceAccountId),
'Source Account ID is needed if the Role Name is provided and not the Role Arn.',
'Source Account ID is needed if the Role Name is provided and not the Role Arn.'
);
roleArn = `arn:aws:iam::${sourceAccountId}:role/${roleArn}`;
}
@@ -148,16 +145,22 @@ export async function assumeRole(params: assumeRoleParams) {
const stsClient = credentialsClient.stsClient;
// Assume role using one of three methods
if (!!webIdentityToken) {
return assumeRoleWithOIDC(commonAssumeRoleParams, stsClient, webIdentityToken);
switch (true) {
case !!webIdentityToken: {
return assumeRoleWithOIDC(commonAssumeRoleParams, stsClient, webIdentityToken!);
}
case !!webIdentityTokenFile: {
return assumeRoleWithWebIdentityTokenFile(
commonAssumeRoleParams,
stsClient,
webIdentityTokenFile!,
GITHUB_WORKSPACE
);
}
default: {
return assumeRoleWithCredentials(commonAssumeRoleParams, stsClient);
}
}
if (!!webIdentityTokenFile) {
return assumeRoleWithWebIdentityTokenFile(
commonAssumeRoleParams,
stsClient,
webIdentityTokenFile,
GITHUB_WORKSPACE,
);
}
return assumeRoleWithCredentials(commonAssumeRoleParams, stsClient);
}
+12 -15
View File
@@ -13,21 +13,18 @@ import { errorMessage } from '../helpers';
*/
export function cleanup() {
const outputEnvCredentialsInput = core.getInput('output-env-credentials', { required: false }) || 'true';
if (outputEnvCredentialsInput === 'true') {
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(errorMessage(error));
}
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(errorMessage(error));
}
}
/* c8 ignore start */
+20 -91
View File
@@ -7,73 +7,25 @@ const MAX_TAG_VALUE_LENGTH = 256;
const SANITIZATION_CHARACTER = '_';
const SPECIAL_CHARS_REGEX = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]+/;
export function translateEnvVariables() {
const envVars = [
'AWS_REGION',
'ROLE_TO_ASSUME',
'WEB_IDENTITY_TOKEN_FILE',
'ROLE_CHAINING',
'AUDIENCE',
'HTTP_PROXY',
'MASK_AWS_ACCOUNT_ID',
'ROLE_DURATION_SECONDS',
'ROLE_EXTERNAL_ID',
'ROLE_SESSION_NAME',
'ROLE_SKIP_SESSION_TAGGING',
'INLINE_SESSION_POLICY',
'MANAGED_SESSION_POLICIES',
'OUTPUT_CREDENTIALS',
'UNSET_CURRENT_CREDENTIALS',
'DISABLE_RETRY',
'RETRY_MAX_ATTEMPTS',
'SPECIAL_CHARACTERS_WORKAROUND',
'USE_EXISTING_CREDENTIALS',
];
// Treat HTTPS_PROXY as HTTP_PROXY. Precedence is HTTPS_PROXY > HTTP_PROXY
if (process.env.HTTPS_PROXY) process.env.HTTP_PROXY = process.env.HTTPS_PROXY;
for (const envVar of envVars) {
if (process.env[envVar]) {
const inputKey = `INPUT_${envVar.replace(/_/g, '-')}`;
process.env[inputKey] = process.env[inputKey] || process.env[envVar];
}
}
}
// Configure the AWS CLI and AWS SDKs using environment variables and set them as secrets.
// Setting the credentials as secrets masks them in Github Actions logs
export function exportCredentials(
creds?: Partial<Credentials>,
outputCredentials?: boolean,
outputEnvCredentials?: boolean,
) {
export function exportCredentials(creds?: Partial<Credentials>, outputCredentials?: boolean) {
if (creds?.AccessKeyId) {
core.setSecret(creds.AccessKeyId);
core.exportVariable('AWS_ACCESS_KEY_ID', creds.AccessKeyId);
}
if (creds?.SecretAccessKey) {
core.setSecret(creds.SecretAccessKey);
core.exportVariable('AWS_SECRET_ACCESS_KEY', creds.SecretAccessKey);
}
if (creds?.SessionToken) {
core.setSecret(creds.SessionToken);
}
if (outputEnvCredentials) {
if (creds?.AccessKeyId) {
core.exportVariable('AWS_ACCESS_KEY_ID', creds.AccessKeyId);
}
if (creds?.SecretAccessKey) {
core.exportVariable('AWS_SECRET_ACCESS_KEY', creds.SecretAccessKey);
}
if (creds?.SessionToken) {
core.exportVariable('AWS_SESSION_TOKEN', creds.SessionToken);
} else if (process.env.AWS_SESSION_TOKEN) {
// clear session token from previous credentials action
core.exportVariable('AWS_SESSION_TOKEN', '');
}
core.exportVariable('AWS_SESSION_TOKEN', creds.SessionToken);
} else if (process.env['AWS_SESSION_TOKEN']) {
// clear session token from previous credentials action
core.exportVariable('AWS_SESSION_TOKEN', '');
}
if (outputCredentials) {
@@ -86,27 +38,20 @@ export function exportCredentials(
if (creds?.SessionToken) {
core.setOutput('aws-session-token', creds.SessionToken);
}
if (creds?.Expiration) {
core.setOutput('aws-expiration', creds.Expiration);
}
}
}
export function unsetCredentials(outputEnvCredentials?: boolean) {
if (outputEnvCredentials) {
core.exportVariable('AWS_ACCESS_KEY_ID', '');
core.exportVariable('AWS_SECRET_ACCESS_KEY', '');
core.exportVariable('AWS_SESSION_TOKEN', '');
core.exportVariable('AWS_REGION', '');
core.exportVariable('AWS_DEFAULT_REGION', '');
}
export function unsetCredentials() {
core.exportVariable('AWS_ACCESS_KEY_ID', '');
core.exportVariable('AWS_SECRET_ACCESS_KEY', '');
core.exportVariable('AWS_SESSION_TOKEN', '');
core.exportVariable('AWS_REGION', '');
core.exportVariable('AWS_DEFAULT_REGION', '');
}
export function exportRegion(region: string, outputEnvCredentials?: boolean) {
if (outputEnvCredentials) {
core.exportVariable('AWS_DEFAULT_REGION', region);
core.exportVariable('AWS_REGION', region);
}
export function exportRegion(region: string) {
core.exportVariable('AWS_DEFAULT_REGION', region);
core.exportVariable('AWS_REGION', region);
}
// Obtains account ID from STS Client and sets it as output
@@ -114,16 +59,13 @@ export async function exportAccountId(credentialsClient: CredentialsClient, mask
const client = credentialsClient.stsClient;
const identity = await client.send(new GetCallerIdentityCommand({}));
const accountId = identity.Account;
const arn = identity.Arn;
if (!accountId || !arn) {
throw new Error('Could not get Account ID or ARN from STS. Did you set credentials?');
if (!accountId) {
throw new Error('Could not get Account ID from STS. Did you set credentials?');
}
if (maskAccountId) {
core.setSecret(accountId);
core.setSecret(arn);
}
core.setOutput('aws-account-id', accountId);
core.setOutput('authenticated-arn', arn);
return accountId;
}
@@ -174,7 +116,7 @@ export async function retryAndBackoff<T>(
isRetryable: boolean,
maxRetries = 12,
retries = 0,
base = 50,
base = 50
): Promise<T> {
try {
return await fn();
@@ -183,7 +125,7 @@ export async function retryAndBackoff<T>(
throw err;
}
// It's retryable, so sleep and retry.
await sleep(Math.random() * (2 ** retries * base));
await sleep(Math.random() * (Math.pow(2, retries) * base));
retries += 1;
if (retries >= maxRetries) {
throw err;
@@ -201,16 +143,3 @@ export function isDefined<T>(i: T | undefined | null): i is T {
return i !== undefined && i !== null;
}
/* c8 ignore stop */
export async function areCredentialsValid(credentialsClient: CredentialsClient) {
const client = credentialsClient.stsClient;
try {
const identity = await client.send(new GetCallerIdentityCommand({}));
if (identity.Account) {
return true;
}
return false;
} catch (_) {
return false;
}
}
+27 -55
View File
@@ -3,13 +3,11 @@ import type { AssumeRoleCommandOutput } from '@aws-sdk/client-sts';
import { assumeRole } from './assumeRole';
import { CredentialsClient } from './CredentialsClient';
import {
areCredentialsValid,
errorMessage,
exportAccountId,
exportCredentials,
exportRegion,
retryAndBackoff,
translateEnvVariables,
exportRegion,
exportCredentials,
exportAccountId,
unsetCredentials,
verifyKeys,
} from './helpers';
@@ -20,44 +18,30 @@ const REGION_REGEX = /^[a-z0-9-]+$/g;
export async function run() {
try {
translateEnvVariables();
// Get inputs
const AccessKeyId = core.getInput('aws-access-key-id', { required: false });
const SecretAccessKey = core.getInput('aws-secret-access-key', {
required: false,
});
const sessionTokenInput = core.getInput('aws-session-token', {
required: false,
});
const SecretAccessKey = core.getInput('aws-secret-access-key', { required: false });
const sessionTokenInput = core.getInput('aws-session-token', { required: false });
const SessionToken = sessionTokenInput === '' ? undefined : sessionTokenInput;
const region = core.getInput('aws-region', { required: true });
const roleToAssume = core.getInput('role-to-assume', { required: false });
const audience = core.getInput('audience', { required: false });
const maskAccountIdInput = core.getInput('mask-aws-account-id', { required: false }) || 'false';
const maskAccountId = maskAccountIdInput.toLowerCase() === 'true';
const roleExternalId = core.getInput('role-external-id', {
required: false,
});
const webIdentityTokenFile = core.getInput('web-identity-token-file', {
required: false,
});
const roleDuration =
Number.parseInt(core.getInput('role-duration-seconds', { required: false })) || DEFAULT_ROLE_DURATION;
const roleExternalId = core.getInput('role-external-id', { required: false });
const webIdentityTokenFile = core.getInput('web-identity-token-file', { required: false });
const roleDuration = parseInt(core.getInput('role-duration-seconds', { required: false })) || DEFAULT_ROLE_DURATION;
const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
const roleSkipSessionTaggingInput = core.getInput('role-skip-session-tagging', { required: false }) || 'false';
const roleSkipSessionTagging = roleSkipSessionTaggingInput.toLowerCase() === 'true';
const proxyServer = core.getInput('http-proxy', { required: false }) || process.env.HTTP_PROXY;
const inlineSessionPolicy = core.getInput('inline-session-policy', {
required: false,
});
const proxyServer = core.getInput('http-proxy', { required: false });
const inlineSessionPolicy = core.getInput('inline-session-policy', { required: false });
const managedSessionPoliciesInput = core.getMultilineInput('managed-session-policies', { required: false });
const managedSessionPolicies: { arn: string }[] = [];
const managedSessionPolicies: any[] = [];
const roleChainingInput = core.getInput('role-chaining', { required: false }) || 'false';
const roleChaining = roleChainingInput.toLowerCase() === 'true';
const outputCredentialsInput = core.getInput('output-credentials', { required: false }) || 'false';
const outputCredentials = outputCredentialsInput.toLowerCase() === 'true';
const outputEnvCredentialsInput = core.getInput('output-env-credentials', { required: false }) || 'true';
const outputEnvCredentials = outputEnvCredentialsInput.toLowerCase() === 'true';
const unsetCurrentCredentialsInput = core.getInput('unset-current-credentials', { required: false }) || 'false';
const unsetCurrentCredentials = unsetCurrentCredentialsInput.toLowerCase() === 'true';
const disableRetryInput = core.getInput('disable-retry', { required: false }) || 'false';
@@ -65,9 +49,7 @@ export async function run() {
const specialCharacterWorkaroundInput =
core.getInput('special-characters-workaround', { required: false }) || 'false';
const specialCharacterWorkaround = specialCharacterWorkaroundInput.toLowerCase() === 'true';
const useExistingCredentialsInput = core.getInput('use-existing-credentials', { required: false }) || 'false';
const useExistingCredentials = useExistingCredentialsInput.toLowerCase() === 'true';
let maxRetries = Number.parseInt(core.getInput('retry-max-attempts', { required: false })) || 12;
let maxRetries = parseInt(core.getInput('retry-max-attempts', { required: false })) || 12;
switch (true) {
case specialCharacterWorkaround:
// 😳
@@ -92,17 +74,17 @@ export async function run() {
!!roleToAssume &&
!webIdentityTokenFile &&
!AccessKeyId &&
!process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN &&
!process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] &&
!roleChaining
) {
core.info(
'It looks like you might be trying to authenticate with OIDC. Did you mean to set the `id-token` permission? ' +
'If you are not trying to authenticate with OIDC and the action is working successfully, you can ignore this message.',
'If you are not trying to authenticate with OIDC and the action is working successfully, you can ignore this message.'
);
}
return (
!!roleToAssume &&
!!process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN &&
!!process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] &&
!AccessKeyId &&
!webIdentityTokenFile &&
!roleChaining
@@ -110,29 +92,19 @@ export async function run() {
};
if (unsetCurrentCredentials) {
unsetCredentials(outputEnvCredentials);
unsetCredentials();
}
if (!region.match(REGION_REGEX)) {
throw new Error(`Region is not valid: ${region}`);
}
exportRegion(region, outputEnvCredentials);
exportRegion(region);
// Instantiate credentials client
const credentialsClient = new CredentialsClient({ region, proxyServer });
let sourceAccountId: string;
let webIdentityToken: string;
//if the user wants to attempt to use existing credentials, check if we have some already
if (useExistingCredentials) {
const validCredentials = await areCredentialsValid(credentialsClient);
if (validCredentials) {
core.notice('Pre-existing credentials are valid. No need to generate new ones.');
return;
}
core.notice('No valid credentials exist. Running as normal.');
}
// If OIDC is being used, generate token
// Else, export credentials provided as input
if (useGitHubOIDCProvider()) {
@@ -142,7 +114,7 @@ export async function run() {
return core.getIDToken(audience);
},
!disableRetry,
maxRetries,
maxRetries
);
} catch (error) {
throw new Error(`getIDToken call failed: ${errorMessage(error)}`);
@@ -155,7 +127,7 @@ export async function run() {
// Plus, in the assume role case, if the AssumeRole call fails, we want
// the source credentials to already be masked as secrets
// in any error messages.
exportCredentials({ AccessKeyId, SecretAccessKey, SessionToken }, outputCredentials, outputEnvCredentials);
exportCredentials({ AccessKeyId, SecretAccessKey, SessionToken });
} else if (!webIdentityTokenFile && !roleChaining) {
// Proceed only if credentials can be picked up
await credentialsClient.validateCredentials();
@@ -174,6 +146,7 @@ export async function run() {
if (roleToAssume) {
let roleCredentials: AssumeRoleCommandOutput;
do {
// eslint-disable-next-line no-await-in-loop
roleCredentials = await retryAndBackoff(
async () => {
return assumeRole({
@@ -191,28 +164,27 @@ export async function run() {
});
},
!disableRetry,
maxRetries,
maxRetries
);
// eslint-disable-next-line no-unmodified-loop-condition
} while (specialCharacterWorkaround && !verifyKeys(roleCredentials.Credentials));
core.info(`Authenticated as assumedRoleId ${roleCredentials.AssumedRoleUser?.AssumedRoleId}`);
exportCredentials(roleCredentials.Credentials, outputCredentials, outputEnvCredentials);
core.info(`Authenticated as assumedRoleId ${roleCredentials.AssumedRoleUser!.AssumedRoleId!}`);
exportCredentials(roleCredentials.Credentials, outputCredentials);
// We need to validate the credentials in 2 of our use-cases
// First: self-hosted runners. If the GITHUB_ACTIONS environment variable
// is set to `true` then we are NOT in a self-hosted runner.
// Second: Customer provided credentials manually (IAM User keys stored in GH Secrets)
if (!process.env.GITHUB_ACTIONS || AccessKeyId) {
if (!process.env['GITHUB_ACTIONS'] || AccessKeyId) {
await credentialsClient.validateCredentials(roleCredentials.Credentials?.AccessKeyId);
}
if (outputEnvCredentials) {
await exportAccountId(credentialsClient, maskAccountId);
}
await exportAccountId(credentialsClient, maskAccountId);
} else {
core.info('Proceeding with IAM user credentials');
}
} catch (error) {
core.setFailed(errorMessage(error));
const showStackTrace = process.env.SHOW_STACK_TRACE;
const showStackTrace = process.env['SHOW_STACK_TRACE'];
if (showStackTrace === 'true') {
throw error;
+32 -33
View File
@@ -1,34 +1,35 @@
import * as core from '@actions/core';
import { STSClient } from '@aws-sdk/client-sts';
import { mockClient } from 'aws-sdk-client-mock';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { cleanup } from '../src/cleanup';
import mocks from './mockinputs.test';
const mockedSTSClient = mockClient(STSClient);
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;
describe('Configure AWS Credentials cleanup', {}, () => {
beforeEach(() => {
// Reset mock state
vi.restoreAllMocks();
mockedSTSClient.reset();
// Mock GitHub Actions core functions
vi.spyOn(core, 'exportVariable').mockImplementation((_n, _v) => {});
vi.spyOn(core, 'setSecret').mockImplementation((_s) => {});
vi.spyOn(core, 'setFailed').mockImplementation((_m) => {});
vi.spyOn(core, 'setOutput').mockImplementation((_n, _v) => {});
vi.spyOn(core, 'debug').mockImplementation((_m) => {});
vi.spyOn(core, 'info').mockImplementation((_m) => {});
process.env = {
...mocks.envs,
AWS_ACCESS_KEY_ID: 'CLEANUPTEST',
AWS_SECRET_ACCESS_KEY: 'CLEANUPTEST',
AWS_SESSION_TOKEN: 'CLEANUPTEST',
AWS_REGION: 'CLEANUPTEST',
AWS_DEFAULT_REGION: 'CLEANUPTEST',
};
jest.resetModules();
jest.spyOn(core, 'exportVariable').mockImplementation();
jest.spyOn(core, 'setSecret').mockImplementation();
jest.spyOn(core, 'setOutput').mockImplementation();
jest.spyOn(core, 'setFailed').mockImplementation();
process.env = { ...OLD_ENV, ...ACTION_ENVIRONMENT_VARIABLES };
});
it('replaces AWS credential and region environment variables with empty strings', {}, () => {
afterEach(() => {
process.env = OLD_ENV;
});
test('replaces AWS credential and region env vars with empty strings', () => {
cleanup();
expect(core.setFailed).toHaveBeenCalledTimes(0);
expect(core.exportVariable).toHaveBeenCalledTimes(5);
@@ -38,16 +39,14 @@ describe('Configure AWS Credentials cleanup', {}, () => {
expect(core.exportVariable).toHaveBeenCalledWith('AWS_DEFAULT_REGION', '');
expect(core.exportVariable).toHaveBeenCalledWith('AWS_REGION', '');
});
it('handles errors', {}, () => {
vi.spyOn(core, 'exportVariable').mockImplementationOnce(() => {
throw new Error('Test error');
test('error is caught and fails the action', () => {
jest.spyOn(core, 'exportVariable').mockImplementation(() => {
throw new Error();
});
cleanup();
expect(core.setFailed).toHaveBeenCalled();
});
it(`doesn't export credentials as empty env variables if asked not to`, {}, () => {
vi.spyOn(core, 'getInput').mockImplementation(mocks.getInput(mocks.NO_ENV_CREDS_INPUTS));
cleanup();
expect(core.exportVariable).toHaveBeenCalledTimes(0);
});
});
+16 -54
View File
@@ -1,64 +1,26 @@
import { beforeEach } from 'node:test';
import * as core from '@actions/core';
import { describe, expect, it, vi } from 'vitest';
import * as helpers from '../src/helpers';
describe('Configure AWS Credentials helpers', {}, () => {
describe('helpers', () => {
beforeEach(() => {
vi.restoreAllMocks();
jest.resetModules();
jest.clearAllMocks();
});
it('removes brackets from GitHub Actor', {}, () => {
const actor = 'actor[bot]';
expect(helpers.sanitizeGitHubVariables(actor)).toBe('actor_bot_');
test('removes brackets from GitHub Actor', () => {
expect(helpers.sanitizeGitHubVariables('foo[bot]')).toEqual('foo_bot_');
});
it('can sleep', {}, async () => {
const sleep = helpers.defaultSleep(10);
await expect(Promise.race([sleep, new Promise((_, reject) => setTimeout(reject, 20))])).resolves.toBe(undefined);
});
it('removes special characters from workflow names', {}, () => {
test('removes special characters from worflow names', () => {
expect(helpers.sanitizeGitHubVariables('sdf234@#$%$^&*()_+{}|:"<>?')).toEqual('sdf234@__________+___:____');
});
it("doesn't retry non-retryable errors", {}, async () => {
const fn = vi.fn().mockRejectedValue('i am not retryable');
test('can sleep', () => {
const sleep = helpers.defaultSleep(10);
expect(Promise.race([sleep, new Promise((_res, rej) => setTimeout(rej, 20))])).resolves;
});
test("backoff function doesn't retry non-retryable errors", async () => {
const fn = jest.fn().mockRejectedValue('i am not retryable');
await expect(helpers.retryAndBackoff(fn, false)).rejects.toMatch('i am not retryable');
expect(fn).toHaveBeenCalledTimes(1);
});
it('can output creds when told to', {}, () => {
vi.spyOn(core, 'setOutput').mockImplementation(() => {});
vi.spyOn(core, 'setSecret').mockImplementation(() => {});
vi.spyOn(core, 'exportVariable').mockImplementation(() => {});
helpers.exportCredentials(
{ AccessKeyId: 'test', SecretAccessKey: 'test', SessionToken: 'test', Expiration: new Date(8640000000000000) },
true,
true,
);
expect(core.setOutput).toHaveBeenCalledTimes(4);
expect(core.setSecret).toHaveBeenCalledTimes(3);
expect(core.exportVariable).toHaveBeenCalledTimes(3);
});
it('can unset credentials', {}, () => {
const env = process.env;
helpers.unsetCredentials();
expect(process.env.AWS_ACCESS_KEY_ID).toBeUndefined;
expect(process.env.AWS_SECRET_ACCESS_KEY).toBeUndefined;
expect(process.env.AWS_SESSION_TOKEN).toBeUndefined;
expect(process.env.AWS_REGION).toBeUndefined;
expect(process.env.AWS_DEFAULT_REGION).toBeUndefined;
process.env = env;
});
it(`won't output credentials to env if told not to`, {}, () => {
vi.spyOn(core, 'setOutput').mockImplementation(() => {});
vi.spyOn(core, 'setSecret').mockImplementation(() => {});
vi.spyOn(core, 'exportVariable').mockImplementation(() => {});
helpers.exportCredentials(
{ AccessKeyId: 'test', SecretAccessKey: 'test', SessionToken: 'test', Expiration: new Date(8640000000000000) },
true,
false,
);
helpers.unsetCredentials(false);
helpers.exportRegion('fake-test-region', false);
expect(core.setOutput).toHaveBeenCalledTimes(4);
expect(core.setSecret).toHaveBeenCalledTimes(3);
expect(core.exportVariable).toHaveBeenCalledTimes(0);
});
});
+837 -379
View File
File diff suppressed because it is too large Load Diff
-114
View File
@@ -1,114 +0,0 @@
import type * as core from '@actions/core';
const inputs = {
GH_OIDC_INPUTS: {
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'special-characters-workaround': 'true',
},
IAM_USER_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'aws-region': 'fake-region-1',
},
IAM_ASSUMEROLE_INPUTS: {
'aws-access-key-id': 'MYAWSACCESSKEYID',
'aws-secret-access-key': 'MYAWSSECRETACCESSKEY',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
},
WEBIDENTITY_TOKEN_FILE_INPUTS: {
'web-identity-token-file': 'file.txt',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
},
EXISTING_ROLE_INPUTS: {
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'role-chaining': 'true',
'aws-region': 'fake-region-1',
},
USE_EXISTING_CREDENTIALS_INPUTS: {
'aws-region': 'fake-region-1',
'use-existing-credentials': 'true',
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
},
NO_ENV_CREDS_INPUTS: {
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'output-env-credentials': 'false',
},
STEP_BUT_NO_ENV_INPUTS: {
'role-to-assume': 'arn:aws:iam::111111111111:role/MY-ROLE',
'aws-region': 'fake-region-1',
'output-env-credentials': 'false',
'output-credentials': 'true',
},
};
const envs = {
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_WORKSPACE: '/home/github',
GITHUB_ACTIONS: 'true',
};
const outputs = {
STS_CREDENTIALS: {
Credentials: {
AccessKeyId: 'STSAWSACCESSKEYID',
SecretAccessKey: 'STSAWSSECRETACCESSKEY',
SessionToken: 'STSAWSSESSIONTOKEN',
Expiration: new Date(8640000000000000),
},
AssumedRoleUser: {
Arn: 'arn:aws:sts::111111111111:assumed-role/MY-ROLE/',
AssumedRoleId: 'AROAFAKEASSUMEDROLEID',
},
},
GET_CALLER_IDENTITY: {
Account: '111111111111',
Arn: 'arn:aws:iam::111111111111:role/MY-ROLE',
},
FAKE_STS_ACCESS_KEY_ID: 'STSAWSACCESSKEYID',
FAKE_STS_SECRET_ACCESS_KEY: 'STSAWSSECRETACCESSKEY',
FAKE_STS_SESSION_TOKEN: 'STSAWSSESSIONTOKEN',
ODD_CHARACTER_CREDENTIALS: {
Credentials: {
AccessKeyId: 'STSA#$%^&',
SecretAccessKey: 'STSA#$%^&Key',
SessionToken: 'STSA#$%^',
Expiration: new Date(8640000000000000),
},
AssumedRoleUser: {
Arn: 'arn:aws:sts::111111111111:assumed-role/MY-ROLE/',
AssumedRoleId: 'AROAFAKEASSUMEDROLEID',
},
},
};
export default {
getInput: (fakeEnv: Record<string, string>) => {
return (name: string, options?: core.InputOptions): string => {
if (!fakeEnv[name]) {
if (options?.required) throw new Error(`Input ${name} not found`);
return '';
}
return fakeEnv[name];
};
},
getMultilineInput: (fakeEnv: Record<string, string[]>) => {
return (name: string, options?: core.InputOptions): string[] => {
if (!fakeEnv[name]) {
if (options?.required) throw new Error(`Input ${name} not found`);
return [];
}
return fakeEnv[name];
};
},
...inputs,
outputs,
envs,
} as const;
+9
View File
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"exclude": [
"test/**/*.ts"
],
"compilerOptions": {
"rootDir": "src"
},
}
+11 -7
View File
@@ -7,24 +7,28 @@
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": false,
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"module": "CommonJS",
"resolveJsonModule": true,
"outDir": "build",
"declaration": false,
"declaration": true,
"newLine": "lf",
"noEmitOnError": true,
"sourceMap": true,
"disableSizeLimit": true,
"forceConsistentCasingInFileNames": true,
"lib": ["ES2020"],
"lib": [ "ES2020" ],
"target": "ES2020",
"noErrorTruncation": true,
"esModuleInterop": true,
"rootDir": "src"
"esModuleInterop": true
},
"include": ["src/**/*.ts"],
"exclude": ["test/**/*.ts"]
"include": [
"src/**/*.ts",
"test/**/*.ts"
],
"exclude": [],
}
-8
View File
@@ -1,8 +0,0 @@
{
"extends": "./tsconfig.json",
"include": ["test/**/*.ts", "src/**/*.ts"],
"exclude": [],
"compilerOptions": {
"rootDir": "./"
}
}
-10
View File
@@ -1,10 +0,0 @@
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
passWithNoTests: true,
include: ['test/**/*.test.ts'],
coverage: { enabled: true },
typecheck: { tsconfig: './tsconfig.test.json' },
},
});