Page updated Jan 16, 2024

File access levels

Amplify Flutter v0 is now in Maintenance Mode until July 19th, 2024. This means that we will continue to include updates to ensure compatibility with backend services and security. No new features will be introduced in v0.

Please use the latest version (v1) of Amplify Flutter to get started.

If you are currently using v0, follow these instructions to upgrade to v1.

When adding the Storage category, you configure the level of access users have to your S3 bucket. You can configure separate rules for authenticated vs. guest users. When using the Storage category to upload files, you can also specify an access level for each individual file: guest, protected, or private.

  • Guest Accessible by all users of your application
  • Protected Readable by all users, but only writable by the creating user
  • Private Readable and writable only by the creating user

Guest access does not mean that your files are totally public. A "guest" is a user of your application who has not yet signed in. To enable access at this level, you will still be required to configured Authentication in your app. The user must be able to assume an unauthenticated role from your Cognito Identity Pool.

For protected and private access, the [IDENTITY_ID] below corresponds to the unique ID of the user. Once the user has signed in, the [IDENTITY_ID] can be retrieved from the session by accessing the identity id. See Accessing credentials to retrieve the identity id, and use this as the unique ID of the authenticated user.

The default access level for the Storage category is guest. Unless you specify otherwise, all uploaded files will be available to all users of your application. This means that a user who is using your application but has not signed in will have access. Anyone else who is not using your application will not be able to access your files.

Protected access

After the user has signed in, create an options object specifying the protected access level to allow other users to read the object:

1import 'dart:io';
2import 'package:path_provider/path_provider.dart';
3
4Future<void> uploadProtected() async {
5 // Create a dummy file
6 const exampleString = 'Example file contents';
7 final tempDir = await getTemporaryDirectory();
8 final exampleFile = File(tempDir.path + '/example.txt')
9 ..createSync()
10 ..writeAsStringSync(exampleString);
11
12 // Set the access level to `protected` for the current user
13 // Note: A user must be logged in through Cognito Auth
14 // for this to work.
15 final uploadOptions = S3UploadFileOptions(
16 accessLevel: StorageAccessLevel.protected,
17 );
18
19 // Upload the file to S3 with protected access
20 try {
21 final UploadFileResult result = await Amplify.Storage.uploadFile(
22 local: exampleFile,
23 key: 'ExampleKey',
24 options: uploadOptions,
25 onProgress: (progress) {
26 safePrint('Fraction completed: ${progress.getFractionCompleted()}');
27 }
28 );
29 safePrint('Successfully uploaded file: ${result.key}');
30 } on StorageException catch (e) {
31 safePrint('Error uploading protected file: $e');
32 }
33}

This will upload with the prefix /protected/[IDENTITY_ID]/ followed by the key.

For other users to read the file, you must specify the user ID of the creating user in the passed options.

1import 'dart:io';
2import 'package:path_provider/path_provider.dart';
3
4Future<void> downloadProtected(String cognitoIdentityId) async {
5 // Create a file to store downloaded contents
6 final documentsDir = await getApplicationDocumentsDirectory();
7 final filepath = documentsDir.path + '/example.txt';
8 final file = File(filepath);
9
10 // Set access level and Cognito Identity ID.
11 // Note: `targetIdentityId` is only needed when downloading
12 // protected files of a user other than the one currently
13 // logged in.
14 final downloadOptions = S3DownloadFileOptions(
15 accessLevel: StorageAccessLevel.protected,
16
17 // e.g. us-west-2:2f41a152-14d1-45ff-9715-53e20751c7ee
18 targetIdentityId: cognitoIdentityId,
19 );
20
21 // Download protected file and read contents
22 try {
23 await Amplify.Storage.downloadFile(
24 key: 'ExampleKey',
25 local: file,
26 options: downloadOptions,
27 );
28 final contents = file.readAsStringSync();
29 safePrint('Got protected file with contents: $contents');
30 } on StorageException catch (e) {
31 safePrint('Error downloading protected file: $e');
32 }
33}

Private Access

Create an options object specifying the private access level to only allow an object to be accessed by the creating user

1Future<void> uploadPrivateFile() async {
2 ...
3 // Update the uploadOptions
4 final uploadOptions = S3UploadFileOptions(
5 // Add the private access level
6 accessLevel: StorageAccessLevel.private,
7 );
8
9 try {
10 final UploadFileResult result = await Amplify.Storage.uploadFile(
11 ...
12 //Be sure to use the options
13 options: uploadOptions,
14 ...
15 );
16 safePrint('Successfully uploaded file: ${result.key}');
17 }...
18}

This will upload with the prefix /private/[IDENTITY_ID]/, followed by the key.

For the user to read the file, specify the same access level (private) and key you used to upload:

1Future<void> downloadPrivateFile(String cognitoIdentityId) async {
2 ...
3 final downloadOptions = S3DownloadFileOptions(
4 // Add the private access level
5 accessLevel: StorageAccessLevel.private
6 ...
7 );
8
9 try {
10 await Amplify.Storage.downloadFile(
11 ...
12 // Be sure to use the correct options
13 options: downloadOptions,
14 );
15 ...
16 }...
17}