aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 821 forks source link

Amplify PR environments override S3 access policies for the `Authenticated role` in an imported Identity Pool #10098

Open agrantdeakin opened 2 years ago

agrantdeakin commented 2 years ago

Before opening, please confirm:

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

v16.9.1

Amplify CLI Version

7.6.25

What operating system are you using?

macOS 12.2.1 (21D62)

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

No. We use imported Cognito User and Identity Pools.

Amplify Categories

auth, storage

Amplify Commands

Not applicable

Describe the bug

Amplify PR environments override S3 access policies for the Authenticated role in an imported Identity Pool.

Amplify CLI version: 7.6.25

Amplify replaces the bucket name in all ARNs with the PR env bucket name when creating the PR environments. It should not change the bucket name in the policy but instead append a new item to the "Resource" array.

Policies affected:

Privatepolicy Protectedpolicy Publicpolicy readpolicy Uploadspolicy*

As it is, all PR environments will override the S3 access policies for the imported ID Pools Authenticated role.

Relevant AWS documentation:

https://docs.amplify.aws/cli/auth/import/#import-an-existing-identity-pool

Amplify CLI will update the policies attached to the roles to ensure Amplify categories function correctly. For example, enabling Storage for authenticated & guest users will add private, protected, public, read and upload permissions for the S3 bucket to the unauthenticated & authenticated role.

Expected behavior

It should not change the bucket name in the policy but instead append a new item to the "Resource" array.

Reproduction steps

• Create a User Pool • Create an Identity Pool with the new user pool as an authentication provider. • Run amplify import auth and import the User and ID Pools. • Create a dev environment. • Add storage to the environment and take note of the bucket name. • Require authenticated access to storage. • Push the dev environment. • Turn on PR environments. • Turn on Amplify continuous deployment for the dev environment and perhaps the main branch. • Make some code changes and raise PR in GitHub. • Merge the PR to main. • When the PR environment is created, it will override the bucket name in the imported identity pool's Authenticated role S3 access policies. E.g. it will no longer use the original storage bucket specified when adding storage to Amplify but instead use the bucket created for the PR environment.

GraphQL schema(s)

```graphql # Put schemas below this line ```

Log output

``` # Put your logs below this line ```

Additional information

No response

hico34 commented 2 years ago

I encountered the same issue. We are using the same imported user pool and identity pool for multiple testing environments. When one creates a new environment with the same identity pool, the IAM policies attached to roles granted by the identity pool are overriden, and the old environment does not have access to its S3 bucket anymore.

josefaidt commented 2 years ago

Hey @agrantdeakin :wave: apologies for the delay here!! I was able to successfully reproduce this issue using the provided steps, thank you for those!

akshbhu commented 1 year ago

Hi @agrantdeakin @hico34

It seems like we don't support imported Identity pool sharing in multi envs , as its overriding the BucketName of specific env in the authRole IAM policies when changing env and auth is imported and shared.

Changing this to enhancement and for the workaround, you can use extensibility (overrides feature to append policies to PR Preview env.) https://docs.amplify.aws/cli/storage/override/.

Steps in dev environment: 1) amplify override storage 2) Add the below override code to modify cfn based on env

import { AmplifyProjectInfo, AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyS3ResourceTemplate, amplifyProjectInfo: AmplifyProjectInfo) {
    const devs3ObjectPolicyDocument = {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": {
                                "Fn::Split" : [ "," , {
                                    "Ref": "s3PermissionsAuthenticatedProtected"
                                } ]
                            },
// pr preview env s3 resource
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/protected/${cognito-identity.amazonaws.com:sub}/*"
                                        ]
                                    ]
                                },
// this is my **dev** env s3 bucket resource
"arn:aws:s3:::i1009811d219ddaf50465c8ef0cbc9d95b40b634325-dev/protected/${cognito-identity.amazonaws.com:sub}/*"
                            ]
                        }
                    ]
                }
    // this to be added only is you have  imported userpool  and shared between envs
    if(amplifyProjectInfo.envName !== 'dev'){
        resources.s3AuthPrivatePolicy.policyDocument = {...devs3ObjectPolicyDocument}
    }

}

3) amplify push 4) amplify add env test (pr preview env) 5) amplify push (above override code will append the dev s3 bucket policy in test env)

This will append both bucket resources in authRoleName of imported Identity pool. Like below:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::storagepolicyappend268ce824ac9c54f01a62f2fddd70151932-test/protected/${cognito-identity.amazonaws.com:sub}/*",
                "arn:aws:s3:::i1009811d219ddaf50465c8ef0cbc9d95b40b634325-dev/protected/${cognito-identity.amazonaws.com:sub}/*"
            ],
            "Effect": "Allow"
        }
    ]
}