mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-08-25 04:35:06 +09:00
Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 010d0da01d | |||
| b48e2ee5c6 | |||
| 183b94a269 | |||
| 1d4ae371e5 | |||
| 6a430ce1a4 | |||
| 8402193770 | |||
| f31c158843 | |||
| 164817a8f8 | |||
| e2c335e163 | |||
| a1a09b7ff2 | |||
| 53bf02c02f | |||
| 6960539309 | |||
| 83ceb16ee1 | |||
| 5cb52d02e4 | |||
| fbaaea8490 | |||
| 0d9b446851 | |||
| 51e898662e | |||
| dc894b4148 | |||
| 4f8ea089cf | |||
| ff5c452440 | |||
| 96cd64d434 | |||
| 3d11655d76 | |||
| e50f96d7c7 | |||
| 8025ae060f | |||
| bc2200e43c | |||
| 155b315cee | |||
| 59d2ad0a59 | |||
| 1067f72d75 | |||
| 393929845e | |||
| 8c3f20df09 | |||
| 50ac8dd1e1 | |||
| a2593d09d1 | |||
| 7a8dec84bd | |||
| 2b89f8a0da | |||
| 6488aec6e7 | |||
| 856a411d27 | |||
| 7e7ee94419 | |||
| 8ad39aa824 | |||
| 2014030530 | |||
| 3aeb7ba662 | |||
| 3994f1aeae | |||
| a3412312b9 | |||
| ef2571b57d | |||
| 8e373defe9 | |||
| 9555344752 | |||
| 72f2c7b9a3 | |||
| b0cb02aa90 | |||
| 7bac5f98a7 | |||
| 922470e4ee | |||
| d3c2317d0a | |||
| f0ede74cf3 | |||
| 8afcd6259e | |||
| 84a8fd5e77 | |||
| d78f55b1db | |||
| 6c962b9fd3 | |||
| 14b6c355ca | |||
| 22617f9706 | |||
| 622237c36a | |||
| 014a5f9adc | |||
| 44cffa5fa8 | |||
| 19f0360930 | |||
| fd194eccd1 | |||
| 7f32242eff | |||
| 7e430f7278 | |||
| 04b98b3f9e | |||
| a2b0094a4d | |||
| 3464309856 | |||
| 3a12f318be | |||
| 6478abc372 | |||
| 91d9dfcd6f | |||
| 76997ececd | |||
| a96263310b | |||
| fbbf385657 | |||
| f5f46df077 |
@@ -0,0 +1,51 @@
|
||||
name: "Close Stale Issues"
|
||||
|
||||
# Controls when the action will run.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 */4 * * *"
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
permissions:
|
||||
issues: write
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
name: Stale issue job
|
||||
steps:
|
||||
- uses: aws-actions/stale-issue-cleanup@v5
|
||||
with:
|
||||
# Setting messages to an empty string will cause the automation to skip
|
||||
# that category
|
||||
ancient-issue-message: This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.
|
||||
stale-issue-message: This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.
|
||||
stale-pr-message: This PR has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.
|
||||
|
||||
# These labels are required
|
||||
stale-issue-label: closing-soon
|
||||
exempt-issue-labels: no-autoclose
|
||||
stale-pr-label: closing-soon
|
||||
exempt-pr-labels: no-autoclose
|
||||
response-requested-label: response-requested
|
||||
|
||||
# Don't set closed-for-staleness label to skip closing very old issues
|
||||
# regardless of label
|
||||
closed-for-staleness-label: closed-for-staleness
|
||||
|
||||
# Issue timing
|
||||
days-before-stale: 5
|
||||
days-before-close: 2
|
||||
days-before-ancient: 36500
|
||||
|
||||
# If you don't want to mark a issue as being ancient based on a
|
||||
# threshold of "upvotes", you can set this here. An "upvote" is
|
||||
# the total number of +1, heart, hooray, and rocket reactions
|
||||
# on an issue.
|
||||
minimum-upvotes-to-exempt: 5
|
||||
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
loglevel: DEBUG
|
||||
# Set dry-run to true to not perform label or close actions.
|
||||
dry-run: false
|
||||
@@ -13,7 +13,5 @@ jobs:
|
||||
# These inputs are both required
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
message: |
|
||||
** Note **
|
||||
Comments on closed issues are hard for our team to see.
|
||||
If you need more assistance, please either tag a team member or open a new issue that references this one.
|
||||
If you wish to keep having a conversation with other community members under this issue feel free to do so.
|
||||
|
||||
@@ -6,6 +6,7 @@ on:
|
||||
- main
|
||||
paths-ignore:
|
||||
- 'dist/**'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
package:
|
||||
@@ -27,10 +28,10 @@ jobs:
|
||||
npm test
|
||||
npm run package
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-west-2
|
||||
role-to-assume: ${{ secrets.SECRETS_AWS_ROLE_TO_ASSUME }}
|
||||
role-to-assume: ${{ secrets.SECRETS_AWS_PACKAGING_ROLE_TO_ASSUME }}
|
||||
role-duration-seconds: 900
|
||||
role-session-name: SecretsManagerFetch
|
||||
- name: Get bot user token
|
||||
@@ -38,7 +39,7 @@ jobs:
|
||||
with:
|
||||
parse-json-secrets: true
|
||||
secret-ids: |
|
||||
OSDS,arn:aws:secretsmanager:us-west-2:294535624312:secret:github-aws-sdk-osds-automation-ZHNalp
|
||||
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 }}"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Run tests
|
||||
name: Run Integ tests
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -12,7 +12,6 @@ jobs:
|
||||
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
|
||||
@@ -27,12 +26,37 @@ jobs:
|
||||
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]
|
||||
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
|
||||
@@ -48,12 +72,32 @@ jobs:
|
||||
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]
|
||||
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
|
||||
|
||||
@@ -9,7 +9,6 @@ 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
|
||||
@@ -19,7 +18,7 @@ jobs:
|
||||
- name: "Setup node"
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
node-version: 20
|
||||
- name: "Install dependencies"
|
||||
uses: bahmutov/npm-install@v1
|
||||
- name: "Run tests"
|
||||
@@ -34,7 +33,7 @@ jobs:
|
||||
- name: "Setup node"
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
- name: "Install dependencies"
|
||||
uses: bahmutov/npm-install@v1
|
||||
- name: "Lint code"
|
||||
|
||||
+12
-4
@@ -1,8 +1,12 @@
|
||||
queue_rules:
|
||||
- name: default
|
||||
conditions:
|
||||
# Conditions to get out of the queue (= merged)
|
||||
- status-success=Run Unit Tests
|
||||
# Conditions to merge a queued PR
|
||||
- check-success=Run unit tests (windows-latest)
|
||||
- check-success=Run unit tests (ubuntu-latest)
|
||||
- check-success=Run unit tests (macos-latest)
|
||||
- "#approved-reviews-by>=1"
|
||||
- -approved-reviews-by~=author
|
||||
|
||||
pull_request_rules:
|
||||
- name: Automatically merge on CI success and review approval
|
||||
@@ -10,7 +14,9 @@ pull_request_rules:
|
||||
- base~=main|integ-tests
|
||||
- "#approved-reviews-by>=1"
|
||||
- -approved-reviews-by~=author
|
||||
- status-success=Run Unit Tests
|
||||
- check-success=Run unit tests (windows-latest)
|
||||
- check-success=Run unit tests (ubuntu-latest)
|
||||
- check-success=Run unit tests (macos-latest)
|
||||
- label!=work-in-progress
|
||||
- -title~=(WIP|wip)
|
||||
- -merged
|
||||
@@ -25,7 +31,9 @@ pull_request_rules:
|
||||
conditions:
|
||||
- base~=main
|
||||
- author=dependabot[bot]
|
||||
- status-success=Run Unit Tests
|
||||
- check-success=Run unit tests (windows-latest)
|
||||
- check-success=Run unit tests (ubuntu-latest)
|
||||
- check-success=Run unit tests (macos-latest)
|
||||
- -title~=(WIP|wip)
|
||||
- -label~=(blocked|do-not-merge)
|
||||
- -merged
|
||||
|
||||
@@ -2,6 +2,34 @@
|
||||
|
||||
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.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
|
||||
* fixes #817 #819: validation logic throwing unwanted errors [d78f55b](https://github.com/aws-actions/configure-aws-credentials/commit/d78f55b1db65186cb251a8504ae9527af06fc5fd)
|
||||
|
||||
## [3.0.1](https://github.com/aws-actions/configure-aws-credentials/compare/v3.0.0...v3.0.1) (2023-08-24)
|
||||
|
||||
### Features
|
||||
* Can configure `special-characters-workaround` to keep retrying credentials if the returned
|
||||
credentials have special characters (Fixes #599)
|
||||
|
||||
### Bug Fixes
|
||||
* Fixes #792: Action fails when intending to use existing credentials
|
||||
* Minor typo fix from @ubaid-ansari21
|
||||
|
||||
### Changes to existing functionality
|
||||
* Special characters are now allowed in returned credential variables unless you configure the
|
||||
`special-characters-workaround` option
|
||||
|
||||
## [3.0.0](https://github.com/aws-actions/configure-aws-credentials/compare/v2.2.0...v3.0.0) (2023-08-21)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -7,7 +7,23 @@ calls.
|
||||
|
||||
---
|
||||
|
||||
### News
|
||||
### Recent News
|
||||
|
||||
#### Long-term credentials warning (10/3/23)
|
||||
|
||||
We have added a warning when using long-term credentials to access AWS
|
||||
(IAM access keys and secret keys). Using long-term credentials requires you
|
||||
to create IAM users and properly secure the access keys to prevent their disclosure.
|
||||
A better approach is to use [GitHub's support for OpenID Connect](#OIDC) to authenticate
|
||||
using an IAM role to generate temporary security credentials.
|
||||
|
||||
#### v4 Announcement (9/11/23)
|
||||
|
||||
We have just released `v4` of Configure AWS Credentials. The only thing that
|
||||
changed from `v3` is that the action now runs on `node20` instead of `node16`.
|
||||
You can still see the `v3` announcement below, as it is still recent.
|
||||
|
||||
#### v3 Announcement (8/23/23)
|
||||
|
||||
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
|
||||
@@ -24,9 +40,9 @@ changes should be backwards compatible with your existing workflows.
|
||||
_all_ use cases. This is changed from 6 hours in `v2`. You can adjust this value
|
||||
with the `role-duration-seconds` input.
|
||||
- By default, your account ID will not be masked in workflow logs. This was
|
||||
changed from being masked by default in the previous version. AWS does consider
|
||||
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 rever to the old default and mask your account ID in workflow logs by
|
||||
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**
|
||||
@@ -46,7 +62,7 @@ variables are interfering with the action. You can enable this by setting the
|
||||
**Bug fixes**
|
||||
|
||||
You can find a list of bugs that have been fixed in v3 in the
|
||||
[changelog](./changelog.md).
|
||||
[changelog](./CHANGELOG.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -82,7 +98,7 @@ To do that, you would add the following step to your workflow:
|
||||
|
||||
```yaml
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||
aws-region: us-east-2
|
||||
@@ -111,7 +127,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Configure AWS credentials from Test account
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::111111111111:role/my-github-actions-role-test
|
||||
aws-region: us-east-1
|
||||
@@ -119,7 +135,7 @@ jobs:
|
||||
run: |
|
||||
aws s3 sync . s3://my-s3-test-website-bucket
|
||||
- name: Configure AWS credentials from Production account
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::222222222222:role/my-github-actions-role-prod
|
||||
aws-region: us-west-2
|
||||
@@ -161,13 +177,15 @@ We recommend using [GitHub's OIDC provider](https://docs.github.com/en/actions/d
|
||||
|
||||
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` |
|
||||
| --------------------------------------------------------------- | ------------------- | ---------------- | ------------------------- | - |
|
||||
| [✅ 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 | | ✔ | | ✔ |
|
||||
| **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**.
|
||||
@@ -207,7 +225,7 @@ within the Action. See [issue 419](https://github.com/aws-actions/configure-aws-
|
||||
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
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
role-skip-session-tagging: true
|
||||
```
|
||||
@@ -218,13 +236,13 @@ You can skip this session tagging by providing
|
||||
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@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
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@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
inline-session-policy: >-
|
||||
{
|
||||
@@ -244,13 +262,13 @@ Or we can have a nicely formatted JSON as well:
|
||||
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@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
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@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
managed-session-policies: |
|
||||
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
|
||||
@@ -268,6 +286,15 @@ Your account ID is not masked by default in workflow logs since it's not conside
|
||||
#### 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
|
||||
|
||||
#### 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.
|
||||
|
||||
## 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:
|
||||
@@ -280,11 +307,11 @@ We recommend using [GitHub's OIDC provider](https://docs.github.com/en/actions/d
|
||||
|
||||
### Audience
|
||||
|
||||
When the JWT is created, an audience needs to be specified. By default, the audience is `sts.amazon.com` and this will work for most cases. Changing the default audience may be necessary when using non-default AWS partitions. You can specify the audience through the `audience` input:
|
||||
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@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
audience: sts.amazonaws.com.cn
|
||||
aws-region: us-east-3
|
||||
@@ -396,7 +423,7 @@ 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
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
```
|
||||
@@ -406,7 +433,7 @@ 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
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: my-github-actions-role
|
||||
@@ -429,7 +456,7 @@ environment.
|
||||
|
||||
Manually configured proxy:
|
||||
```yaml
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: my-github-actions-role
|
||||
@@ -459,7 +486,7 @@ should include the AWS CLI by default.
|
||||
### AssumeRoleWithWebIdentity (recommended)
|
||||
```yaml
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||
@@ -470,13 +497,13 @@ In this example, the Action will load the OIDC token from the GitHub-provided en
|
||||
### AssumeRole with role previously assumed by action in same workflow
|
||||
```yaml
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||
role-session-name: MySessionName
|
||||
- name: Configure other AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: arn:aws:iam::987654321000:role/my-second-role
|
||||
@@ -488,7 +515,7 @@ In this two-step example, the first step will use OIDC to assume the role `arn:a
|
||||
### AssumeRole with static IAM credentials in repository secrets
|
||||
```yaml
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
@@ -504,7 +531,7 @@ In this example, the secret `AWS_ROLE_TO_ASSUME` contains a string like `arn:aws
|
||||
```yaml
|
||||
- name: Configure AWS Credentials 1
|
||||
id: creds
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
role-to-assume: arn:aws:iam::123456789100:role/my-github-actions-role
|
||||
@@ -513,7 +540,7 @@ In this example, the secret `AWS_ROLE_TO_ASSUME` contains a string like `arn:aws
|
||||
run: |
|
||||
aws sts get-caller-identity
|
||||
- name: Configure AWS Credentials 2
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-2
|
||||
aws-access-key-id: ${{ steps.creds.outputs.aws-access-key-id }}
|
||||
|
||||
+1
-1
@@ -3307,7 +3307,7 @@ Apache-2.0
|
||||
limitations under the License.
|
||||
|
||||
|
||||
@aws-sdk/node-http-handler
|
||||
@aws-sdk/region-config-resolver
|
||||
Apache-2.0
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
|
||||
+4
-1
@@ -2,7 +2,7 @@
|
||||
name: '"Configure AWS Credentials" Action for GitHub Actions'
|
||||
description: Configures AWS credentials for use in subsequent steps in a GitHub Action workflow
|
||||
runs:
|
||||
using: node16
|
||||
using: node20
|
||||
main: dist/index.js
|
||||
post: dist/cleanup/index.js
|
||||
branding:
|
||||
@@ -70,6 +70,9 @@ inputs:
|
||||
retry-max-attempts:
|
||||
description: The maximum number of attempts it will attempt to retry the assume role call. By default it will retry 12 times
|
||||
required: false
|
||||
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
|
||||
outputs:
|
||||
aws-account-id:
|
||||
description: The AWS account ID for the provided credentials
|
||||
|
||||
+1991
-1396
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -9,7 +9,7 @@ export declare function defaultSleep(ms: number): Promise<unknown>;
|
||||
declare let sleep: typeof defaultSleep;
|
||||
export declare function withsleep(s: typeof sleep): void;
|
||||
export declare function reset(): void;
|
||||
export declare function verifyKeys(creds: Partial<Credentials> | undefined): void;
|
||||
export declare function 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;
|
||||
|
||||
+643
-1492
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-region: us-east-1
|
||||
## the following creates an ARN based on the values entered into github secrets
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# federated-setup
|
||||
|
||||
## [github-action-oidc-federation](./github-actions-odic-federation.yml)
|
||||
## [github-action-oidc-federation](./github-actions-oidc-federation.yml)
|
||||
|
||||
Setup of the OIDC federation between your GitHub Organization/repository and your AWS account.
|
||||
|
||||
|
||||
Generated
+2249
-1966
File diff suppressed because it is too large
Load Diff
+19
-19
@@ -14,34 +14,34 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aws-sdk/credential-provider-env": "^3.186.0",
|
||||
"@aws-sdk/property-provider": "^3.188.0",
|
||||
"@jest/globals": "^29.1.2",
|
||||
"@types/jest": "^29.1.2",
|
||||
"@types/node": "^14",
|
||||
"@typescript-eslint/eslint-plugin": "^5",
|
||||
"@typescript-eslint/parser": "^5",
|
||||
"@vercel/ncc": "^0.34.0",
|
||||
"aws-sdk-client-mock": "^2.0.0",
|
||||
"@smithy/property-provider": "^2.0.11",
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@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.0.0",
|
||||
"del-cli": "^5.1.0",
|
||||
"eslint": "^8",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-import-resolver-node": "^0.3.6",
|
||||
"eslint-import-resolver-typescript": "^3.5.1",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"jest": "^29.1.2",
|
||||
"jest-junit": "^13",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.28.1",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-junit": "^16",
|
||||
"json-schema": "^0.4.0",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier": "^3.0.3",
|
||||
"standard-version": "^9",
|
||||
"ts-jest": "^29.0.3",
|
||||
"typescript": "^4.8.4"
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@actions/core": "^1.10.1",
|
||||
"@aws-sdk/client-sts": "^3",
|
||||
"@aws-sdk/node-http-handler": "^3",
|
||||
"@smithy/node-http-handler": "^2.1.6",
|
||||
"https-proxy-agent": "^5.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { info } from '@actions/core';
|
||||
import { STSClient } from '@aws-sdk/client-sts';
|
||||
import { NodeHttpHandler } from '@aws-sdk/node-http-handler';
|
||||
import { NodeHttpHandler } from '@smithy/node-http-handler';
|
||||
import { HttpsProxyAgent } from 'https-proxy-agent';
|
||||
import { errorMessage } from './helpers';
|
||||
|
||||
|
||||
+7
-4
@@ -5,7 +5,7 @@ import * as core from '@actions/core';
|
||||
import type { AssumeRoleCommandInput, STSClient, Tag } from '@aws-sdk/client-sts';
|
||||
import { AssumeRoleCommand, AssumeRoleWithWebIdentityCommand } from '@aws-sdk/client-sts';
|
||||
import type { CredentialsClient } from './CredentialsClient';
|
||||
import { errorMessage, isDefined, sanitizeGitHubVariables, verifyKeys } from './helpers';
|
||||
import { errorMessage, isDefined, sanitizeGitHubVariables } from './helpers';
|
||||
|
||||
async function assumeRoleWithOIDC(params: AssumeRoleCommandInput, client: STSClient, webIdentityToken: string) {
|
||||
delete params.Tags;
|
||||
@@ -17,7 +17,6 @@ async function assumeRoleWithOIDC(params: AssumeRoleCommandInput, client: STSCli
|
||||
WebIdentityToken: webIdentityToken,
|
||||
})
|
||||
);
|
||||
verifyKeys(creds.Credentials);
|
||||
return creds;
|
||||
} catch (error) {
|
||||
throw new Error(`Could not assume role with OIDC: ${errorMessage(error)}`);
|
||||
@@ -49,7 +48,6 @@ async function assumeRoleWithWebIdentityTokenFile(
|
||||
WebIdentityToken: webIdentityToken,
|
||||
})
|
||||
);
|
||||
verifyKeys(creds.Credentials);
|
||||
return creds;
|
||||
} catch (error) {
|
||||
throw new Error(`Could not assume role with web identity token file: ${errorMessage(error)}`);
|
||||
@@ -58,9 +56,14 @@ async function assumeRoleWithWebIdentityTokenFile(
|
||||
|
||||
async function assumeRoleWithCredentials(params: AssumeRoleCommandInput, client: STSClient) {
|
||||
core.info('Assuming role with user credentials');
|
||||
if (!process.env['AWS_SESSION_TOKEN']) {
|
||||
core.warning(
|
||||
'To avoid using long-term AWS credentials, please update your workflows to authenticate using OpenID Connect.' +
|
||||
' See https://s12d.com/gha-oidc-aws for more information.'
|
||||
);
|
||||
}
|
||||
try {
|
||||
const creds = await client.send(new AssumeRoleCommand({ ...params }));
|
||||
verifyKeys(creds.Credentials);
|
||||
return creds;
|
||||
} catch (error) {
|
||||
throw new Error(`Could not assume role with user credentials: ${errorMessage(error)}`);
|
||||
|
||||
+6
-3
@@ -93,18 +93,21 @@ export function reset() {
|
||||
|
||||
export function verifyKeys(creds: Partial<Credentials> | undefined) {
|
||||
if (!creds) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (creds.AccessKeyId) {
|
||||
if (SPECIAL_CHARS_REGEX.test(creds.AccessKeyId)) {
|
||||
throw new Error('AccessKeyId contains special characters.');
|
||||
core.debug('AccessKeyId contains special characters.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (creds.SecretAccessKey) {
|
||||
if (SPECIAL_CHARS_REGEX.test(creds.SecretAccessKey)) {
|
||||
throw new Error('SecretAccessKey contains special characters.');
|
||||
core.debug('SecretAccessKey contains special characters.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Retries the promise with exponential backoff if the error isRetryable up to maxRetries time.
|
||||
|
||||
+45
-24
@@ -1,4 +1,5 @@
|
||||
import * as core from '@actions/core';
|
||||
import type { AssumeRoleCommandOutput } from '@aws-sdk/client-sts';
|
||||
import { assumeRole } from './assumeRole';
|
||||
import { CredentialsClient } from './CredentialsClient';
|
||||
import {
|
||||
@@ -8,6 +9,7 @@ import {
|
||||
exportCredentials,
|
||||
exportAccountId,
|
||||
unsetCredentials,
|
||||
verifyKeys,
|
||||
} from './helpers';
|
||||
|
||||
const DEFAULT_ROLE_DURATION = 3600; // One hour (seconds)
|
||||
@@ -43,10 +45,20 @@ export async function run() {
|
||||
const unsetCurrentCredentialsInput = core.getInput('unset-current-credentials', { required: false }) || 'false';
|
||||
const unsetCurrentCredentials = unsetCurrentCredentialsInput.toLowerCase() === 'true';
|
||||
const disableRetryInput = core.getInput('disable-retry', { required: false }) || 'false';
|
||||
const disableRetry = disableRetryInput.toLowerCase() === 'true';
|
||||
let disableRetry = disableRetryInput.toLowerCase() === 'true';
|
||||
const specialCharacterWorkaroundInput =
|
||||
core.getInput('special-characters-workaround', { required: false }) || 'false';
|
||||
const specialCharacterWorkaround = specialCharacterWorkaroundInput.toLowerCase() === 'true';
|
||||
let maxRetries = parseInt(core.getInput('retry-max-attempts', { required: false })) || 12;
|
||||
if (maxRetries < 1) {
|
||||
maxRetries = 1;
|
||||
switch (true) {
|
||||
case specialCharacterWorkaround:
|
||||
// 😳
|
||||
disableRetry = false;
|
||||
maxRetries = 12;
|
||||
break;
|
||||
case maxRetries < 1:
|
||||
maxRetries = 1;
|
||||
break;
|
||||
}
|
||||
for (const managedSessionPolicy of managedSessionPoliciesInput) {
|
||||
managedSessionPolicies.push({ arn: managedSessionPolicy });
|
||||
@@ -66,7 +78,8 @@ export async function run() {
|
||||
!roleChaining
|
||||
) {
|
||||
core.info(
|
||||
'It looks like you might be trying to authenticate with OIDC. Did you mean to set the `id-token` permission?'
|
||||
'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.'
|
||||
);
|
||||
}
|
||||
return (
|
||||
@@ -116,7 +129,9 @@ export async function run() {
|
||||
// in any error messages.
|
||||
exportCredentials({ AccessKeyId, SecretAccessKey, SessionToken });
|
||||
} else if (!webIdentityTokenFile && !roleChaining) {
|
||||
throw new Error('Could not determine how to assume credentials. Please check your inputs and try again.');
|
||||
// Proceed only if credentials can be picked up
|
||||
await credentialsClient.validateCredentials();
|
||||
sourceAccountId = await exportAccountId(credentialsClient, maskAccountId);
|
||||
}
|
||||
|
||||
if (AccessKeyId || roleChaining) {
|
||||
@@ -129,25 +144,30 @@ export async function run() {
|
||||
|
||||
// Get role credentials if configured to do so
|
||||
if (roleToAssume) {
|
||||
const roleCredentials = await retryAndBackoff(
|
||||
async () => {
|
||||
return assumeRole({
|
||||
credentialsClient,
|
||||
sourceAccountId,
|
||||
roleToAssume,
|
||||
roleExternalId,
|
||||
roleDuration,
|
||||
roleSessionName,
|
||||
roleSkipSessionTagging,
|
||||
webIdentityTokenFile,
|
||||
webIdentityToken,
|
||||
inlineSessionPolicy,
|
||||
managedSessionPolicies,
|
||||
});
|
||||
},
|
||||
!disableRetry,
|
||||
maxRetries
|
||||
);
|
||||
let roleCredentials: AssumeRoleCommandOutput;
|
||||
do {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
roleCredentials = await retryAndBackoff(
|
||||
async () => {
|
||||
return assumeRole({
|
||||
credentialsClient,
|
||||
sourceAccountId,
|
||||
roleToAssume,
|
||||
roleExternalId,
|
||||
roleDuration,
|
||||
roleSessionName,
|
||||
roleSkipSessionTagging,
|
||||
webIdentityTokenFile,
|
||||
webIdentityToken,
|
||||
inlineSessionPolicy,
|
||||
managedSessionPolicies,
|
||||
});
|
||||
},
|
||||
!disableRetry,
|
||||
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);
|
||||
// We need to validate the credentials in 2 of our use-cases
|
||||
@@ -173,6 +193,7 @@ export async function run() {
|
||||
}
|
||||
|
||||
/* c8 ignore start */
|
||||
/* istanbul ignore next */
|
||||
if (require.main === module) {
|
||||
(async () => {
|
||||
await run();
|
||||
|
||||
+96
-50
@@ -6,7 +6,7 @@ import {
|
||||
STSClient,
|
||||
} from '@aws-sdk/client-sts';
|
||||
import { fromEnv } from '@aws-sdk/credential-provider-env';
|
||||
import { CredentialsProviderError } from '@aws-sdk/property-provider';
|
||||
import { CredentialsProviderError } from '@smithy/property-provider';
|
||||
import { mockClient } from 'aws-sdk-client-mock';
|
||||
import { withsleep, reset } from '../src/helpers';
|
||||
import { run } from '../src/index';
|
||||
@@ -105,6 +105,9 @@ describe('Configure AWS Credentials', () => {
|
||||
jest.spyOn(core, 'info').mockImplementation((string) => {
|
||||
return string;
|
||||
});
|
||||
jest.spyOn(core, 'warning').mockImplementation((string) => {
|
||||
return string;
|
||||
});
|
||||
(fromEnv as jest.Mock)
|
||||
.mockImplementationOnce(() => () => ({
|
||||
accessKeyId: FAKE_ACCESS_KEY_ID,
|
||||
@@ -202,7 +205,7 @@ describe('Configure AWS Credentials', () => {
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Could not determine how to assume credentials. Please check your inputs and try again.'
|
||||
'Credentials could not be loaded, please check your action inputs: Could not load credentials from any providers'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -217,7 +220,7 @@ describe('Configure AWS Credentials', () => {
|
||||
await run();
|
||||
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Could not determine how to assume credentials. Please check your inputs and try again.'
|
||||
'Credentials could not be loaded, please check your action inputs: Access key ID empty after loading credentials'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -508,6 +511,8 @@ describe('Configure AWS Credentials', () => {
|
||||
});
|
||||
|
||||
test('GH OIDC check fails if token is not set', async () => {
|
||||
(fromEnv as jest.Mock).mockReset();
|
||||
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = undefined;
|
||||
process.env['GITHUB_ACTIONS'] = 'true';
|
||||
jest.spyOn(core, 'getInput').mockImplementation(
|
||||
mockGetInput({
|
||||
@@ -519,13 +524,34 @@ describe('Configure AWS Credentials', () => {
|
||||
await run();
|
||||
|
||||
expect(core.info).toHaveBeenCalledWith(
|
||||
'It looks like you might be trying to authenticate with OIDC. Did you mean to set the `id-token` permission?'
|
||||
'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.'
|
||||
);
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Could not determine how to assume credentials. Please check your inputs and try again.'
|
||||
'Credentials could not be loaded, please check your action inputs: provider is not a function'
|
||||
);
|
||||
});
|
||||
|
||||
test('Assume role with existing credentials if nothing else set', async () => {
|
||||
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = undefined;
|
||||
process.env['AWS_ACCESS_KEY_ID'] = FAKE_ACCESS_KEY_ID;
|
||||
process.env['AWS_SECRET_ACCESS_KEY'] = FAKE_SECRET_ACCESS_KEY;
|
||||
jest.spyOn(core, 'getInput').mockImplementation(
|
||||
mockGetInput({
|
||||
'role-to-assume': ROLE_ARN,
|
||||
'aws-region': FAKE_REGION,
|
||||
})
|
||||
);
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.info).toHaveBeenCalledWith(
|
||||
'It looks like you might be trying to authenticate with OIDC. Did you mean to set the `id-token` permission?' +
|
||||
' If you are not trying to authenticate with OIDC and the action is working successfully, you can ignore this message.'
|
||||
);
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(1);
|
||||
});
|
||||
|
||||
test('role assumption fails after maximum trials using OIDC provider', async () => {
|
||||
process.env['GITHUB_ACTIONS'] = 'true';
|
||||
process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN'] = 'test-token';
|
||||
@@ -556,61 +582,62 @@ describe('Configure AWS Credentials', () => {
|
||||
expect(mockedSTS.commandCalls(AssumeRoleWithWebIdentityCommand).length).toEqual(1);
|
||||
});
|
||||
|
||||
test('role assumption fails if access key id contains special characters', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||
test('special character workaround works for AWS_ACCESS_KEY_ID', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'special-characters-workaround': 'true' }));
|
||||
|
||||
mockedSTS.on(AssumeRoleCommand).resolves({
|
||||
Credentials: {
|
||||
AccessKeyId: 'asdf+',
|
||||
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
});
|
||||
mockedSTS
|
||||
.on(AssumeRoleCommand)
|
||||
.resolvesOnce({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: 'asdf+',
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
})
|
||||
.resolves({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: 'asdf',
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(12);
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Could not assume role with user credentials: AccessKeyId contains special characters.'
|
||||
);
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(2);
|
||||
});
|
||||
|
||||
test('role assumption fails if secret access key contains special characters', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||
test('special character workaround works for AWS_SECRET_ACCESS_KEY', async () => {
|
||||
jest
|
||||
.spyOn(core, 'getInput')
|
||||
.mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS, 'special-characters-workaround': 'true' }));
|
||||
|
||||
mockedSTS.on(AssumeRoleCommand).resolves({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: 'asdf+',
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
});
|
||||
mockedSTS
|
||||
.on(AssumeRoleCommand)
|
||||
.resolvesOnce({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: 'asdf+',
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
})
|
||||
.resolves({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: 'asdf',
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(12);
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
'Could not assume role with user credentials: SecretAccessKey contains special characters.'
|
||||
);
|
||||
});
|
||||
|
||||
test('role assumption succeeds if keys have no special characters', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput({ ...ASSUME_ROLE_INPUTS }));
|
||||
|
||||
mockedSTS.on(AssumeRoleCommand).resolves({
|
||||
Credentials: {
|
||||
AccessKeyId: FAKE_STS_ACCESS_KEY_ID,
|
||||
SecretAccessKey: FAKE_STS_SECRET_ACCESS_KEY,
|
||||
SessionToken: FAKE_STS_SESSION_TOKEN,
|
||||
Expiration: new Date(8640000000000000),
|
||||
},
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(1);
|
||||
expect(mockedSTS.commandCalls(AssumeRoleCommand).length).toEqual(2);
|
||||
});
|
||||
|
||||
test('max retries is configurable', async () => {
|
||||
@@ -844,4 +871,23 @@ describe('Configure AWS Credentials', () => {
|
||||
|
||||
expect(core.setOutput).toHaveBeenCalledTimes(4);
|
||||
});
|
||||
|
||||
test('prints warning for access key usage and no session token', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(ASSUME_ROLE_INPUTS));
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.warning).toHaveBeenCalledWith(
|
||||
'To avoid using long-term AWS credentials, please update your workflows to authenticate using OpenID Connect.' +
|
||||
' See https://s12d.com/gha-oidc-aws for more information.'
|
||||
);
|
||||
});
|
||||
|
||||
test('skips warning for access key usage with session token', async () => {
|
||||
jest.spyOn(core, 'getInput').mockImplementation(mockGetInput(DEFAULT_INPUTS));
|
||||
|
||||
await run();
|
||||
|
||||
expect(core.warning).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user