## Customization ### Customize Object Key Path You can customize your key path by defining a prefix resolver: ```dart import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:amplify_storage_s3/amplify_storage_s3.dart'; // Define your own prefix resolver, which implements the `S3PrefixResolver`. class MyPrefixResolver implements S3PrefixResolver { const MyPrefixResolver(); @override Future resolvePrefix({ required StorageAccessLevel accessLevel, String? identityId, }) async { if (accessLevel == StorageAccessLevel.guest) { return 'myPublicPrefix/'; } final String accessLevelPrefix; if (accessLevel == StorageAccessLevel.protected) { accessLevelPrefix = 'myProtectedPrefix/'; } else { accessLevelPrefix = 'myPrivatePrefix/'; } final targetIdentityId = identityId ?? await getCurrentUserIdentityId(); return '$accessLevelPrefix$targetIdentityId/'; } Future getCurrentUserIdentityId() async { final authPlugin = Amplify.Auth.getPlugin(AmplifyAuthCognito.pluginKey); final authSession = await authPlugin.fetchAuthSession(); return authSession.identityIdResult.value; } } ``` Then configure the storage plugin with the resolver. ```dart final storagePlugin = AmplifyStorageS3( prefixResolver: const MyPrefixResolver(), ); ... await Amplify.addPlugin(storagePlugin); ``` Add the IAM policy that corresponds with the prefixes defined above to enable read, write and delete operation for all the objects under path *myPublicPrefix/*: ```json { "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": ["arn:aws:s3:::your-s3-bucket/myPublicPrefix/*"] } ] } ``` If you want to have custom *private* path prefix like *`myPrivatePrefix/`*, you need to add it into your IAM policy: ```json { "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::your-s3-bucket/myPrivatePrefix/${cognito-identity.amazonaws.com:sub}/*" ] } ] } ``` #### Passthrough PrefixResolver If you would like no prefix resolution logic, such as performing S3 requests at the root of the bucket, you can use the `PassThroughPrefixResolver` provided by the `amplify_storage_s3` package. ```dart import 'package:amplify_storage_s3/amplify_storage_s3.dart'; final storagePlugin = AmplifyStorageS3( prefixResolver: const PassThroughPrefixResolver(), ); await Amplify.addPlugin(storagePlugin); ```