Amplify-cli: [Bug? DX issue?] Cannot access Amplify Storage when authenticated - 403 Access Denied Error results

Created on 23 Oct 2020  ·  16Comments  ·  Source: aws-amplify/amplify-cli

Describe the bug

With the default IAM policies and intuitive CRUD set up via Amplify CLI, I still encounter 403 errors when I try to Storage.list, even when I am authenticated, and even when I have made sure to allow authenticated and guest users inside Amplify CLI.

Here is the error message we get back when trying to Storage.list, from an authenticated user:

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>A050E71568DB969D</RequestId><HostId>nLVBqKHstIbYZwOfGSAQVlKX2b7I2VyXFYumVb9HEf0upQiJGPl+QUZ7iKYXHxc6JnC4PsuNx8E=</HostId></Error>

image

To Reproduce

Steps to reproduce the behavior:

  1. amplify init
  2. amplify add storage
  3. add auth accordingly, with post confirmation trigger with addUserToGroup lambda.
  4. make sure storage allows for authenticated users and guests to read
  5. try to do Storage.list while authenticated, from localhost.

Expected behavior

an authenticated user should be able to read from the s3 bucket, by default, without extra hassle. errors should hint at possible resolution steps rather than just leave us hanging with a 403.

Screenshots



Proof that I have the correct IAM policies set up

image

i have verified that this is the correct user account



Proof that I have set up Amplify Storage for read by authenticated users

image



Proof that my Bucket's CORS policy is as recommended

image



My Amplify Storage generated configs

image

// parameters.json
{
    "bucketName": "demoamplifystoragefiee0ba928066f4f838f174a89245",
    "authPolicyName": "s3_amplify_f13c0061",
    "unauthPolicyName": "s3_amplify_f13c0061",
    "authRoleName": {
        "Ref": "AuthRoleName"
    },
    "unauthRoleName": {
        "Ref": "UnauthRoleName"
    },
    "selectedGuestPermissions": [
        "s3:GetObject",
        "s3:ListBucket"
    ],
    "selectedAuthenticatedPermissions": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:DeleteObject"
    ],
    "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
    "s3PublicPolicy": "Public_policy_0afee245",
    "s3PermissionsAuthenticatedUploads": "s3:PutObject",
    "s3UploadsPolicy": "Uploads_policy_0afee245",
    "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject,s3:DeleteObject",
    "s3ProtectedPolicy": "Protected_policy_8ff96670",
    "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject,s3:DeleteObject",
    "s3PrivatePolicy": "Private_policy_8ff96670",
    "AuthenticatedAllowList": "ALLOW",
    "s3ReadPolicy": "read_policy_0afee245",
    "s3PermissionsGuestPublic": "s3:GetObject",
    "s3PermissionsGuestUploads": "DISALLOW",
    "GuestAllowList": "ALLOW",
    "triggerFunction": "NONE"
}

