Skip to content

fix(amplify-category-storage): make IAM policy names environment-specific - #14962

Open
w3lld1 wants to merge 3 commits into
aws-amplify:devfrom
w3lld1:category-storage/unique-policy-names-14961
Open

w3lld1 wants to merge 3 commits into
aws-amplify:devfrom
w3lld1:category-storage/unique-policy-names-14961

Conversation

@w3lld1

@w3lld1 w3lld1 commented Jul 15, 2026

Copy link
Copy Markdown

Description of changes

I made generated S3 IAM policy names environment-specific by appending the current Amplify environment name to the existing policy UUID. This prevents two environments that share imported auth roles from trying to manage identically named inline policies.

I also added a focused regression test for the generated policy names and updated the existing stack-transform expectations.

Issue #, if available

Fixes #14961

Description of how you validated changes

  • yarn lerna run build --scope @aws-amplify/amplify-category-storage --include-dependencies --concurrency 4
  • node ../../node_modules/jest/bin/jest.js --runInBand --coverage=false from packages/amplify-category-storage (15 suites, 48 tests)
  • Prettier and ESLint checks for all changed TypeScript files

I did not run cloud E2E tests or the macOS CI job locally.

Checklist

  • PR description included
  • yarn test passes for the changed package
  • Tests are changed or added
  • Relevant documentation is changed or added (and PR referenced)
  • New AWS SDK calls or CloudFormation actions have been added to relevant test and service IAM policies
  • Pull request labels are added

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@w3lld1
w3lld1 requested a review from a team as a code owner July 15, 2026 19:18
…olicy names

The env-specific policy-name suffix read `getEnvInfo().envName` directly. When
env info is absent or blank (uninitialized env / headless / export paths) the
suffix silently became `..._undefined`, which puts every such deployment back on
one shared policy name and re-collides -- the exact bug this change fixes -- or
threw an opaque error on a path that previously succeeded.

Read the env name once and validate it: fail fast with a clear
`EnvironmentNotInitializedError` when it is missing or empty, so names never
degrade to a shared `_undefined` suffix.

Adds a regression test covering the missing-envName case alongside the existing
happy-path test.
@sharonyajain
sharonyajain requested a review from sarayev August 24, 2026 08:56
…orted auth

Appending the environment name to every S3 IAM policy name renamed the inline
policy for all already-deployed storage apps. PolicyName is replace-on-update for
AWS::IAM::Policy, so the next push after upgrading would force a policy
replacement on every existing environment -- churn and risk well beyond the
shared-role collision this fixes, and it hit apps that never had the problem.

The collision only occurs when the auth/unauth IAM roles are shared across
environments, which is the imported Cognito Identity Pool case. Gate the
`_${envName}` suffix on imported auth (detected from project meta): managed-auth
apps keep the legacy env-agnostic name and see no policy replacement on upgrade,
while imported-auth environments -- whose deploys are already failing -- get the
unique per-env name. The missing-envName fail-fast now applies only on the
imported path.

Adds a regression test asserting managed auth keeps the legacy names, alongside
the imported happy-path and imported missing-envName tests.
@sharonyajain
sharonyajain requested a review from sarayev August 24, 2026 13:20

@sarayev sarayev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick turnaround, both of my concerns are addressed nicely.

Gating the suffix on imported auth is exactly the backward-compatible shape I was hoping for: managed-auth apps keep the legacy name and see no policy replacement on upgrade, and only the shared-role environments (whose deploys are already failing) get the env-scoped name. Scoping the fail-fast to the imported path and tracing the callers to confirm envName is always present there also resolves the export/headless worry. The three tests (imported gets the suffix, managed keeps the legacy name, imported + blank env throws) lock the behavior in well. Looks good to me.

Left one small nit inline on the $TSAny cast, non-blocking.

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.

Storage deploy fails with 'Policy resource was already managed by another stack' after CFN enforcement change (Jan 2026)

3 participants