## 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<String> 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<String> 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);
```
