Page updated Jan 16, 2024

File access levels

Storage module can manage files with three different access levels; guest, protected and private. The Amplify CLI configures three different access levels on the storage bucket: guest, protected and private. When you run amplify add storage, the CLI will configure appropriate IAM policies on the bucket using a Cognito identity pool Role. You will have the option of adding CRUD (Create/Update, Read and Delete) based permissions as well, so that Authenticated and Guest users will be granted limited permissions within these levels.

If you had previously enabled user sign-in by running amplify add auth in your project, the policies will be connected to an Authenticated Role of the identity pool which has scoped permission to the objects in the bucket for each user identity. If you haven't configured user sign-in, then an Unauthenticated Role will be assigned for each unique user/device combination, which still has scoped permissions to just their objects.

  • Guest: Accessible by all users of your app. Files are stored under the public/ path in your S3 bucket.
  • Protected: Readable by all users, but writable only by the creating user. Files are stored under protected/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.
  • Private: Only accessible for the individual user. Files are stored under private/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.

When using Auth and Storage modules together, you do not need to construct the /{user_identity_id}/ manually as the library will use the configured Cognito Identity ID for your user/device along with the configured access level for an action. This includes UnAuthenticated access where you will first call Auth.currentCredentials() before a Storage action. See Authentication for more information.

The access level can be configured on the Storage object globally. Alternatively, the access levels can be set in individual function calls.

Default access level for Storage module is guest. Unless you configure Storage otherwise, all uploaded files will be publicly available for all users.

Access level configuration on the Storage object:

import { getUrl } from 'aws-amplify/storage'; await getUrl({ key: 'welcome.png', options: { level: 'guest' } }); // Gets welcome.png in public space
1import { getUrl } from 'aws-amplify/storage';
2
3await getUrl({ key: 'welcome.png', options: { level: 'guest' } }); // Gets welcome.png in public space

The default access level is guest:

import { getUrl } from 'aws-amplify/storage'; await getUrl({ key: 'welcome.png' }); // Get welcome.png in public space
1import { getUrl } from 'aws-amplify/storage';
2
3await getUrl({ key: 'welcome.png' }); // Get welcome.png in public space

Customization

Customize Object Key Path

You can customize your key path by defining a prefix resolver:

import amplifyconfig from './amplifyconfiguration.json'; Amplify.configure(amplifyconfig, { Storage: { S3: { prefixResolver: async ({ accessLevel, targetIdentityId }) => { if (accessLevel === 'guest') { return 'myPublicPrefix/'; } else if (accessLevel === 'protected') { return `myProtectedPrefix/${targetIdentityId}/`; } else { return `myPrivatePrefix/${targetIdentityId}/`; } } } } });
1import amplifyconfig from './amplifyconfiguration.json';
2
3Amplify.configure(amplifyconfig, {
4 Storage: {
5 S3: {
6 prefixResolver: async ({ accessLevel, targetIdentityId }) => {
7 if (accessLevel === 'guest') {
8 return 'myPublicPrefix/';
9 } else if (accessLevel === 'protected') {
10 return `myProtectedPrefix/${targetIdentityId}/`;
11 } else {
12 return `myPrivatePrefix/${targetIdentityId}/`;
13 }
14 }
15 }
16 }
17});

For example, if you want to enable read, write and delete operation for all the objects under path myPublicPrefix/, declare it in your IAM policy:

"Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::your-s3-bucket/myPublicPrefix/*", ] } ]
1"Statement": [
2 {
3 "Effect": "Allow",
4 "Action": [
5 "s3:GetObject",
6 "s3:PutObject",
7 "s3:DeleteObject"
8 ],
9 "Resource": [
10 "arn:aws:s3:::your-s3-bucket/myPublicPrefix/*",
11 ]
12 }
13]

If you want to have custom private path prefix like myPrivatePrefix/, you need to add it into your IAM policy:

"Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::your-s3-bucket/myPrivatePrefix/${cognito-identity.amazonaws.com:sub}/*" ] } ]
1"Statement": [
2 {
3 "Effect": "Allow",
4 "Action": [
5 "s3:GetObject",
6 "s3:PutObject",
7 "s3:DeleteObject"
8 ],
9 "Resource": [
10 "arn:aws:s3:::your-s3-bucket/myPrivatePrefix/${cognito-identity.amazonaws.com:sub}/*"
11 ]
12 }
13]

This ensures only the authenticated users has the access to the objects under the path.