Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

fix(aws-util): use current session partition in GetRoleArn#616

Open
nlang wants to merge 1 commit intoorg-formation:masterorg-formation/org-formation-cli:masterfrom
wabicloud:fix/getrolearn-partitionwabicloud/org-formation-cli:fix/getrolearn-partitionCopy head branch name to clipboard
Open

fix(aws-util): use current session partition in GetRoleArn#616
nlang wants to merge 1 commit intoorg-formation:masterorg-formation/org-formation-cli:masterfrom
wabicloud:fix/getrolearn-partitionwabicloud/org-formation-cli:fix/getrolearn-partitionCopy head branch name to clipboard

Conversation

@nlang
Copy link
Copy Markdown

@nlang nlang commented Apr 29, 2026

Summary

AwsUtil.GetRoleArn hardcodes the commercial AWS partition (arn:aws:iam::...) when constructing the cross-account AssumeRole ARN. In any non-commercial partition this produces ARNs that the running partition's IAM cannot resolve, breaking every multi-account operation — including the post-CreateAccount initial assume into a freshly provisioned member account.

The partition is already determined dynamically during Initialize() via GetPartitionFromCurrentSession() (uses STS GetCallerIdentity) and cached on AwsUtil.partition. This change uses that cached value, falling back to 'aws' so the commercial path is byte-for-byte unchanged.

The GovCloud-mode GetPartitionRoleArn is intentionally left alone — it represents a cross-partition target ARN and its semantics differ (commercial → GovCloud mirroring).

How I hit this

Bootstrapping a multi-account organization in AWS European Sovereign Cloud (eusc-de-east-1, partition aws-eusc):

  1. First update-organization against the EUSC master account: ✅ works.
  2. CreateAccount for a sandbox member: ✅ AWS provisions the account, OFN sees the new account ID.
  3. OFN immediately tries to assume OrganizationAccountAccessRole in the new member to set tags / move to OU.
  4. AccessDenied: ... is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::<member-id>:role/OrganizationAccountAccessRole — note the aws: partition in a partition that doesn't know it.

With this patch, the ARN becomes arn:aws-eusc:iam::... and the assume succeeds. Validated end-to-end: org-create, account-create, IAM stack in member, SSO assignment in master — all green.

Compatibility

  • Commercial AWS: AwsUtil.partition === 'aws' (set during Initialize), behavior identical.
  • GovCloud: same — partition cache is 'aws-us-gov' for runs in that partition.
  • Pre-Initialize call (defensive): falls back to 'aws', same as before.

Out of scope (audit notes for reviewers)

A wider grep for partition-relevant hardcodes turned up a handful of others, all in code paths my EUSC use case does not exercise. Listed for transparency, intentionally not in this PR to keep the diff focused:

  • src/parser/validator.ts:176knownRegions whitelist lacks eusc-de-east-1 (produces a non-fatal WARN: region not recognized).
  • src/aws-provider/aws-events.ts:52us-east-1 hardcoded for the post-run OrganizationChanged EventBridge notification (non-fatal unable to put event after successful runs in EUSC).
  • src/util/aws-util.ts:752 — large-template S3 URL uses s3.<region>.amazonaws.com literal (only triggers for templates over the inline-body limit).
  • src/plugin/impl/rp-build-task-plugin.ts:187 — community resource provider catalog URL uses s3.amazonaws.com literal (only triggers when registering custom resource types; EUSC currently has no Public Extensions registry, so this needs a different solution anyway).
  • src/aws-provider/aws-organization-reader.ts:74 — partition mirror detection only matches aws-us-gov, not other non-commercial partitions.

Happy to follow up with separate PRs for any of these if useful.

Relation to #613

#613 (feat/eusc) addresses a different scenario: managing a commercial Org and an EUSC Org in mirror mode (analogous to the existing GovCloud mirror). My use case is a standalone EUSC Org with no commercial counterpart, where the only thing missing is partition-correct ARN construction. The two changes are orthogonal and could land independently.

Cross-account `AssumeRole` ARN construction is hardcoded to the
commercial AWS partition (`arn:aws:iam::...`). In any non-commercial
partition (e.g. AWS European Sovereign Cloud `aws-eusc`, or the China
partitions `aws-cn`) this produces ARNs that cannot be resolved by the
running partition's IAM, breaking every multi-account operation —
including the post-CreateAccount initial assume into a freshly
provisioned member account.

Fix: read the partition from the cached value populated during
`Initialize()` via `GetPartitionFromCurrentSession`. Falls back to
'aws' so behavior in commercial AWS is unchanged. The GovCloud-mode
`GetPartitionRoleArn` is intentionally left alone — it represents a
cross-partition target ARN and its semantics differ.

Discovered while bootstrapping a multi-account organization in
`eusc-de-east-1`: the first `update-organization` succeeded for the
master account, then `CreateAccount` for a sandbox member account
succeeded, and OFN immediately failed with `AccessDenied` on
`sts:AssumeRole arn:aws:iam::<member>:role/OrganizationAccountAccessRole`
— note the `aws:` partition in the ARN. With this fix that ARN
becomes `arn:aws-eusc:iam::...` and the assume succeeds.

Note for reviewers: a separate audit identified a few more partition-
relevant hardcodes (region whitelist in `validator.ts`, EventBridge
region in `aws-events.ts:52`, large-template URL in `aws-util.ts`,
catalog URL in `rp-build-task-plugin.ts`). They are in code paths not
exercised by my use case and are intentionally left out of this PR to
keep the diff focused. Happy to follow up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.