Skip to content

Problem with doing an S3 list on Amplify G2

0

I have an app where I am using S3 storage. My storage resource.ts is: import { defineStorage } from '@aws-amplify/backend';

export const storage = defineStorage({ name: 'React_Photo2', access: (allow) => ({ 'public/*': [

allow.guest.to(['read']),allow.authenticated.to(['read','write','delete']) ], 'private/*': [ allow.authenticated.to(['read','write','delete']) ], });

I am getting the following error when I run my app trying to do a list on my S3 bucket: Error listing albums: AccessDenied: User: arn:aws:sts::328276666436:assumed-role/React_Photo2/CognitoIdentityCredentials is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::amplify-d2ywylvgrt997m-ma-reactphoto2bucket9055036-6s7g3ownnzl0" because no identity-based policy allows the s3:ListBucket action at async fetchAlbums (PhotoAlbum.js:184:1)

Both ChatGPT 4o and MS CoPilot suggested adding a list parameter to the allow.authenticated.to such as:

import { defineStorage } from '@aws-amplify/backend';

export const storage = defineStorage({ name: 'React_Photo2', access: (allow) => ({ // Bucket-level access for listing 'public/*': [ allow.guest.to(['list']), // bucket-level allow.authenticated.to(['list']), // bucket-level ],

// Object-level access
'public/*': [
  allow.guest.to(['read']), // object-level
  allow.authenticated.to(['read', 'write', 'delete']), // object-level
],

'private/*': [
  allow.authenticated.to(['list']), // bucket-level
],
'private/*': [
  allow.authenticated.to(['read', 'write', 'delete']), // object-level
],

}), });

I have always got a syntax error from Amplify saying I cannot when I try to do this.

TS2345: Argument of type '("read" | "list")[]' is not assignable to parameter of type '("read" | "write" | "delete")[] | ("get" | "list" | "write" | "delete")[]'. Type '("read" | "list")[]' is not assignable to type '("read" | "write" | "delete")[]'.

I have tried other iterations of adding the list. What is the correct way to fix? Is there some unrelated attribute or permissions that I need to change?

asked a year ago234 views

3 Answers
0

The error you're encountering is related to permissions for listing S3 buckets in Amplify Gen2. The issue is that the list permission needs to be properly configured in your storage definition.

In Amplify Gen2, the permission model is slightly different from what ChatGPT and Copilot suggested. The correct way to add listing permissions is to use the proper permission types that Amplify Gen2 supports.

Try modifying your storage definition like this:

import { defineStorage } from '@aws-amplify/backend';

export const storage = defineStorage({
name: 'React_Photo2',
access: (allow) => ({
'public': [
allow.guest.to(['read']),
allow.authenticated.to(['read', 'list'])
],
'public/*': [
allow.guest.to(['read']),
allow.authenticated.to(['read', 'write', 'delete'])
],
'private': [
allow.authenticated.to(['read', 'list'])
],
'private/*': [
allow.authenticated.to(['read', 'write', 'delete'])
]
})
});

The key difference is separating the bucket-level permissions ('public' and 'private') from the object-level permissions ('public/*' and 'private/*'). The list operation is a bucket-level permission, while read, write, and delete can be applied at both levels.

Another thing to check is if your user belongs to any groups. If your user is part of a group (like "admin"), you need to explicitly grant that group permissions as well. For example, if your user is in an "admin" group, you would need to add:

allow.groups(["admin"]).to(["read", "list"])

to your bucket-level permissions to ensure the user can list objects in the bucket.

If you're still experiencing issues after making these changes, check that your IAM role has the necessary permissions for S3 bucket operations, particularly s3:ListBucket.
Sources
Issue with amplify gen2 file upload using Storage: access denied | AWS re:Post
Authorization on S3 assignment | AWS re:Post
Amplify : CredentialProvider Error , with correct policies attached | AWS re:Post

answered a year ago

  • Cutting and pasting the resource.ts above still gives the same error when I try to git push the amplify app: [INFO]: [SyntaxError] TypeScript validation check failed. Resolution: Fix the syntax and type errors in your backend definition. Details: amplify/storage/resource.ts:10:28 - error TS2345: Argument of type '("read" | "list")[]' is not assignable to parameter of type '("read" | "write" | "delete")[] | ("get" | "list" | "write" | "delete")[]'. Type '("read" | "list")[]' is not assignable to type '("read" | "write" | "delete")[]'. Type '"read" | "list"' is not assignable to type '"read" | "write" | "delete"'. Type '"list"' is not assignable to type '"read" | "write" | "delete"'. 10 allow.authenticated.to(['read', 'list']) Any other ideas? Is something misconfigured in my app so storage doesn't recognize list?

0

hi,

your app trying to do a list on S3 bucket at bucket level, but your current permission read, write, delete only object level access, need to add List permission.

{
  "Effect": "Allow",
  "Action": [
    "s3:ListBucket"
  ],
  "Resource": "arn:aws:s3:::your-bucket-name"
}

hope this will help,

Best

answered a year ago

  • Still a syntax error: Resolution: Fix the syntax and type errors in your backend definition. Details: amplify/storage/resource.ts:10:28 - error TS2345: Argument of type '("read" | "list")[]' is not assignable to parameter of type '("read" | "write" | "delete")[] | ("get" | "list" | "write" | "delete")[]'. Type '("read" | "list")[]' is not assignable to type '("read" | "write" | "delete")[]'. Type '"read" | "list"' is not assignable to type '"read" | "write" | "delete"'. Type '"list"' is not assignable to type '"read" | "write" | "delete"'. 10 allow.authenticated.to(['read', 'list'])

    Please note that this error occurs during the git push, I have not even had the chance to try running the app. I don't believe the permissions influence this error since they likely only are referenced during runtime but my present permissions are below: { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "", "Action": "s3:ListBucket", "Resource": "REDACTED" }, { "Effect": "Allow", "Principal": "", "Action": "s3:GetObject", "Resource": "REDACTED"

0

hi again,

in your code, it looks like 'private/*' is defined twice, means it is overwriting the first one.

In Amplify Gen 2, bucket-level vs object-level paths are separated using /*:

Bucket-level (no /*) like **list **that apply to the bucket.

Object-level (with /*) like **read, write, delete **that apply to objects.

Like, re:post agent listed.

https://docs.amplify.aws/react/build-a-backend/storage/authorization/

so, combine them for ease:

'private/*': [
  allow.authenticated.to(['list']),               // bucket-level
  allow.authenticated.to(['read', 'write', 'delete']), // object-level
],

hope this help,

Best

answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.