---
title: Amazon S3
related:
  - https://docs.kentico.com/documentation/developers-and-admins/api/files-api-and-cms-io.md
  - https://docs.kentico.com/documentation/developers-and-admins/api/files-api-and-cms-io/file-system-providers.md
  - https://docs.kentico.com/documentation/developers-and-admins/api/files-api-and-cms-io/file-system-providers/storage-path-mapping.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

Xperience by Kentico supports file system providers that allow you to map parts of the file system to [Amazon S3](https://aws.amazon.com/s3/) storage. You can use Amazon S3 when hosting your project in [private cloud](https://docs.kentico.com/documentation/developers-and-admins/deployment/deploy-to-private-cloud.md) or when you wish to store parts of the application file system in external shared storage. For example, shared storage is a requirement for all [scaled](https://docs.kentico.com/documentation/developers-and-admins/configuration/auto-scaling-support.md) Xperience environments.

> **Info:** **Filename case**
>
> Unlike regular file systems (NTFS, VFAT), Amazon S3 storage is case-sensitive. To ensure consistent behavior, Xperience automatically converts all file and folder names to lower case when processing files on Amazon S3.

## Media library files in Amazon S3

> **Note:** **Media libraries will be removed**
>
> Support for media libraries ended on 24 July, 2026. The feature and its associated APIs will be removed in two steps:
>
> - **August 2026** Refresh – the feature was hidden in the admin UI for projects that have no media libraries.
> - **September 2026** Refresh – the feature and all associated APIs will be fully removed.
>
> Before mapping media library files to the [Amazon S3](https://aws.amazon.com/s3/) storage, consider migrating media libraries and mapping content item assets instead. See [Media library migration](https://docs.kentico.com/guides/architecture/media-libraries-migration-guidance.md) for instructions on how to migrate your media library files to [Content hub](https://docs.kentico.com/documentation/business-users/content-hub.md).

Media library files stored in Amazon S3 have the following limitations:

- **Storing a large number (thousands) of media library files in a single media library can significantly affect the performance and user experience of the [Media libraries](https://docs.kentico.com/documentation/business-users/media-libraries/create-media-libraries.md) application.**
  - We recommend structuring media library files into multiple media libraries and storing at most 100 files in a single media library folder.
- Mapping subfolders of media libraries is not supported. You can map either the directory containing the media libraries (**\~/assets/media**), or individual media libraries (**\~/assets/media/**).
- The system's automatic clearing of files from the server-side cache does not work for files stored in an external storage. If you modify a media file, the website may still display the old version until the cache expires (unless you manually clear the application's cache). See also: [File caching](https://docs.kentico.com/documentation/developers-and-admins/development/caching/file-caching.md).

## Map files to Amazon storage

Mapping folders to Amazon storage allows you to store files on a shared storage and leverage Amazon's Cloudfront CDN.

Before you can map parts of the file system to Amazon storage, add the following application settings to your project:

1. The ID of your Amazon access key:

   ```json title="appsettings.json"
   "CMSAmazonAccessKeyID": "YourKey"
   ```
2. The Amazon access key:

   ```json title="appsettings.json"
   "CMSAmazonAccessKey": "YourSecret"
   ```
3. Add the following key to specify the bucket that you want to use to store files.

   ```json title="appsettings.json"
   "CMSAmazonBucketName": "YourBucketName"
   ```

With the Amazon account connected and configured, use the following process to map parts of the file system to the specified bucket:

1. Open the Xperience project in Visual Studio.
2. [Add a custom Class Library project](https://docs.kentico.com/documentation/developers-and-admins/customization/integrate-custom-code.md) and install the **Kentico.Xperience.AmazonStorage** NuGet package as a dependency.
3. Create a [custom module class](https://docs.kentico.com/documentation/developers-and-admins/customization/run-code-on-application-startup.md) in the created library.
4. Override the module's `OnInit` method and use the [storage path registry](https://docs.kentico.com/documentation/developers-and-admins/api/files-api-and-cms-io/file-system-providers/storage-path-mapping.md) to iterate registered paths and map them to your Amazon S3 provider:

   > **Note:** As some deployment environments don’t provide a persistent file system, we recommend mapping all `SharedPersistent` paths to prevent possible loss of files due to redeployment, swapping of slots, etc.

   ```csharp title="Mapping registered paths to Amazon storage"
   using CMS;
   using CMS.DataEngine;
   using CMS.IO;
   using CMS.IO.Extensions;

   using Kentico.Xperience.AmazonStorage;

   using Microsoft.Extensions.DependencyInjection;

   // Registers the custom module into the system
   [assembly: RegisterModule(typeof(CustomInitializationModule))]

   public class CustomInitializationModule : Module
   {
       // Module class constructor, the system registers the module under the name "CustomInit"
       public CustomInitializationModule()
           : base("CustomInit")
       {
       }

       // Contains initialization code that is executed when the application starts
       protected override void OnInit(ModuleInitParameters parameters)
       {
           base.OnInit(parameters);

           IStoragePathRegistry registry = parameters.Services.GetRequiredService<IStoragePathRegistry>();

           // Maps all SharedPersistent paths to Amazon S3 storage
           foreach (PathRegistration registration in registry.GetRegistrations(PathType.SharedPersistent))
           {
               // Creates an Amazon S3 storage provider
               // First parameter: CustomRootPath used within the bucket
               // Second parameter: PublicExternalFolderObject - set to true for paths
               // whose files are served directly via URL (e.g., media library files).
               // Defaults to the global CMSAmazonPublicAccess setting when omitted.
               bool isPublic = registration.IsMediaLibraryPath();

               StorageHelper.MapStoragePath(
                   registration.MappedPath,
                   AmazonStorageProvider.Create("myassetsbucket", isPublic));
           }
       }
   }
   ```

> **Note:** For `PublicExternalFolderObject` to work, your bucket must have [Object Ownership](https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html) set to **ACLs enabled** and `BlockPublicAcls`/`IgnorePublicAcls` turned off – or use a bucket policy to grant public read access instead, keep in mind that the bucket policy is applied to the whole bucket and all objects in it.

The deployed application now stores files from all registered shared persistent paths in the **myassetsbucket** Amazon S3 bucket.

### Optional application settings for Amazon S3

| Key                      | Description                                                                                                                                                                                                                                                                                                                                         |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CMSAmazonTempPath        | Path to a local directory that the system uses to store temporary files.<br>**Default value**: \App\_Data\AmazonTemp<br>`"CMSAmazonTempPath": "C:\\Windows\\Temp"`                                                                                                                                                                                  |
| CMSAmazonCachePath       | Path to a local directory where the provider stores cached files.<br>**Default value**: \App\_Data\AmazonCache<br>`"CMSAmazonCachePath": "C:\\Cache"`                                                                                                                                                                                               |
| CMSAmazonEndPoint        | Allows you to change the default URL of the Amazon S3 [Website Endpoint](http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html). For example, you can change the endpoint if you want to use CloudFront CDN.<br>**Default value**: http://.s3.amazonaws.com<br>`"CMSAmazonEndPoint": "http://someendpoint.s3.amazonaws.com"`         |
| CMSAmazonRestApiEndPoint | Allows you to change the default URL of the Amazon S3 [REST API Endpoint](http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html#WebsiteRestEndpointDiff). The system uses the REST API to determine the region of buckets.<br>**Default value**: https://s3.amazonaws.com<br>`"CMSAmazonRestApiEndPoint": "http://s3.amazonaws.com"` |
| CMSAmazonPublicAccess    | Specifies whether files uploaded to Amazon S3 through Xperience are accessible for public users.<br>**Default value**:<br>_true_ if you specify an endpoint<br>_false_ If no endpoint is specified<br>`"CMSAmazonPublicAccess": true`                                                                                                               |

## Configuring Xperience to use Amazon CloudFront CDN

A Content Delivery Network (CDN) speeds up distribution of content to the end users through a network of data centers. See [Amazon CloudFront Product Details](https://aws.amazon.com/cloudfront/features/) to learn more.

To start using the Amazon CloudFront service with Xperience:

1. Create a **CloudFront Distribution**. You can use the [ Amazon Management Console](https://console.aws.amazon.com). Select your Amazon S3 storage bucket as the **Origin Domain Name**.
2. Edit the application settings file of your Xperience project and add the **CMSAmazonPublicAccess** and **CMSAmazonEndPoint** keys:

   ```json title="appsettings.json"
   "CMSAmazonPublicAccess": true,
   "CMSAmazonEndPoint": "EndpointURL"
   ```
3. Set the value of the **CMSAmazonEndPoint** key to the **Domain Name** URL of your created CDN.

   > **Note:** If your website runs under **HTTPS**, we recommend always specifying the endpoint URL with the **HTTPS** protocol as well.
   >
   > For example:  _https://domain.cloudfront.net_
   >
   > Without this configuration you may receive [Mixed Content](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/what-is-mixed-content?hl=en) warnings in your browser's console when retrieving files from the CDN.

Your project now uses the created CDN service.
