Compare commits

..

1 Commits

Author SHA1 Message Date
Tom Keller 1b88572b3b fix: attach git credentials before Tag Major Version push
The Tag Major Version step ran 'git push origin' after Checkout Again
re-cloned with persist-credentials: false, leaving the remote without
credentials. This caused 'fatal: could not read Username' (exit 128) on
the first release. Set the authenticated remote URL using OSDS_ACCESS_TOKEN
before pushing tags, mirroring the Update README step.
2026-07-09 12:25:02 -07:00
7 changed files with 2253 additions and 2633 deletions
+7 -35
View File
@@ -26,7 +26,7 @@ Authenticate to AWS in GitHub Actions (and others)! Works especially well with
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:<GITHUB_ORG>@<ORG_ID>/<GITHUB_REPOSITORY>@<REPO_ID>:ref:refs/heads/<GITHUB_BRANCH>"
"token.actions.githubusercontent.com:sub": "repo:<GITHUB_ORG>/<GITHUB_REPOSITORY>:ref:refs/heads/<GITHUB_BRANCH>"
}
}
}
@@ -36,16 +36,11 @@ Authenticate to AWS in GitHub Actions (and others)! Works especially well with
</details>
Note: The value of the `sub` claim may be different depending on the workflow
and the environment in which it's running. Workflows in repositories created
prior to [15 July 2026][immutable-sub] will omit the `@<ORG_ID>` and
`@<REPO_ID>` suffixes unless opted in. Workflows running in GitHub
environments will include an`environment:<ENVIRONMENT_NAME>` stanza. See
[Claims and scoping permissions](#claims-and-scoping-permissions) for more
information.
[immutable-sub]:
https://github.blog/changelog/2026-04-23-immutable-subject-claims-for-github-actions-oidc-tokens/
Note: if you are running in a GitHub environment based workflow, the value
for the Sub claim will be different, in the form of
`repo:<GITHUB_ORG>/<GITHUB_REPOSITORY>:environment:<ENVIRONMENT_NAME>`.
Adjust the trust policy accordingly if you are using environment-based
workflows.
3. Attach permissions to the IAM Role that allow it to access the AWS resources
you need.
@@ -598,29 +593,6 @@ claims ([1][gh-blog-oidc], [2][sub-claim-custom]).
> unintended access. Instead, use `StringEquals` or `StringLike` operators to
> check for specific claim values.
#### Immutable subject claims
Repositories created on github.com on or after 15 July 2026, and older
repositories that have opted in, emit an [immutable `sub` claim][immutable-sub].
This claim appends the permanent numeric ID of the organization and of the
repository after each name, separated by `@`, so that a recycled org or
repository name cannot be used to mint tokens matching a stale trust policy.
For example:
```text
# Legacy (mutable) sub claim
repo:octo-org/octo-repo:ref:refs/heads/main
# Immutable sub claim
repo:octo-org@123456/octo-repo@789012:ref:refs/heads/main
```
If your trust policy matches the legacy name-only form and your repository emits
the immutable claim, `AssumeRoleWithWebIdentity` fails with `Not authorized to
perform sts:AssumeRoleWithWebIdentity`. To fix this, update the `sub` condition
to the immutable form. You can find your repository's prefix in the Settings,
or by following the token inspection steps below.
[least-privilege]:
https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege
[gh-blog-oidc]:
@@ -633,7 +605,7 @@ or by following the token inspection steps below.
If you aren't sure what claim values your workflow is producing, the
[`actions-oidc-debugger`](https://github.com/github/actions-oidc-debugger)
action will print the decoded JWT payload. Run it in a private repository
only; the token itself is short-lived but the claim values may be sensitive.
only the token itself is short-lived but the claim values may be sensitive.
See the GitHub [security-hardening guide][gh-oidc-hardening] for further
discussion of trust conditions and threat modeling.
+21 -21
View File
@@ -222,7 +222,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The following npm package may be included in this product:
- @aws-sdk/client-sts@3.1091.0
- @aws-sdk/client-sts@3.1080.0
This package contains the following license:
@@ -432,9 +432,9 @@ Apache License
The following npm packages may be included in this product:
- @aws-sdk/signature-v4-multi-region@3.996.41
- @smithy/core@3.29.6
- @smithy/types@4.16.1
- @aws-sdk/signature-v4-multi-region@3.996.38
- @smithy/core@3.29.1
- @smithy/types@4.15.1
These packages each contain the following license:
@@ -832,7 +832,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The following npm package may be included in this product:
- @aws-sdk/core@3.975.3
- @aws-sdk/core@3.974.28
This package contains the following license:
@@ -1042,16 +1042,16 @@ Apache License
The following npm packages may be included in this product:
- @aws-sdk/credential-provider-env@3.972.59
- @aws-sdk/credential-provider-ini@3.973.4
- @aws-sdk/credential-provider-node@3.972.70
- @aws-sdk/token-providers@3.1088.0
- @aws-sdk/types@3.974.2
- @aws-sdk/xml-builder@3.972.36
- @smithy/credential-provider-imds@4.4.11
- @smithy/fetch-http-handler@5.6.8
- @smithy/node-http-handler@4.9.8
- @smithy/signature-v4@5.6.7
- @aws-sdk/credential-provider-env@3.972.54
- @aws-sdk/credential-provider-ini@3.972.61
- @aws-sdk/credential-provider-node@3.972.63
- @aws-sdk/token-providers@3.1080.0
- @aws-sdk/types@3.973.15
- @aws-sdk/xml-builder@3.972.33
- @smithy/credential-provider-imds@4.4.6
- @smithy/fetch-http-handler@5.6.3
- @smithy/node-http-handler@4.9.3
- @smithy/signature-v4@5.6.2
These packages each contain the following license:
@@ -1261,9 +1261,9 @@ Apache License
The following npm packages may be included in this product:
- @aws-sdk/credential-provider-process@3.972.59
- @aws-sdk/credential-provider-sso@3.973.3
- @aws-sdk/credential-provider-web-identity@3.972.65
- @aws-sdk/credential-provider-process@3.972.54
- @aws-sdk/credential-provider-sso@3.972.60
- @aws-sdk/credential-provider-web-identity@3.972.60
These packages each contain the following license:
@@ -1473,9 +1473,9 @@ Apache License
The following npm packages may be included in this product:
- @aws-sdk/credential-provider-http@3.972.61
- @aws-sdk/credential-provider-login@3.972.66
- @aws-sdk/nested-clients@3.997.33
- @aws-sdk/credential-provider-http@3.972.56
- @aws-sdk/credential-provider-login@3.972.60
- @aws-sdk/nested-clients@3.997.28
These packages each contain the following license:
Generated Vendored
+1906 -1877
View File
File diff suppressed because it is too large Load Diff
+299 -684
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -17,25 +17,25 @@
"organization": true
},
"devDependencies": {
"@aws-sdk/credential-provider-env": "^3.972.59",
"@biomejs/biome": "2.5.4",
"@smithy/property-provider": "^4.4.11",
"@types/node": "^26.1.1",
"@aws-sdk/credential-provider-env": "^3.972.49",
"@biomejs/biome": "2.5.2",
"@smithy/property-provider": "^4.4.6",
"@types/node": "^26.1.0",
"@vitest/coverage-v8": "4.1.10",
"aws-sdk-client-mock": "^4.1.0",
"esbuild": "^0.28.1",
"generate-license-file": "^4.2.1",
"json-schema": "^0.4.0",
"markdownlint-cli": "^0.49.1",
"memfs": "^4.64.0",
"markdownlint-cli": "^0.49.0",
"memfs": "^4.58.0",
"standard-version": "^9.5.0",
"typescript": "^7.0.2",
"typescript": "^6.0.3",
"vitest": "4.1.10"
},
"dependencies": {
"@actions/core": "^3.0.1",
"@aws-sdk/client-sts": "^3.1091.0",
"@smithy/node-http-handler": "^4.9.8",
"@aws-sdk/client-sts": "^3.1080.0",
"@smithy/node-http-handler": "^4.9.1",
"proxy-agent": "^8.0.2"
},
"keywords": [
+6 -2
View File
@@ -2,7 +2,11 @@ import assert from 'node:assert';
import path from 'node:path';
import * as core from '@actions/core';
import type { AssumeRoleCommandInput, STSClient, Tag } from '@aws-sdk/client-sts';
import { AssumeRoleCommand, AssumeRoleWithWebIdentityCommand } from '@aws-sdk/client-sts';
import {
AssumeRoleCommand,
AssumeRoleWithWebIdentityCommand,
PackedPolicyTooLargeException,
} from '@aws-sdk/client-sts';
import type { CredentialsClient } from './CredentialsClient';
import { errorMessage, isDefined, readFileUtf8, sanitizeGitHubVariables } from './helpers';
@@ -61,7 +65,7 @@ async function assumeRoleWithCredentials(params: AssumeRoleCommandInput, client:
const creds = await client.send(new AssumeRoleCommand({ ...params }));
return creds;
} catch (error) {
if ((error as { name?: string })?.name === 'PackedPolicyTooLargeException') {
if (error instanceof PackedPolicyTooLargeException) {
core.info('Session tag size is too large; dropping droppable tags and retrying.');
const droppableKeys = new Set(DROPPABLE_TAG_SOURCES.map((s) => s.key));
params.Tags = params.Tags?.filter((tag) => !droppableKeys.has(tag.Key ?? ''));
+5 -5
View File
@@ -3,6 +3,7 @@ import {
AssumeRoleCommand,
AssumeRoleWithWebIdentityCommand,
GetCallerIdentityCommand,
PackedPolicyTooLargeException,
STSClient,
} from '@aws-sdk/client-sts';
import { mockClient } from 'aws-sdk-client-mock';
@@ -330,11 +331,10 @@ describe('Configure AWS Credentials', {}, () => {
});
it('drops droppable tags and retries on PackedPolicyTooLargeException', {}, async () => {
vi.mocked(core.getInput).mockImplementation(mocks.getInput(mocks.IAM_ASSUMEROLE_INPUTS));
// Reject with a plain error carrying only the `name`, NOT an instance of the SDK class. This
// mirrors the bundled action, where the error can be deserialized by a second, non-identical
// copy of PackedPolicyTooLargeException so `instanceof` fails; the recovery must key off `name`.
const packedPolicyError = Object.assign(new Error('too large'), { name: 'PackedPolicyTooLargeException' });
mockedSTSClient.on(AssumeRoleCommand).rejectsOnce(packedPolicyError).resolvesOnce(mocks.outputs.STS_CREDENTIALS);
mockedSTSClient
.on(AssumeRoleCommand)
.rejectsOnce(new PackedPolicyTooLargeException({ message: 'too large', $metadata: {} }))
.resolvesOnce(mocks.outputs.STS_CREDENTIALS);
await run();
expect(core.info).toHaveBeenCalledWith('Session tag size is too large; dropping droppable tags and retrying.');
const retryInput = mockedSTSClient.commandCalls(AssumeRoleCommand)[1].args[0].input;