* chore(deps-dev): bump vitest from 3.2.4 to 4.1.5 (#1748) * chore(deps-dev): bump vitest from 3.2.4 to 4.1.5 Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 3.2.4 to 4.1.5. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.5/packages/vitest) --- updated-dependencies: - dependency-name: vitest dependency-version: 4.1.5 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore(deps-dev): update @vitest/coverage-v8 Bump @vitest/coverage-v8 to ^4.1.5 to match peer dependency, and move vi.mock('node:fs') calls to the top level of test files to reflect actual hoisting semantics required by vitest 4.x. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tom Keller <kellertk@amazon.com> (cherry picked from commit78f374f6d1) * chore(deps): bump @actions/core from 2.0.3 to 3.0.1 (#1746) * chore(deps): bump @actions/core from 2.0.3 to 3.0.1 Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 2.0.3 to 3.0.1. - [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md) - [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core) --- updated-dependencies: - dependency-name: "@actions/core" dependency-version: 3.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * chore: update test mocks for @actions/core ESM @actions/core v3 ships as an ESM module with non-configurable exports, breaking vi.spyOn(). Switch to vi.mock('@actions/core') which intercepts at the module loader level. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Tom Keller <kellertk@amazon.com> (cherry picked from commit64d8e82527) * chore(deps): bump @aws-sdk/client-sts from 3.1043.0 to 3.1044.0 (#1754) Bumps [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) from 3.1043.0 to 3.1044.0. - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1044.0/clients/client-sts) --- updated-dependencies: - dependency-name: "@aws-sdk/client-sts" dependency-version: 3.1042.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit4cfda40a13) * chore: bump unit test node version (#1758) (cherry picked from commit39d1702721) * chore: automatic major version tagging (#1565) * Update release-please.yml to auto-update version tag * chore: configure release-please auto floating tag --------- Co-authored-by: Tom Keller <kellertk@amazon.com> (cherry picked from commitc36525a567) * feat: Allow custom session tags to be passed when assuming a role (#1759) * Add possibility to input custom session tags * Use json for input to custom-tags, add documentation for custom-tags * Add more examples * Simplify example to avoid parse error * Add input validation for custom tags * Fix unit tests for custom-tags * Add debugging message * Skip failing test for now * Build package * Remove some unused validation for custom tags * feat: add validation for custom session tags Harden the custom-tags feature against misuse and misconfiguration: - Validate input is a JSON object (reject arrays, primitives, null) - Enforce STS tag constraints: key length (128), value length (256), allowed characters - Reject nested object/array values that would silently stringify to '[object Object]' - Block overriding default session tags (GitHub, Repository, Workflow, etc.) - Enforce 50-tag session limit - Warn when custom-tags used with OIDC or web identity - Fix missing await on helpers test assertion - Remove unused CUSTOM_TAGS_JSON_INPUTS fixture - Normalize test mocking to vi.mocked() pattern --------- Co-authored-by: Sylvain Verly <sylvain.verly@gmail.com> (cherry picked from commit61f50f630f) * chore: configure codeql to ignore generated code (#1760) (cherry picked from commitdc2353e57a) * feat: support custom STS endpoints (#1762) Closes #1067. This is a advanced option and is not needed for most deployments. (cherry picked from commit8d52d05d7a) * chore: automate README version bumping (#1763) Closes #1420. (cherry picked from commit07ada0fe07) * feat: add more retry logic and better logging (#1764) Wraps exportAccountId and validateCredentials calls in retryAndBackoff. Closes #1681. Adds a label parameter to retryAndBackoff for better info-level log messages. (cherry picked from commit540d0c13ae) * feat: add regex validation to role-session-name (#1765) Previously invalid role session names would get errors from the STS API instead of this action rejecting them, causing unnecessary retries. Now we check them and fail early. Closes #1656. That FR recommended that we sanitize the name before sending to STS, but instead we error to not silently change the user's selected session name (avoiding the potential security sharp edge) (cherry picked from commite35449909c) * chore: update documentation for environment workflows (#1766) Closes #1238. (cherry picked from commit3f7e1b63d7) * chore(deps): bump @aws-sdk/client-sts from 3.1044.0 to 3.1045.0 (#1767) Bumps [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) from 3.1044.0 to 3.1045.0. - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1045.0/clients/client-sts) --- updated-dependencies: - dependency-name: "@aws-sdk/client-sts" dependency-version: 3.1045.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commita388f23f7d) * chore(deps-dev): bump @vitest/coverage-v8 from 4.1.5 to 4.1.6 (#1768) Bumps [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) from 4.1.5 to 4.1.6. - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.6/packages/coverage-v8) --- updated-dependencies: - dependency-name: "@vitest/coverage-v8" dependency-version: 4.1.6 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit1fb495c4b2) * chore(deps-dev): bump @smithy/property-provider from 4.2.14 to 4.3.1 (#1771) Bumps [@smithy/property-provider](https://github.com/smithy-lang/smithy-typescript/tree/HEAD/packages/property-provider) from 4.2.14 to 4.3.1. - [Release notes](https://github.com/smithy-lang/smithy-typescript/releases) - [Changelog](https://github.com/smithy-lang/smithy-typescript/blob/main/packages/property-provider/CHANGELOG.md) - [Commits](https://github.com/smithy-lang/smithy-typescript/commits/@smithy/property-provider@4.3.1/packages/property-provider) --- updated-dependencies: - dependency-name: "@smithy/property-provider" dependency-version: 4.3.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit1ab31502aa) * chore(deps): bump @smithy/node-http-handler from 4.6.1 to 4.7.1 (#1770) Bumps [@smithy/node-http-handler](https://github.com/smithy-lang/smithy-typescript/tree/HEAD/packages/node-http-handler) from 4.6.1 to 4.7.1. - [Release notes](https://github.com/smithy-lang/smithy-typescript/releases) - [Changelog](https://github.com/smithy-lang/smithy-typescript/blob/main/packages/node-http-handler/CHANGELOG.md) - [Commits](https://github.com/smithy-lang/smithy-typescript/commits/@smithy/node-http-handler@4.7.1/packages/node-http-handler) --- updated-dependencies: - dependency-name: "@smithy/node-http-handler" dependency-version: 4.7.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commitdbd503f368) * chore(deps-dev): bump @biomejs/biome from 2.4.14 to 2.4.15 (#1772) Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.4.14 to 2.4.15. - [Release notes](https://github.com/biomejs/biome/releases) - [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md) - [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.15/packages/@biomejs/biome) --- updated-dependencies: - dependency-name: "@biomejs/biome" dependency-version: 2.4.15 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit7521c55910) * chore(deps-dev): bump @types/node from 25.6.0 to 25.7.0 (#1773) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.6.0 to 25.7.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.7.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commitef734cca81) * feat: expose run id in STS client user-agent (#1774) * feat: expose run id in STS client user-agent Closes #483. This commit modifies the user-agent string so that it includes the GITHUB_RUN_ID and the GITHUB_RUN_ATTEMPT, in the format typically used by the SDK. User agent strings are logged to CloudTrail, allowing users to correlate CloudTrail events with GHA runs. We took this approach instead of logging the ACCESS_KEY_ID as suggested in the issue to avoid logging sensitive information. * feat: add github_action to ua string (cherry picked from commit29d1be3027) * feat: add additional session tags by default (#1775) Closes #390. Note that 50 session tags are the AWS default, and this commit changes our default set from 7 tags to 15 tags. This commit includes logic to split the tags into "required" vs "overridable". Required tags are this action's previous defaults and could never be overridden. Overridable tags are the new set and can be overridden by custom-tags. The action will not add tags if the addition plus the required plus the user's custom tags exceed the AWS limit of 50 total tags. This ensures backwards compat for the tag additions. (cherry picked from commite0ba768507) * chore: document forgejo compatibility (#1776) * chore: document forgejo compatibility * chore: linting fixes (cherry picked from commitf35a7d7d7e) * fix: skip credential check on output-env-credentials: false (#1778) Closes #1554. (cherry picked from commit58e7c47adf) * chore: update README for additional claim support (#1779) * chore: update README for additional claim support * chore: lint fix (whitespace) (cherry picked from commit713aaabfec) * chore(deps): bump @smithy/node-http-handler from 4.7.1 to 4.7.3 (#1781) Bumps [@smithy/node-http-handler](https://github.com/smithy-lang/smithy-typescript/tree/HEAD/packages/node-http-handler) from 4.7.1 to 4.7.3. - [Release notes](https://github.com/smithy-lang/smithy-typescript/releases) - [Changelog](https://github.com/smithy-lang/smithy-typescript/blob/main/packages/node-http-handler/CHANGELOG.md) - [Commits](https://github.com/smithy-lang/smithy-typescript/commits/@smithy/node-http-handler@4.7.3/packages/node-http-handler) --- updated-dependencies: - dependency-name: "@smithy/node-http-handler" dependency-version: 4.7.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commita7c33ae483) * chore(deps-dev): bump @types/node from 25.7.0 to 25.9.0 (#1785) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.7.0 to 25.9.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.9.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commitffde832a1d) * chore(deps-dev): bump @aws-sdk/credential-provider-env (#1784) Bumps [@aws-sdk/credential-provider-env](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages-internal/credential-provider-env) from 3.972.34 to 3.972.38. - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages-internal/credential-provider-env/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/HEAD/packages-internal/credential-provider-env) --- updated-dependencies: - dependency-name: "@aws-sdk/credential-provider-env" dependency-version: 3.972.38 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commitbc1093db1d) * chore(deps-dev): bump @smithy/property-provider from 4.3.1 to 4.3.3 (#1783) Bumps [@smithy/property-provider](https://github.com/smithy-lang/smithy-typescript/tree/HEAD/packages/property-provider) from 4.3.1 to 4.3.3. - [Release notes](https://github.com/smithy-lang/smithy-typescript/releases) - [Changelog](https://github.com/smithy-lang/smithy-typescript/blob/main/packages/property-provider/CHANGELOG.md) - [Commits](https://github.com/smithy-lang/smithy-typescript/commits/@smithy/property-provider@4.3.3/packages/property-provider) --- updated-dependencies: - dependency-name: "@smithy/property-provider" dependency-version: 4.3.3 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commitfe6ad3af19) * chore(deps): bump @aws-sdk/client-sts from 3.1045.0 to 3.1049.0 (#1782) Bumps [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) from 3.1045.0 to 3.1049.0. - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1049.0/clients/client-sts) --- updated-dependencies: - dependency-name: "@aws-sdk/client-sts" dependency-version: 3.1049.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit4684f47f89) * chore: reconcile lockfile and test formatting * chore: Update dist --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Michael Lehmann <lehmanmj@amazon.com> Co-authored-by: Sylvain Verly <sylvain.verly@gmail.com>
332 lines
14 KiB
TypeScript
332 lines
14 KiB
TypeScript
import * as core from '@actions/core';
|
|
import type { AssumeRoleCommandOutput } from '@aws-sdk/client-sts';
|
|
import { assumeRole } from './assumeRole';
|
|
import { CredentialsClient } from './CredentialsClient';
|
|
import {
|
|
areCredentialsValid,
|
|
errorMessage,
|
|
exportAccountId,
|
|
exportCredentials,
|
|
exportRegion,
|
|
getBooleanInput,
|
|
retryAndBackoff,
|
|
translateEnvVariables,
|
|
unsetCredentials,
|
|
verifyKeys,
|
|
} from './helpers';
|
|
import { writeProfileFiles } from './profileManager';
|
|
|
|
const DEFAULT_ROLE_DURATION = 3600; // One hour (seconds)
|
|
const ROLE_SESSION_NAME = 'GitHubActions';
|
|
const REGION_REGEX = /^[a-z0-9-]+$/g;
|
|
const ROLE_SESSION_NAME_REGEX = /^[\w+=,.@-]*$/;
|
|
|
|
export async function run() {
|
|
try {
|
|
translateEnvVariables();
|
|
// Get inputs
|
|
// Undefined inputs are empty strings ( or empty arrays)
|
|
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 SessionToken = sessionTokenInput === '' ? undefined : sessionTokenInput;
|
|
const region = core.getInput('aws-region', { required: true });
|
|
const awsProfile = core.getInput('aws-profile', { required: false });
|
|
const overwriteAwsProfile = getBooleanInput('overwrite-aws-profile', { required: false });
|
|
const roleToAssume = core.getInput('role-to-assume', { required: false });
|
|
const audience = core.getInput('audience', { required: false });
|
|
const maskAccountId = getBooleanInput('mask-aws-account-id', { required: false });
|
|
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 roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME;
|
|
const roleSkipSessionTagging = getBooleanInput('role-skip-session-tagging', { required: false });
|
|
const transitiveTagKeys = core.getMultilineInput('transitive-tag-keys', { required: false });
|
|
const proxyServer = core.getInput('http-proxy', { required: false }) || process.env.HTTP_PROXY;
|
|
const customTags = core.getInput('custom-tags', { required: false });
|
|
const inlineSessionPolicy = core.getInput('inline-session-policy', { required: false });
|
|
const managedSessionPolicies = core.getMultilineInput('managed-session-policies', { required: false }).map((p) => {
|
|
return { arn: p };
|
|
});
|
|
const roleChaining = getBooleanInput('role-chaining', { required: false });
|
|
const outputCredentials = getBooleanInput('output-credentials', { required: false });
|
|
// Default to always outputting environment credentials unless profile is specified. If profile is specified, default to
|
|
// no environment credentials (but still output them if the user specifically requests it).
|
|
const outputEnvCredentials = getBooleanInput('output-env-credentials', { required: false, default: !awsProfile });
|
|
const unsetCurrentCredentials = getBooleanInput('unset-current-credentials', { required: false });
|
|
let disableRetry = getBooleanInput('disable-retry', { required: false });
|
|
const specialCharacterWorkaround = getBooleanInput('special-characters-workaround', { required: false });
|
|
const useExistingCredentials = core.getInput('use-existing-credentials', { required: false });
|
|
let maxRetries = Number.parseInt(core.getInput('retry-max-attempts', { required: false })) || 12;
|
|
const expectedAccountIds = core
|
|
.getInput('allowed-account-ids', { required: false })
|
|
.split(',')
|
|
.map((s) => s.trim());
|
|
const forceSkipOidc = getBooleanInput('force-skip-oidc', { required: false });
|
|
const noProxy = core.getInput('no-proxy', { required: false });
|
|
const stsEndpoint = core.getInput('sts-endpoint', { required: false });
|
|
const globalTimeout = Number.parseInt(core.getInput('action-timeout-s', { required: false })) || 0;
|
|
|
|
let timeoutId: NodeJS.Timeout | undefined;
|
|
if (globalTimeout > 0) {
|
|
core.info(`Setting a global timeout of ${globalTimeout} seconds for the action`);
|
|
timeoutId = setTimeout(() => {
|
|
core.setFailed(`Action timed out after ${globalTimeout} seconds`);
|
|
process.exit(1);
|
|
}, globalTimeout * 1000);
|
|
}
|
|
|
|
if (forceSkipOidc && roleToAssume && !AccessKeyId && !webIdentityTokenFile) {
|
|
throw new Error(
|
|
"If 'force-skip-oidc' is true and 'role-to-assume' is set, 'aws-access-key-id' or 'web-identity-token-file' must be set",
|
|
);
|
|
}
|
|
|
|
if (specialCharacterWorkaround) {
|
|
// 😳
|
|
disableRetry = false;
|
|
maxRetries = 12;
|
|
} else if (maxRetries < 1) {
|
|
maxRetries = 1;
|
|
}
|
|
|
|
const withRetry = <T>(fn: () => Promise<T>, label: string): Promise<T> =>
|
|
retryAndBackoff(fn, !disableRetry, maxRetries, 0, 50, label);
|
|
|
|
// Logic to decide whether to attempt to use OIDC or not
|
|
const useGitHubOIDCProvider = () => {
|
|
if (forceSkipOidc) return false;
|
|
// The `ACTIONS_ID_TOKEN_REQUEST_TOKEN` environment variable is set when the `id-token` permission is granted.
|
|
// This is necessary to authenticate with OIDC, but not strictly set just for OIDC. If it is not set and all other
|
|
// checks pass, it is likely but not guaranteed that the user needs but lacks this permission in their workflow.
|
|
// So, we will log a warning when it is the only piece absent
|
|
if (
|
|
!!roleToAssume &&
|
|
!webIdentityTokenFile &&
|
|
!AccessKeyId &&
|
|
!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.',
|
|
);
|
|
}
|
|
return (
|
|
!!roleToAssume &&
|
|
!!process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN &&
|
|
!AccessKeyId &&
|
|
!webIdentityTokenFile &&
|
|
!roleChaining
|
|
);
|
|
};
|
|
|
|
if (unsetCurrentCredentials) {
|
|
unsetCredentials(outputEnvCredentials);
|
|
}
|
|
|
|
if (!region.match(REGION_REGEX)) {
|
|
throw new Error(`Region is not valid: ${region}`);
|
|
}
|
|
|
|
if (roleSessionName.length < 2 || roleSessionName.length > 64) {
|
|
throw new Error(
|
|
`Role session name must be between 2 and 64 characters, got ${roleSessionName.length}: '${roleSessionName}'`,
|
|
);
|
|
}
|
|
if (!roleSessionName.match(ROLE_SESSION_NAME_REGEX)) {
|
|
throw new Error(
|
|
`Role session name is not valid: '${roleSessionName}'. Must satisfy regular expression pattern: [\\w+=,.@-]*`,
|
|
);
|
|
}
|
|
|
|
exportRegion(region, outputEnvCredentials);
|
|
|
|
// Instantiate credentials client
|
|
const clientProps: {
|
|
region: string;
|
|
proxyServer?: string;
|
|
noProxy?: string;
|
|
stsEndpoint?: string;
|
|
roleChaining: boolean;
|
|
} = {
|
|
region,
|
|
roleChaining,
|
|
};
|
|
if (proxyServer) clientProps.proxyServer = proxyServer;
|
|
if (noProxy) clientProps.noProxy = noProxy;
|
|
if (stsEndpoint) clientProps.stsEndpoint = stsEndpoint;
|
|
const credentialsClient = new CredentialsClient(clientProps);
|
|
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.');
|
|
if (timeoutId) clearTimeout(timeoutId);
|
|
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()) {
|
|
try {
|
|
webIdentityToken = await withRetry(async () => {
|
|
return core.getIDToken(audience);
|
|
}, 'getIDToken');
|
|
} catch (error) {
|
|
throw new Error(`getIDToken call failed: ${errorMessage(error)}`);
|
|
}
|
|
} else if (AccessKeyId) {
|
|
if (!SecretAccessKey) {
|
|
throw new Error("'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided");
|
|
}
|
|
// The STS client for calling AssumeRole pulls creds from the environment.
|
|
// Plus, in the assume role case, if the AssumeRole call fails, we want
|
|
// the source credentials to already be masked as secrets
|
|
// in any error messages.
|
|
exportCredentials({ AccessKeyId, SecretAccessKey, SessionToken }, outputCredentials, outputEnvCredentials);
|
|
|
|
// If using IAM User Credentials, write to profile now so that the assumeRole call can succeed (and also for
|
|
// credential validation before role assumption).
|
|
if (awsProfile) {
|
|
writeProfileFiles(awsProfile, { AccessKeyId, SecretAccessKey, SessionToken }, region, overwriteAwsProfile);
|
|
}
|
|
} else if (!webIdentityTokenFile && !roleChaining) {
|
|
// Proceed only if credentials can be picked up
|
|
await withRetry(
|
|
() => credentialsClient.validateCredentials(undefined, roleChaining, expectedAccountIds),
|
|
'validateCredentials',
|
|
);
|
|
sourceAccountId = await withRetry(() => exportAccountId(credentialsClient, maskAccountId), 'exportAccountId');
|
|
}
|
|
|
|
if (AccessKeyId || roleChaining) {
|
|
// Validate that the SDK can actually pick up credentials.
|
|
// This validates cases where this action is using existing environment credentials,
|
|
// and cases where the user intended to provide input credentials but the secrets inputs resolved to empty strings.
|
|
// Skip when output-env-credentials is false: input IAM keys were not written to env, so
|
|
// the default chain would resolve to ambient runner credentials and the access-key check
|
|
// would spuriously fail (see #1554).
|
|
if (outputEnvCredentials) {
|
|
await withRetry(
|
|
() => credentialsClient.validateCredentials(AccessKeyId, roleChaining, expectedAccountIds),
|
|
'validateCredentials',
|
|
);
|
|
sourceAccountId = await withRetry(() => exportAccountId(credentialsClient, maskAccountId), 'exportAccountId');
|
|
}
|
|
}
|
|
if (customTags && (useGitHubOIDCProvider() || webIdentityTokenFile)) {
|
|
core.warning(
|
|
"'custom-tags' is set but will be ignored because session tags cannot be applied when using OIDC or web identity token authentication. " +
|
|
'Tags are controlled by the identity provider token claims in these authentication flows.',
|
|
);
|
|
}
|
|
|
|
// Get role credentials if configured to do so
|
|
if (roleToAssume) {
|
|
let roleCredentials: AssumeRoleCommandOutput;
|
|
do {
|
|
roleCredentials = await withRetry(async () => {
|
|
return assumeRole({
|
|
credentialsClient,
|
|
sourceAccountId,
|
|
roleToAssume,
|
|
roleExternalId,
|
|
roleDuration,
|
|
roleSessionName,
|
|
roleSkipSessionTagging,
|
|
transitiveTagKeys,
|
|
webIdentityTokenFile,
|
|
webIdentityToken,
|
|
inlineSessionPolicy,
|
|
managedSessionPolicies,
|
|
customTags,
|
|
});
|
|
}, 'AssumeRole');
|
|
} while (specialCharacterWorkaround && !verifyKeys(roleCredentials.Credentials));
|
|
core.info(`Authenticated as assumedRoleId ${roleCredentials.AssumedRoleUser?.AssumedRoleId}`);
|
|
exportCredentials(roleCredentials.Credentials, outputCredentials, outputEnvCredentials);
|
|
// Validate that the SDK can pick up the assumed-role credentials from the environment.
|
|
// Skip when output-env-credentials is false: the credentials were never written to env,
|
|
// so the default credential provider chain would resolve to ambient runner credentials
|
|
// (e.g. an EC2 instance profile) and the access-key-id check would spuriously fail.
|
|
// Skip when using a profile: validation runs after the profile file is written below.
|
|
if ((!process.env.GITHUB_ACTIONS || AccessKeyId) && !awsProfile && outputEnvCredentials) {
|
|
await withRetry(
|
|
() =>
|
|
credentialsClient.validateCredentials(
|
|
roleCredentials.Credentials?.AccessKeyId,
|
|
roleChaining,
|
|
expectedAccountIds,
|
|
),
|
|
'validateCredentials',
|
|
);
|
|
}
|
|
if (outputEnvCredentials) {
|
|
await withRetry(() => exportAccountId(credentialsClient, maskAccountId), 'exportAccountId');
|
|
}
|
|
|
|
// Write profile files if profile mode is enabled
|
|
if (awsProfile) {
|
|
if (!roleCredentials.Credentials) {
|
|
throw new Error('AssumeRole call succeeded but returned no credentials');
|
|
}
|
|
// If user provided IAM User Credentials and then we assumed a role, overwrite the profile file to add
|
|
// the session token. (this only overwrites the profile within a single run of the action).
|
|
// We then validate the credentials to make sure they work.
|
|
if (AccessKeyId || !process.env.GITHUB_ACTIONS) {
|
|
writeProfileFiles(awsProfile, roleCredentials.Credentials, region, true);
|
|
await withRetry(
|
|
() =>
|
|
credentialsClient.validateCredentials(
|
|
roleCredentials.Credentials?.AccessKeyId,
|
|
roleChaining,
|
|
expectedAccountIds,
|
|
),
|
|
'validateCredentials',
|
|
);
|
|
} else {
|
|
writeProfileFiles(awsProfile, roleCredentials.Credentials, region, overwriteAwsProfile);
|
|
}
|
|
|
|
if (outputEnvCredentials) {
|
|
core.exportVariable('AWS_PROFILE', awsProfile);
|
|
}
|
|
}
|
|
} else {
|
|
core.info('Proceeding with IAM user credentials');
|
|
|
|
if (awsProfile) {
|
|
if (outputEnvCredentials) {
|
|
core.exportVariable('AWS_PROFILE', awsProfile);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clear timeout on successful completion
|
|
if (timeoutId) clearTimeout(timeoutId);
|
|
} catch (error) {
|
|
core.setFailed(errorMessage(error));
|
|
|
|
const showStackTrace = process.env.SHOW_STACK_TRACE;
|
|
if (showStackTrace === 'true') {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* c8 ignore start */
|
|
/* istanbul ignore next */
|
|
if (require.main === module) {
|
|
(async () => {
|
|
await run();
|
|
})().catch((error) => {
|
|
core.setFailed(errorMessage(error));
|
|
});
|
|
}
|