diff --git a/.github/workflows/tests-integ.yml b/.github/workflows/tests-integ.yml index b1c5358f3..b2f15ed9d 100644 --- a/.github/workflows/tests-integ.yml +++ b/.github/workflows/tests-integ.yml @@ -72,6 +72,9 @@ jobs: role-to-assume: ${{ secrets.SECRETS_AWS_ROLE_TO_ASSUME }} role-session-name: IntegAccessKeysAssumeRole role-external-id: ${{ secrets.SECRETS_AWS_ROLE_EXTERNAL_ID }} + transitive-tag-keys: + Actor + Repository integ-access-keys-env: strategy: fail-fast: false @@ -93,6 +96,7 @@ jobs: role-to-assume: ${{ secrets.SECRETS_AWS_ROLE_TO_ASSUME }} role-session-name: IntegAccessKeysAssumeRole role-external-id: ${{ secrets.SECRETS_AWS_ROLE_EXTERNAL_ID }} + transitive-tag-keys: Repository integ-iam-user: strategy: fail-fast: false diff --git a/README.md b/README.md index 1e7f7c29b..d62105a50 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ See [action.yml](./action.yml) for more detail. | role-external-id | The external ID of the role to assume. Only needed if your role requires it. | No | | role-session-name | Defaults to "GitHubActions", but may be changed if required. | No | | role-skip-session-tagging | Skips session tagging if set. | No | +| transitive-tag-keys | Define a list of transitive tag keys to pass when assuming a role. | No | | inline-session-policy | You may further restrict the assumed role policy by defining an inline policy here. | No | | managed-session-policies | You may further restrict the assumed role policy by specifying a managed policy here. | No | | output-credentials | When set, outputs fetched credentials as action step output. Defaults to false. | No | @@ -167,6 +168,18 @@ You can skip this session tagging by providing role-skip-session-tagging: true ``` +To forward session tags to subsequent sessions in a role chain, you can use the +`transitive-tag-keys` input to specify the keys of the tags to be passed. Eg. +```yaml + uses: aws-actions/configure-aws-credentials@v4 + with: + transitive-tag-keys: + Repository + Workflow + Action + Actor +``` + ### Session policies Session policies are not required, but they allow you to limit the scope of the fetched credentials without making changes to IAM roles. You can specify inline diff --git a/action.yml b/action.yml index 91ba47548..d792ae396 100644 --- a/action.yml +++ b/action.yml @@ -52,6 +52,9 @@ inputs: role-skip-session-tagging: description: Skip session tagging during role assumption required: false + transitive-tag-keys: + description: Define a list of transitive tag keys to pass when assuming a role + required: false inline-session-policy: description: Define an inline session policy to use when assuming a role required: false diff --git a/src/assumeRole.ts b/src/assumeRole.ts index 668c2a0cf..62db820cf 100644 --- a/src/assumeRole.ts +++ b/src/assumeRole.ts @@ -70,6 +70,7 @@ export interface assumeRoleParams { roleDuration: number; roleSessionName: string; roleSkipSessionTagging?: boolean; + transitiveTagKeys?: string[]; sourceAccountId?: string; roleExternalId?: string; webIdentityTokenFile?: string; @@ -87,6 +88,7 @@ export async function assumeRole(params: assumeRoleParams) { roleDuration, roleSessionName, roleSkipSessionTagging, + transitiveTagKeys, webIdentityTokenFile, webIdentityToken, inlineSessionPolicy, @@ -121,6 +123,8 @@ export async function assumeRole(params: assumeRoleParams) { core.debug(`${tags.length} role session tags are being used.`); } + const transitiveTagKeysArray = transitiveTagKeys?.filter((key) => tags?.some((tag) => tag.Key === key)); + // Calculate role ARN from name and account ID (currently only supports `aws` partition) let roleArn = roleToAssume; if (!roleArn.startsWith('arn:aws')) { @@ -137,6 +141,7 @@ export async function assumeRole(params: assumeRoleParams) { RoleSessionName: roleSessionName, DurationSeconds: roleDuration, Tags: tags ? tags : undefined, + TransitiveTagKeys: transitiveTagKeysArray, ExternalId: roleExternalId ? roleExternalId : undefined, Policy: inlineSessionPolicy ? inlineSessionPolicy : undefined, PolicyArns: managedSessionPolicies?.length ? managedSessionPolicies : undefined, diff --git a/src/index.ts b/src/index.ts index a35452bf4..85f87fb84 100644 --- a/src/index.ts +++ b/src/index.ts @@ -44,6 +44,7 @@ export async function run() { const roleSessionName = core.getInput('role-session-name', { required: false }) || ROLE_SESSION_NAME; const roleSkipSessionTaggingInput = core.getInput('role-skip-session-tagging', { required: false }) || 'false'; const roleSkipSessionTagging = roleSkipSessionTaggingInput.toLowerCase() === 'true'; + const transitiveTagKeys = core.getMultilineInput('transitive-tag-keys', { required: false }); const proxyServer = core.getInput('http-proxy', { required: false }); const inlineSessionPolicy = core.getInput('inline-session-policy', { required: false, @@ -180,6 +181,7 @@ export async function run() { roleDuration, roleSessionName, roleSkipSessionTagging, + transitiveTagKeys, webIdentityTokenFile, webIdentityToken, inlineSessionPolicy,