// s3-cloudformationtemplate.json

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "S3 resource stack creation using Amplify CLI",
    "Parameters": {
        "bucketName": {
            "Type": "String"
        },
        "authPolicyName": {
            "Type": "String"
        },
        "unauthPolicyName": {
            "Type": "String"
        },
        "authRoleName": {
            "Type": "String"
        },
        "unauthRoleName": {
            "Type": "String"
        },
        "s3PublicPolicy": {
            "Type": "String",
            "Default": "NONE"
        },
        "s3PrivatePolicy": {
            "Type": "String",
            "Default": "NONE"
        },
        "s3ProtectedPolicy": {
            "Type": "String",
            "Default": "NONE"
        },
        "s3UploadsPolicy": {
            "Type": "String",
            "Default": "NONE"
        },
        "s3ReadPolicy": {
            "Type": "String",
            "Default": "NONE"
        },
        "s3PermissionsAuthenticatedPublic": {
            "Type": "String",
            "Default": "DISALLOW"
        },
        "s3PermissionsAuthenticatedProtected": {
            "Type": "String",
            "Default": "DISALLOW"
        },
        "s3PermissionsAuthenticatedPrivate": {
            "Type": "String",
            "Default": "DISALLOW"
        },
        "s3PermissionsAuthenticatedUploads": {
            "Type": "String",
            "Default": "DISALLOW"
        },
        "s3PermissionsGuestPublic": {
            "Type": "String",
            "Default": "DISALLOW"
        },
        "s3PermissionsGuestUploads": {
            "Type": "String",
            "Default": "DISALLOW"
        },
        "AuthenticatedAllowList": {
            "Type": "String",
            "Default": "DISALLOW"
        },
        "GuestAllowList": {
            "Type": "String",
            "Default": "DISALLOW"
        },
        "selectedGuestPermissions": {
            "Type": "CommaDelimitedList",
            "Default": "NONE"
        },
        "selectedAuthenticatedPermissions": {
            "Type": "CommaDelimitedList",
            "Default": "NONE"
        },
        "env": {
            "Type": "String"
        },
        "triggerFunction": {
            "Type": "String"
        },
        "authdemoamplifystoragefi245f7a4d245f7a4dUserPoolId": {
            "Type": "String",
            "Default": "authdemoamplifystoragefi245f7a4d245f7a4dUserPoolId"
        },
        "authuserPoolGroupsAdminsGroupRole": {
            "Type": "String",
            "Default": "authuserPoolGroupsAdminsGroupRole"
        },
        "authuserPoolGroupsEditorsGroupRole": {
            "Type": "String",
            "Default": "authuserPoolGroupsEditorsGroupRole"
        }
    },
    "Conditions": {
        "ShouldNotCreateEnvResources": {
            "Fn::Equals": [
                {
                    "Ref": "env"
                },
                "NONE"
            ]
        },
        "CreateAuthPublic": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "s3PermissionsAuthenticatedPublic"
                        },
                        "DISALLOW"
                    ]
                }
            ]
        },
        "CreateAuthProtected": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "s3PermissionsAuthenticatedProtected"
                        },
                        "DISALLOW"
                    ]
                }
            ]
        },
        "CreateAuthPrivate": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "s3PermissionsAuthenticatedPrivate"
                        },
                        "DISALLOW"
                    ]
                }
            ]
        },
        "CreateAuthUploads": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "s3PermissionsAuthenticatedUploads"
                        },
                        "DISALLOW"
                    ]
                }
            ]
        },
        "CreateGuestPublic": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "s3PermissionsGuestPublic"
                        },
                        "DISALLOW"
                    ]
                }
            ]
        },
        "CreateGuestUploads": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "s3PermissionsGuestUploads"
                        },
                        "DISALLOW"
                    ]
                }
            ]
        },
        "AuthReadAndList": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "AuthenticatedAllowList"
                        },
                        "DISALLOW"
                    ]
                }
            ]
        },
        "GuestReadAndList": {
            "Fn::Not": [
                {
                    "Fn::Equals": [
                        {
                            "Ref": "GuestAllowList"
                        },
                        "DISALLOW"
                    ]
                }
            ]
        }
    },
    "Resources": {
        "S3Bucket": {
            "Type": "AWS::S3::Bucket",
            "DeletionPolicy": "Retain",
            "Properties": {
                "BucketName": {
                    "Fn::If": [
                        "ShouldNotCreateEnvResources",
                        {
                            "Ref": "bucketName"
                        },
                        {
                            "Fn::Join": [
                                "",
                                [
                                    {
                                        "Ref": "bucketName"
                                    },
                                    {
                                        "Fn::Select": [
                                            3,
                                            {
                                                "Fn::Split": [
                                                    "-",
                                                    {
                                                        "Ref": "AWS::StackName"
                                                    }
                                                ]
                                            }
                                        ]
                                    },
                                    "-",
                                    {
                                        "Ref": "env"
                                    }
                                ]
                            ]
                        }
                    ]
                },
                "CorsConfiguration": {
                    "CorsRules": [
                        {
                            "AllowedHeaders": [
                                "*"
                            ],
                            "AllowedMethods": [
                                "GET",
                                "HEAD",
                                "PUT",
                                "POST",
                                "DELETE"
                            ],
                            "AllowedOrigins": [
                                "*"
                            ],
                            "ExposedHeaders": [
                                "x-amz-server-side-encryption",
                                "x-amz-request-id",
                                "x-amz-id-2",
                                "ETag"
                            ],
                            "Id": "S3CORSRuleId1",
                            "MaxAge": "3000"
                        }
                    ]
                }
            }
        },
        "AdminsGroupPolicy": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": "Admins-group-s3-policy",
                "Roles": [
                    {
                        "Fn::Join": [
                            "",
                            [
                                {
                                    "Ref": "authdemoamplifystoragefi245f7a4d245f7a4dUserPoolId"
                                },
                                "-AdminsGroupRole"
                            ]
                        ]
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "s3:PutObject",
                                "s3:GetObject",
                                "s3:ListBucket",
                                "s3:DeleteObject"
                            ],
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/*"
                                        ]
                                    ]
                                }
                            ]
                        },
                        {
                            "Effect": "Allow",
                            "Action": "s3:ListBucket",
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            }
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "S3AuthPublicPolicy": {
            "DependsOn": [
                "S3Bucket"
            ],
            "Condition": "CreateAuthPublic",
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": {
                    "Ref": "s3PublicPolicy"
                },
                "Roles": [
                    {
                        "Ref": "authRoleName"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": {
                                "Fn::Split": [
                                    ",",
                                    {
                                        "Ref": "s3PermissionsAuthenticatedPublic"
                                    }
                                ]
                            },
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/public/*"
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "S3AuthProtectedPolicy": {
            "DependsOn": [
                "S3Bucket"
            ],
            "Condition": "CreateAuthProtected",
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": {
                    "Ref": "s3ProtectedPolicy"
                },
                "Roles": [
                    {
                        "Ref": "authRoleName"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": {
                                "Fn::Split": [
                                    ",",
                                    {
                                        "Ref": "s3PermissionsAuthenticatedProtected"
                                    }
                                ]
                            },
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/protected/${cognito-identity.amazonaws.com:sub}/*"
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "S3AuthPrivatePolicy": {
            "DependsOn": [
                "S3Bucket"
            ],
            "Condition": "CreateAuthPrivate",
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": {
                    "Ref": "s3PrivatePolicy"
                },
                "Roles": [
                    {
                        "Ref": "authRoleName"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": {
                                "Fn::Split": [
                                    ",",
                                    {
                                        "Ref": "s3PermissionsAuthenticatedPrivate"
                                    }
                                ]
                            },
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/private/${cognito-identity.amazonaws.com:sub}/*"
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "S3AuthUploadPolicy": {
            "DependsOn": [
                "S3Bucket"
            ],
            "Condition": "CreateAuthUploads",
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": {
                    "Ref": "s3UploadsPolicy"
                },
                "Roles": [
                    {
                        "Ref": "authRoleName"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": {
                                "Fn::Split": [
                                    ",",
                                    {
                                        "Ref": "s3PermissionsAuthenticatedUploads"
                                    }
                                ]
                            },
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/uploads/*"
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "S3AuthReadPolicy": {
            "DependsOn": [
                "S3Bucket"
            ],
            "Condition": "AuthReadAndList",
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": {
                    "Ref": "s3ReadPolicy"
                },
                "Roles": [
                    {
                        "Ref": "authRoleName"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "s3:GetObject"
                            ],
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/protected/*"
                                        ]
                                    ]
                                }
                            ]
                        },
                        {
                            "Effect": "Allow",
                            "Action": [
                                "s3:ListBucket"
                            ],
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            }
                                        ]
                                    ]
                                }
                            ],
                            "Condition": {
                                "StringLike": {
                                    "s3:prefix": [
                                        "public/",
                                        "public/*",
                                        "protected/",
                                        "protected/*",
                                        "private/${cognito-identity.amazonaws.com:sub}/",
                                        "private/${cognito-identity.amazonaws.com:sub}/*"
                                    ]
                                }
                            }
                        }
                    ]
                }
            }
        },
        "S3GuestPublicPolicy": {
            "DependsOn": [
                "S3Bucket"
            ],
            "Condition": "CreateGuestPublic",
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": {
                    "Ref": "s3PublicPolicy"
                },
                "Roles": [
                    {
                        "Ref": "unauthRoleName"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": {
                                "Fn::Split": [
                                    ",",
                                    {
                                        "Ref": "s3PermissionsGuestPublic"
                                    }
                                ]
                            },
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/public/*"
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "S3GuestUploadPolicy": {
            "DependsOn": [
                "S3Bucket"
            ],
            "Condition": "CreateGuestUploads",
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": {
                    "Ref": "s3UploadsPolicy"
                },
                "Roles": [
                    {
                        "Ref": "unauthRoleName"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": {
                                "Fn::Split": [
                                    ",",
                                    {
                                        "Ref": "s3PermissionsGuestUploads"
                                    }
                                ]
                            },
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/uploads/*"
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        },
        "S3GuestReadPolicy": {
            "DependsOn": [
                "S3Bucket"
            ],
            "Condition": "GuestReadAndList",
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": {
                    "Ref": "s3ReadPolicy"
                },
                "Roles": [
                    {
                        "Ref": "unauthRoleName"
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "s3:GetObject"
                            ],
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/protected/*"
                                        ]
                                    ]
                                }
                            ]
                        },
                        {
                            "Effect": "Allow",
                            "Action": [
                                "s3:ListBucket"
                            ],
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            }
                                        ]
                                    ]
                                }
                            ],
                            "Condition": {
                                "StringLike": {
                                    "s3:prefix": [
                                        "public/",
                                        "public/*",
                                        "protected/",
                                        "protected/*"
                                    ]
                                }
                            }
                        }
                    ]
                }
            }
        },
        "EditorsGroupPolicy": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "PolicyName": "Editors-group-s3-policy",
                "Roles": [
                    {
                        "Fn::Join": [
                            "",
                            [
                                {
                                    "Ref": "authdemoamplifystoragefi245f7a4d245f7a4dUserPoolId"
                                },
                                "-EditorsGroupRole"
                            ]
                        ]
                    }
                ],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "s3:PutObject",
                                "s3:GetObject",
                                "s3:ListBucket",
                                "s3:DeleteObject"
                            ],
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            },
                                            "/*"
                                        ]
                                    ]
                                }
                            ]
                        },
                        {
                            "Effect": "Allow",
                            "Action": "s3:ListBucket",
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "S3Bucket"
                                            }
                                        ]
                                    ]
                                }
                            ]
                        }
                    ]
                }
            }
        }
    },
    "Outputs": {
        "BucketName": {
            "Value": {
                "Ref": "S3Bucket"
            },
            "Description": "Bucket name for the S3 bucket"
        },
        "Region": {
            "Value": {
                "Ref": "AWS::Region"
            }
        }
    }
}

// storage-params.json

{
    "groupPermissionMap": {
        "Admins": [
            "create/update",
            "read",
            "delete"
        ],
        "Editors": [
            "create/update",
            "read",
            "delete"
        ]
    }
}

// amplify-meta.json

{
    "providers": {
        "awscloudformation": {
            "AuthRoleName": "amplify-demoamplifystoragefi-dev-233324-authRole",
            "UnauthRoleArn": "arn:aws:iam::754933769358:role/amplify-demoamplifystoragefi-dev-233324-unauthRole",
            "AuthRoleArn": "arn:aws:iam::754933769358:role/amplify-demoamplifystoragefi-dev-233324-authRole",
            "Region": "us-east-1",
            "DeploymentBucketName": "amplify-demoamplifystoragefi-dev-233324-deployment",
            "UnauthRoleName": "amplify-demoamplifystoragefi-dev-233324-unauthRole",
            "StackName": "amplify-demoamplifystoragefi-dev-233324",
            "StackId": "arn:aws:cloudformation:us-east-1:754933769358:stack/amplify-demoamplifystoragefi-dev-233324/f0647360-147b-11eb-9f8e-1266e578c117",
            "AmplifyAppId": "d26phrorfenghy"
        }
    },
    "function": {
        "demoamplifystoragefi245f7a4d245f7a4dPostConfirmation": {
            "build": true,
            "providerPlugin": "awscloudformation",
            "service": "Lambda",
            "lastBuildTimeStamp": "2020-10-23T13:40:30.674Z",
            "lastPackageTimeStamp": "2020-10-23T13:40:30.802Z",
            "distZipFilename": "demoamplifystoragefi245f7a4d245f7a4dPostConfirmation-684d47596c65656e4879-build.zip",
            "providerMetadata": {
                "s3TemplateURL": "https://s3.amazonaws.com/amplify-demoamplifystoragefi-dev-233324-deployment/amplify-cfn-templates/function/demoamplifystoragefi245f7a4d245f7a4dPostConfirmation-cloudformation-template.json",
                "logicalId": "functiondemoamplifystoragefi245f7a4d245f7a4dPostConfirmation"
            },
            "lastPushTimeStamp": "2020-10-23T13:41:47.288Z",
            "output": {
                "Region": "us-east-1",
                "Arn": "arn:aws:lambda:us-east-1:754933769358:function:demoamplifystoragefi245f7a4d245f7a4dPostConfirmation-dev",
                "Name": "demoamplifystoragefi245f7a4d245f7a4dPostConfirmation-dev",
                "LambdaExecutionRole": "demoamplifystoragefi245f7a4d245f7a4dPostConfirmation-dev"
            },
            "lastPushDirHash": "5kzE/TmqgwJU42+MZdJKNp9kwro="
        }
    },
    "auth": {
        "userPoolGroups": {
            "service": "Cognito-UserPool-Groups",
            "providerPlugin": "awscloudformation",
            "dependsOn": [
                {
                    "category": "auth",
                    "resourceName": "demoamplifystoragefi245f7a4d245f7a4d",
                    "attributes": [
                        "UserPoolId",
                        "AppClientIDWeb",
                        "AppClientID",
                        "IdentityPoolId"
                    ]
                }
            ],
            "providerMetadata": {
                "s3TemplateURL": "https://s3.amazonaws.com/amplify-demoamplifystoragefi-dev-233324-deployment/amplify-cfn-templates/auth/template.json",
                "logicalId": "authuserPoolGroups"
            },
            "lastPushTimeStamp": "2020-10-23T13:41:47.284Z",
            "output": {
                "EditorsGroupRole": "arn:aws:iam::754933769358:role/us-east-1_K46M3jXll-EditorsGroupRole",
                "AdminsGroupRole": "arn:aws:iam::754933769358:role/us-east-1_K46M3jXll-AdminsGroupRole"
            },
            "lastPushDirHash": "MZremj+dNZq+SZN6XNSfoavA9xQ="
        },
        "demoamplifystoragefi245f7a4d245f7a4d": {
            "service": "Cognito",
            "providerPlugin": "awscloudformation",
            "dependsOn": [
                {
                    "category": "function",
                    "resourceName": "demoamplifystoragefi245f7a4d245f7a4dPostConfirmation",
                    "triggerProvider": "Cognito",
                    "attributes": [
                        "Arn",
                        "Name"
                    ]
                }
            ],
            "providerMetadata": {
                "s3TemplateURL": "https://s3.amazonaws.com/amplify-demoamplifystoragefi-dev-233324-deployment/amplify-cfn-templates/auth/demoamplifystoragefi245f7a4d245f7a4d-cloudformation-template.yml",
                "logicalId": "authdemoamplifystoragefi245f7a4d245f7a4d"
            },
            "lastPushTimeStamp": "2020-10-23T13:41:47.285Z",
            "output": {
                "AppClientSecret": "v7727g5vei60ri5jse1c8l8n2k6di131gvr765fg3kbqlg257k4",
                "UserPoolId": "us-east-1_K46M3jXll",
                "AppClientIDWeb": "12d2bft1ksj4s9b19feglscktu",
                "AppClientID": "1jab2djdenjrarerekhulen74f",
                "IdentityPoolId": "us-east-1:8ae2bc43-6513-45a6-9f92-3bf275842862",
                "IdentityPoolName": "demoamplifystoragefi245f7a4d_identitypool_245f7a4d__dev",
                "UserPoolName": "demoamplifystoragefi245f7a4d_userpool_245f7a4d"
            },
            "lastPushDirHash": "Lzs+2p4bemGYVvHYgwBSiuLkp7U="
        }
    },
    "storage": {
        "s3f13c0061": {
            "service": "S3",
            "providerPlugin": "awscloudformation",
            "dependsOn": [
                {
                    "category": "auth",
                    "resourceName": "demoamplifystoragefi245f7a4d245f7a4d",
                    "attributes": [
                        "UserPoolId"
                    ]
                },
                {
                    "category": "auth",
                    "resourceName": "userPoolGroups",
                    "attributes": [
                        "AdminsGroupRole"
                    ]
                },
                {
                    "category": "auth",
                    "resourceName": "userPoolGroups",
                    "attributes": [
                        "EditorsGroupRole"
                    ]
                }
            ],
            "providerMetadata": {
                "s3TemplateURL": "https://s3.amazonaws.com/amplify-demoamplifystoragefi-dev-233324-deployment/amplify-cfn-templates/storage/s3-cloudformation-template.json",
                "logicalId": "storages3f13c0061"
            },
            "lastPushTimeStamp": "2020-10-23T14:40:29.489Z",
            "output": {
                "BucketName": "demoamplifystoragefiee0ba928066f4f838f174a89245233324-dev",
                "Region": "us-east-1"
            },
            "lastPushDirHash": "GmQRS1cetVyrPMcRPNQrZn8q2fw="
        }
    }
}

// backend-config.json

{
    "function": {
        "demoamplifystoragefi245f7a4d245f7a4dPostConfirmation": {
            "build": true,
            "providerPlugin": "awscloudformation",
            "service": "Lambda"
        }
    },
    "auth": {
        "userPoolGroups": {
            "service": "Cognito-UserPool-Groups",
            "providerPlugin": "awscloudformation",
            "dependsOn": [
                {
                    "category": "auth",
                    "resourceName": "demoamplifystoragefi245f7a4d245f7a4d",
                    "attributes": [
                        "UserPoolId",
                        "AppClientIDWeb",
                        "AppClientID",
                        "IdentityPoolId"
                    ]
                }
            ]
        },
        "demoamplifystoragefi245f7a4d245f7a4d": {
            "service": "Cognito",
            "providerPlugin": "awscloudformation",
            "dependsOn": [
                {
                    "category": "function",
                    "resourceName": "demoamplifystoragefi245f7a4d245f7a4dPostConfirmation",
                    "triggerProvider": "Cognito",
                    "attributes": [
                        "Arn",
                        "Name"
                    ]
                }
            ]
        }
    },
    "storage": {
        "s3f13c0061": {
            "service": "S3",
            "providerPlugin": "awscloudformation",
            "dependsOn": [
                {
                    "category": "auth",
                    "resourceName": "demoamplifystoragefi245f7a4d245f7a4d",
                    "attributes": [
                        "UserPoolId"
                    ]
                },
                {
                    "category": "auth",
                    "resourceName": "userPoolGroups",
                    "attributes": [
                        "AdminsGroupRole"
                    ]
                },
                {
                    "category": "auth",
                    "resourceName": "userPoolGroups",
                    "attributes": [
                        "EditorsGroupRole"
                    ]
                }
            ]
        }
    }
}

What is Configured?
If applicable, please provide what is configured for Amplify CLI:

  • Which steps did you follow via Amplify CLI when configuring your resources.
  • Which resources do you have configured?

    • If applicable, please provide your aws-exports file:

      const awsmobile = { "aws_project_region": "us-east-1", "aws_cognito_identity_pool_id": "us-east-1:8ae2bc43-6513-45a6-9f92-3bf275842862", "aws_cognito_region": "us-east-1", "aws_user_pools_id": "us-east-1_K46M3jXll", "aws_user_pools_web_client_id": "12d2bft1ksj4s9b19feglscktu", "oauth": {}, "aws_user_files_s3_bucket": "demoamplifystoragefiee0ba928066f4f838f174a89245233324-dev", "aws_user_files_s3_bucket_region": "us-east-1" };


Environment


  System:
    OS: macOS Mojave 10.14.6
    CPU: (8) x64 Intel(R) Core(TM) i7-8569U CPU @ 2.80GHz
    Memory: 244.01 MB / 16.00 GB
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 12.18.0 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.7 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Browsers:
    Chrome: 86.0.4240.111
    Firefox: 68.11.0
    Safari: 14.0
  npmPackages:
    @aws-amplify/auth: ^3.4.6 => 3.4.7 
    @tailwindcss/ui: ^0.6.2 => 0.6.2 
    autoprefixer: ^10.0.1 => 10.0.1 
    aws-amplify: ^3.3.3 => 3.3.4 
    cross-env: ^5.2.0 => 5.2.1 
    css-loader: ^2.1.1 => 2.1.1 
    mini-css-extract-plugin: ^0.6.0 => 0.6.0 
    postcss-nesting: ^7.0.1 => 7.0.1 
    serve: ^11.0.0 => 11.3.2 
    style-loader: ^0.23.1 => 0.23.1 
    svelte: ^3.0.0 => 3.29.0 
    svelte-loader: 2.13.3 => 2.13.3 
    svelte-preprocess: ^4.5.1 => 4.5.1 
    tailwindcss: ^1.8.12 => 1.9.5 
    webpack: ^4.30.0 => 4.44.2 
    webpack-cli: ^3.3.0 => 3.3.12 
    webpack-dev-server: ^3.3.1 => 3.11.0 
  npmGlobalPackages:
    @11ty/eleventy: 0.11.0
    @aws-amplify/cli: 4.26.1-flutter-preview.0
    @prisma/cli: 2.6.1
    aws-cdk: 1.63.0
    diff-so-fancy: 1.3.0
    expo-cli: 3.21.5
    generator-code: 1.2.19
    netlify-cli: 2.53.0
    npm: 6.14.7
    vsce: 1.77.0
    yo: 3.1.1

bug storage

Most helpful comment

Possibly related issue: https://github.com/aws-amplify/amplify-js/issues/7076 this may be a regression on Cognito side?

All 16 comments

possible related issues:

image

  • suggestion from @kaustavghosh06: There's a user group here - make sure the user is assigned to a group, and make sure the group has the correct permissions (swyx: yes, I have checked this)

i've read through all these but don't know enough to understand if they apply to my situation or not. as far as I can tell I have ruled them out but I am not sure.

@sw-yx

I did the same steps you mentioned and with unauthenticated users I was able to list the objects.

import React from 'react';
import logo from './logo.svg';
import './App.css';
import { Amplify } from 'aws-amplify';
import awsconfig from './aws-exports';
import { Storage } from '@aws-amplify/storage';
import {  } from "module";
Amplify.configure(awsconfig);

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <button onClick={list}>list files</button>
      </header>
    </div>
  );

  async function list() {
    const files = await Storage.list('');

    alert(JSON.stringify(files, null, 2));
  }
}

export default App;

What were your auth settings?

thanks @elorzafe, but i think you may not have read my issue closely. i also have no problem when unauthenticated. thats not the issue i filed (check the title). i wrote my repro steps above!

i had briefly communicated with Richard about this, who also discussed it with @kaustavghosh06. i think @dabit3 may have encountered this before as well. i havent been able to break through this for the past 2 weeks, so it has hampered my ability to ship a demo of Amplify Storage with authenticated users.

Possibly related issue: https://github.com/aws-amplify/amplify-js/issues/7076 this may be a regression on Cognito side?

Hi @sw-yx, I was not able to reproduce this issue with the latest Amplify (aws-amplify: "3.3.7"). I could call Storage.list after I signed in with AmplifyAuthenticator post sign-in, and I used the resources auto-generated by the CLI. I could also confirm that the AdminsGroupRole was referenced successfully when I ran the sample app.

Just to make sure we are on the same page, can you confirm that this is still happening on your app with the latest Amplify and cli? It seems like other customers are experiencing this issue, but I haven't been able to reproduce it yet.

my Amplify CLI inputs fyi:


Auth Configuration

 Do you want to use the default authentication and security configuration? Manual config
uration
 Select the authentication/authorization services that you want to use: User Sign-Up & S
ign-In only (Best used with a cloud API only)
 Please provide a friendly name for your resource that will be used to label this catego
ry in the project: storageappauth64c3a96064c3a960
 Please provide a name for your user pool: storageappauth64c3a960_userpool_64c3a960
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Username
 Do you want to add User Pool Groups? Yes
? Provide a name for your user pool group: Admins
? Do you want to add another User Pool Group No
✔ Sort the user pool groups in order of preference · Admins Do you want to add an admin queries API? No
 Multifactor authentication (MFA) user login options: OFF
 Email based user registration/forgot password: Enabled (Requires per-user email entry a
t registration)
 Please specify an email verification subject: Your verification code
 Please specify an email verification message: Your verification code is {####}
 Do you want to override the default password policy for this User Pool? No
 Warning: you will not be able to edit these selections. 
 Warning: you will not be able to edit these selections. 
 What attributes are required for signing up? Email
 Specify the app's refresh token expiration period (in days): 30
 Do you want to specify the user attributes this app can read and write? No
 Do you want to enable any of the following capabilities? Add User to Group
 Do you want to use an OAuth flow? No
? Do you want to configure Lambda Triggers for Cognito? Yes
? Which triggers do you want to enable for Cognito Post Confirmation
? What functionality do you want to use for Post Confirmation Add User To Group
? Enter the name of the group to which users will be added. Admins
Successfully added resource storageappauth64c3a96064c3a960PostConfirmation locally.


Storage Configuration

? Please select from one of the below mentioned services: Content (Images, audio, video,
 etc.)
? Restrict access by? Both
? Who should have access: Auth and guest users
? What kind of access do you want for Authenticated users? create/update, read, delete
? What kind of access do you want for Guest users? read
? Select groups: Admins
? What kind of access do you want for Admins users? create/update, read, delete
? Do you want to add a Lambda Trigger for your S3 Bucket? No

hey @wlee221, i followed your instructions to the letter and could still replicate. please have a look: https://youtu.be/1wG4ImyUi50

@sw-yx, thank you! these videos help tremendously in reproducing issues. I'll retry this week and let you know how it goes. ps. sorry about the manual auth setup, I assumed you did also :D

Update: I was able to repro this now, thanks. I'll bring this up in the bug bash today.

AWESOME so glad you can repro!

Hi, I investigated a bit further. Lambda works as expected and adds the Admins groups upon account creation. But Storage.list fails with 403 although Admins have proper permission in storage-params.json:

{
    "groupPermissionMap": {
        "Admins": [
            "create/update",
            "read",
            "delete"
        ]
    }
}

I'll transfer this issue to amplify-cli as this seems to be a bug in provisioning proper IAM access. If it helps, I have the reproduction repo at link.

@sw-yx : To give some background, this only happens when groups are used and users are member of a group. The root cause is that ListBucket policy was applied for child objects but on on the bucket. If you run update storage that code path covered it and added the missing permissions. Without Groups it was working correctly.

On the JS side:

const rootFiles = await Storage.list('');

This will default to public prefix, so by default the root files cannot be listed, see here.

To list the root files as well you've to provide a customPrefix for the given operations (or all, and handle the path part yourself) like this:

 const rootFiles = await Storage.list('', { customPrefix: { public: '' }});

5806 fixes this.

Thanks @attilah!

@wlee221 perhaps it would worth a paragraph in the Amplify JS docs that for root items this is the escape hatch?

i greatly appreciate both of you taking the time to look into this! good spot with the policies.

you are saying that this problem only exists at the root, but there is a chance that i also faced this problem when inside a subfolder or inside the "/public" folder as well. i will need to doublecheck and report back if this is the case.

CLI parts:

  1. with current CLI if you create storage but NOT creating the user groups thing, it will work.
  2. with current CLI if you create storage with user groups and after add storage you run an update storage, it will correct the policies.

JS parts:
That is just how AmplifyJS works as it is opiniated, so if you need root you need to use that escape hatch of override. using '' or `'public/' is the same by default.

this was awesome, thanks everyone for your help 👍🏽

Was this page helpful?
0 / 5 - 0 ratings