mirror of
https://github.com/aws-actions/configure-aws-credentials.git
synced 2026-08-24 04:25:05 +09:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ececac1a45 | |||
| 16fec6080f | |||
| eb70354fb4 | |||
| 3478c15aa1 | |||
| a69d38c39d | |||
| 6b1d0f829d | |||
| f021516513 | |||
| 1c8dbbcc02 | |||
| ce290d67fe | |||
| 1780ebd97b | |||
| a02ef26683 | |||
| 5fbd2e409b | |||
| f0af89b102 | |||
| b9ee51dc60 | |||
| 66c00faf39 | |||
| 134d71efe0 | |||
| b8ef615781 | |||
| e5b9735585 | |||
| 79ebbb3141 | |||
| 7f029f3507 | |||
| 39fd91c08e | |||
| cf624fbdad |
@@ -9,10 +9,7 @@ jobs:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
if: >-
|
||||
github.event.review.state == 'approved' &&
|
||||
github.event.repository == 'aws/configure-aws-credentials' &&
|
||||
(github.event.review.author_association == 'OWNER' || github.event.review.user.login == 'aws-sdk-osds')
|
||||
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
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
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
|
||||
@@ -2,10 +2,11 @@ name: Dependabot auto-approve
|
||||
on: pull_request
|
||||
permissions:
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
jobs:
|
||||
dependabot:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'aws/configure-aws-credentials'
|
||||
if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'aws-actions/configure-aws-credentials' }}
|
||||
steps:
|
||||
- name: Get Metadata
|
||||
id: dependabot-metadata
|
||||
@@ -18,7 +19,6 @@ jobs:
|
||||
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:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
".release-please-manifest.json": "4.0.2",
|
||||
"package.json": "4.0.2",
|
||||
".": "4.0.3"
|
||||
".": "4.1.0"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,21 @@
|
||||
|
||||
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.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)
|
||||
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ See [action.yml](./action.yml) for more detail.
|
||||
| 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 |
|
||||
|
||||
#### Credential Lifetime
|
||||
The default session duration is **1 hour**.
|
||||
|
||||
@@ -73,6 +73,8 @@ 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
|
||||
|
||||
+14
@@ -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;
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
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?: {
|
||||
arn: string;
|
||||
}[];
|
||||
}
|
||||
export declare function assumeRole(params: assumeRoleParams): Promise<import("@aws-sdk/client-sts").AssumeRoleCommandOutput>;
|
||||
+11
@@ -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;
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
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 declare function areCredentialsValid(credentialsClient: CredentialsClient): Promise<boolean>;
|
||||
export {};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare function run(): Promise<void>;
|
||||
+4313
-6110
File diff suppressed because it is too large
Load Diff
+3679
-6772
File diff suppressed because it is too large
Load Diff
Generated
+804
-981
File diff suppressed because it is too large
Load Diff
+10
-10
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "configure-aws-credentials",
|
||||
"description": "A GitHub Action to configure AWS credentials",
|
||||
"version": "4.0.3",
|
||||
"version": "4.1.0",
|
||||
"scripts": {
|
||||
"build": "tsc --project tsconfig.build.json",
|
||||
"build": "tsc",
|
||||
"lint": "biome check --error-on-warnings ./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"
|
||||
@@ -16,22 +16,22 @@
|
||||
"devDependencies": {
|
||||
"@aws-sdk/credential-provider-env": "^3.515.0",
|
||||
"@biomejs/biome": "1.9.4",
|
||||
"@smithy/property-provider": "^3.1.7",
|
||||
"@types/node": "^22.9.0",
|
||||
"@vercel/ncc": "^0.38.2",
|
||||
"@vitest/coverage-v8": "^2.1.3",
|
||||
"@smithy/property-provider": "^4.0.1",
|
||||
"@types/node": "^22.13.1",
|
||||
"@vercel/ncc": "^0.38.3",
|
||||
"@vitest/coverage-v8": "^2.1.9",
|
||||
"aws-sdk-client-mock": "^4.1.0",
|
||||
"cpy-cli": "^5.0.0",
|
||||
"del-cli": "^6.0.0",
|
||||
"json-schema": "^0.4.0",
|
||||
"memfs": "^4.14.0",
|
||||
"memfs": "^4.17.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"typescript": "^5.6.3",
|
||||
"vitest": "^2.1.3"
|
||||
"typescript": "^5.7.3",
|
||||
"vitest": "^2.1.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.11.1",
|
||||
"@aws-sdk/client-sts": "^3.675.0",
|
||||
"@aws-sdk/client-sts": "^3.741.0",
|
||||
"@smithy/node-http-handler": "^4.0.1",
|
||||
"https-proxy-agent": "^5.0.1"
|
||||
},
|
||||
|
||||
@@ -144,3 +144,16 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { AssumeRoleCommandOutput } from '@aws-sdk/client-sts';
|
||||
import { CredentialsClient } from './CredentialsClient';
|
||||
import { assumeRole } from './assumeRole';
|
||||
import {
|
||||
areCredentialsValid,
|
||||
errorMessage,
|
||||
exportAccountId,
|
||||
exportCredentials,
|
||||
@@ -60,6 +61,8 @@ 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;
|
||||
switch (true) {
|
||||
case specialCharacterWorkaround:
|
||||
@@ -116,6 +119,16 @@ export async function run() {
|
||||
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()) {
|
||||
|
||||
@@ -27,6 +27,7 @@ describe('Configure AWS Credentials', {}, () => {
|
||||
vi.spyOn(core, 'setOutput').mockImplementation((_n, _v) => {});
|
||||
vi.spyOn(core, 'debug').mockImplementation((_m) => {});
|
||||
vi.spyOn(core, 'info').mockImplementation((_m) => {});
|
||||
vi.spyOn(core, 'notice').mockImplementation((_m) => {});
|
||||
// Remove any existing environment variables before each test to prevent the
|
||||
// SDK from picking them up
|
||||
process.env = { ...mocks.envs };
|
||||
@@ -299,5 +300,17 @@ describe('Configure AWS Credentials', {}, () => {
|
||||
await run();
|
||||
expect(core.setFailed).toHaveBeenCalled();
|
||||
});
|
||||
it('gets new creds if told to reuse existing but they\'re invalid', {}, async () => {
|
||||
vi.spyOn(core, 'getInput').mockImplementation(mocks.getInput(mocks.USE_EXISTING_CREDENTIALS_INPUTS));
|
||||
mockedSTSClient.on(GetCallerIdentityCommand).rejects();
|
||||
await run();
|
||||
expect(core.notice).toHaveBeenCalledWith('No valid credentials exist. Running as normal.')
|
||||
});
|
||||
it('doesn\'t get new creds if there are already valid ones and we said use them', {}, async () => {
|
||||
vi.spyOn(core, 'getInput').mockImplementation(mocks.getInput(mocks.USE_EXISTING_CREDENTIALS_INPUTS));
|
||||
mockedSTSClient.on(GetCallerIdentityCommand).resolves(mocks.outputs.GET_CALLER_IDENTITY);
|
||||
await run();
|
||||
expect(core.setFailed).not.toHaveBeenCalled();
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,6 +27,11 @@ const inputs = {
|
||||
'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',
|
||||
}
|
||||
};
|
||||
|
||||
const envs = {
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": [
|
||||
"test/**/*.ts"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"rootDir": "src"
|
||||
},
|
||||
}
|
||||
+6
-4
@@ -22,12 +22,14 @@
|
||||
"lib": [ "ES2020" ],
|
||||
"target": "ES2020",
|
||||
"noErrorTruncation": true,
|
||||
"esModuleInterop": true
|
||||
"esModuleInterop": true,
|
||||
"rootDir": "src",
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"test/**/*.test.ts"
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"test/**/*.ts"
|
||||
],
|
||||
"exclude": [],
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": [
|
||||
"test/**/*.ts",
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"exclude": [],
|
||||
"compilerOptions": {
|
||||
"rootDir": "./"
|
||||
},
|
||||
}
|
||||
@@ -5,5 +5,6 @@ export default defineConfig({
|
||||
passWithNoTests: true,
|
||||
include: ['test/**/*.test.ts'],
|
||||
coverage: { enabled: true },
|
||||
typecheck: { tsconfig: './tsconfig.test.json' },
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user