AF.Umbraco.S3.Media.Storage
1.2.1
dotnet add package AF.Umbraco.S3.Media.Storage --version 1.2.1
NuGet\Install-Package AF.Umbraco.S3.Media.Storage -Version 1.2.1
<PackageReference Include="AF.Umbraco.S3.Media.Storage" Version="1.2.1" />
<PackageVersion Include="AF.Umbraco.S3.Media.Storage" Version="1.2.1" />
<PackageReference Include="AF.Umbraco.S3.Media.Storage" />
paket add AF.Umbraco.S3.Media.Storage --version 1.2.1
#r "nuget: AF.Umbraco.S3.Media.Storage, 1.2.1"
#:package AF.Umbraco.S3.Media.Storage@1.2.1
#addin nuget:?package=AF.Umbraco.S3.Media.Storage&version=1.2.1
#tool nuget:?package=AF.Umbraco.S3.Media.Storage&version=1.2.1
AF.Umbraco.S3.Media.Storage
AWS S3 media storage provider for Umbraco 15/16/17 on .NET 9/10.
This package replaces the default media file system with an S3-backed implementation and includes:
- S3-backed implementation of Umbraco
IFileSystemfor Media. - Middleware for direct media delivery from S3 under
/media. - ImageSharp integration for dynamic thumbnails.
- S3 cache for all media files (
cache/mirror) plus ImageSharp transformed images. - Localized server-side validation for malformed image uploads.
- Startup S3 connectivity check that blocks app boot on connection failure.
- Optional package-hosted smoke endpoints (opt-in via
AF_SMOKE_TESTS=1). - Optional cache-retention cleanup with normal and test modes.
- Cache folder structure that mirrors the media folder structure.
Credits
This project is a porting of Our.Umbraco.StorageProviders.AWSS3
(adam-werner/Our.Umbraco.StorageProviders.AWSS3),
which is not compatible with recent Umbraco versions.
AF.Umbraco.S3.Media.Storage was fully refactored to be compatible with modern Umbraco versions and then further optimized and extended.
Compatibility
- Umbraco CMS:
15.x,16.x,17.x - .NET:
9.0,10.0 - AWS SDK for .NET:
AWSSDK.S3+AWSSDK.Extensions.NETCore.Setup
Test hosts and smoke CI
- Local compatibility hosts are included under
src/Umbraco.Cms.15.x,src/Umbraco.Cms.16.x, andsrc/Umbraco.Cms.17.x. - Each host supports local overrides through
appsettings.Local.json.
Installation
Install from NuGet:
dotnet add package AF.Umbraco.S3.Media.Storage
Basic setup
1) No Program.cs changes required
The package wires services and middleware automatically via a composer.
You only need to configure appsettings*.json.
2) Configure appsettings*.json
Minimal setup:
{
"Umbraco": {
"Storage": {
"AWSS3": {
"Media": {
"BucketName": "your-media-bucket",
"Region": "eu-west-1"
}
}
}
}
}
For public/open-source repositories, keep placeholders in appsettings.Development.json and store real local values in appsettings.Local.json (git-ignored).
Optional AWS section (local/non-IAM environments):
{
"AWS": {
"Profile": "YOUR_AWS_PROFILE",
"Region": "eu-west-1",
"ServiceURL": "http://localhost:9000",
"ForcePathStyle": true
}
}
Why two sections:
Umbraco:Storage:AWSS3:Mediais package/provider configuration (BucketName, retention, media behavior).AWSis AWS SDK client configuration (Profile,ServiceURL,ForcePathStyle, defaultRegion).
In short: Storage defines what the provider does, AWS defines how the SDK connects.
3) AWS secrets for local development
Keep AWS secrets out of the repository.
Use local shared credentials on your machine (for example ~/.aws/credentials):
[YOUR_AWS_PROFILE]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
Credential precedence used by this project:
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY(for example set only in locallaunchSettings.json)~/.aws/credentialsusing the profile configured inAWS:Profile(for exampleYOUR_AWS_PROFILE)- Other standard AWS SDK providers (for example IAM role on cloud hosts)
Cache retention
Thumbnail cache retention is configurable via:
{
"Umbraco": {
"Storage": {
"AWSS3": {
"Media": {
"CacheRetention": {
"Enabled": false,
"NumberOfDays": 90,
"TestModeEnable": false,
"TestModeSweepSeconds": 30,
"TestModeMaxAgeMinutes": 10
}
}
}
}
}
}
Rules:
TestModeEnable = trueoverridesEnabled.- In normal mode, cleanup uses
NumberOfDays. - In test mode, cleanup sweep/max-age are controlled in seconds/minutes.
Setup validation
- When Umbraco start, the package check AWS connectivity
- If AWS connectivity is invalid, startup may be blocked by the package startup validation.
Smoke endpoints (opt-in)
For local validation and CI checks you can enable built-in smoke endpoints by setting:
AF_SMOKE_TESTS=1
Endpoints:
GET /smoke/healthPOST /smoke/media-upload
These endpoints are disabled by default.
Logging and alerts
- Package logs are emitted in English and include the
[AFUS3MS]prefix for easy filtering. - Startup connectivity failures are logged as critical and block Umbraco startup.
- Upload/cache/delete storage failures are logged with the same prefix and returned to users with localized alert messages.
S3 object layout
- Original media files:
media/... - Mirrored media cache (all media types):
cache/... - ImageSharp transformed cache:
cache/...(under transformed keys) - For ease of management, the
cachefolder replicates themediafolder hierarchy, ensuring a one-to-one correspondence between each media folder and its cache folder.
Localization for validation errors
The package includes localized messages for:
it-ITen-US(default fallback)fr-FRes-ESde-DEda-DK
If a specific culture resource is missing, the package falls back to en-US.
Project documentation
For full technical documentation:
docs/API_REFERENCE.mddocs/ARCHITECTURE.mddocs/CONFIGURATION.mddocs/MAINTENANCE.mddocs/CHANGELOG.md
Security checks
This repository runs automated secret scanning in GitHub Actions via Gitleaks (.github/workflows/secret-scan.yml).
Security advisory notice
This package does not introduce the known Umbraco advisory GHSA-69cg-w8vm-h229, but it can be installed on Umbraco versions that may still include it.
For production usage, always install the latest patched Umbraco release in your major/minor line.
Attribution request (non-binding)
If you fork or modify this project, please consider adding credits to:
- Project:
AF.Umbraco.S3.Media.Storage - Author:
Adriano Fabri - Url:
https://github.com/afabri73/AF.Umbraco.S3.Media.Storage
License
This project is licensed under MIT. See License.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AWSSDK.Extensions.NETCore.Setup (>= 4.0.3.22)
- AWSSDK.S3 (>= 4.0.18.1)
- SixLabors.ImageSharp.Web.Providers.AWS (>= 3.2.0)
- Umbraco.Cms.Web.Common (>= 15.0.0 && < 18.0.0)
-
net9.0
- AWSSDK.Extensions.NETCore.Setup (>= 4.0.3.22)
- AWSSDK.S3 (>= 4.0.18.1)
- SixLabors.ImageSharp.Web.Providers.AWS (>= 3.2.0)
- Umbraco.Cms.Web.Common (>= 15.0.0 && < 18.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
1.2.1: Rebuilt package to include composer auto-registration and smoke endpoints in the shipped DLLs.