Tooark.Storage.Aws
4.7.1
dotnet add package Tooark.Storage.Aws --version 4.7.1
NuGet\Install-Package Tooark.Storage.Aws -Version 4.7.1
<PackageReference Include="Tooark.Storage.Aws" Version="4.7.1" />
<PackageVersion Include="Tooark.Storage.Aws" Version="4.7.1" />
<PackageReference Include="Tooark.Storage.Aws" />
paket add Tooark.Storage.Aws --version 4.7.1
#r "nuget: Tooark.Storage.Aws, 4.7.1"
#:package Tooark.Storage.Aws@4.7.1
#addin nuget:?package=Tooark.Storage.Aws&version=4.7.1
#tool nuget:?package=Tooark.Storage.Aws&version=4.7.1
Tooark.Storage.Aws
Tooark.Storage provider on Amazon S3 and
services compatible with the S3 API, such as MinIO, LocalStack and Cloudflare R2. It implements IStorageService
with upload, download, delete, metadata and presigned URLs for reading and writing.
The contract, the common options and the shared errors are in the
Tooark.Storage README. This README covers
what is specific to AWS.
π Docs: Tooark.Storage.Aws on the site Β· All packages Β· API reference
π Languages: πΊπΈ English (this file) Β· π§π· PortuguΓͺs
π Contents
- Installation
- Configuration
- Credentials
- Compatible services
- Behavior on S3
- Dependencies
- Best Practices
- Error Codes and Solutions
- Contributing
- Help & Security
- Support
- License
π§ Installation
dotnet add package Tooark.Storage.Aws
βοΈ Configuration
appsettings.json
{
"Storage": {
"Bucket": "my-application-files",
"Region": "sa-east-1",
"SignedUrlExpirationMinutes": 15
}
}
Program.cs
using Tooark.Storage.Aws.Injections;
builder.Services.AddTooarkStorageAws(builder.Configuration);
// With an adjustment in code, applied on top of the section
builder.Services.AddTooarkStorageAws(builder.Configuration, options => options.Bucket = "another-bucket");
The registration validates the options and fails at startup when they are incomplete. The S3 client is registered as
IAmazonS3, with one instance for the whole application.
AwsStorageOptions properties
Besides Bucket and SignedUrlExpirationMinutes, the
common options:
| Property | Type | Default | Description |
|---|---|---|---|
Region |
string? |
β | Bucket region, such as sa-east-1. Without it, the region from the AWS default chain applies |
AccessKey |
string? |
β | Access key. Provide it together with SecretKey, or neither |
SecretKey |
string? |
β | Secret key. Provide it together with AccessKey, or neither |
SessionToken |
string? |
β | Session token, for temporary credentials. Only valid with both keys |
ServiceUrl |
string? |
β | Address of an S3-compatible service. Absolute http or https URL |
ForcePathStyle |
bool |
false |
Puts the bucket in the URL path (host/bucket/key), as compatible services usually require |
π Credentials
Without AccessKey and SecretKey, the credentials come from the AWS default chain, in the SDK's order:
environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY), the ~/.aws/credentials profile, the ECS task
role, the EKS pod role and the EC2 instance profile. It is the recommended path in production: no key stays in the
configuration, and AWS rotates the role without intervention.
With the keys in the options, they take precedence. One key without the other fails at registration: silently falling back to the default chain would make the application use another identity.
The identity needs s3:PutObject, s3:GetObject and s3:DeleteObject on the bucket objects, and s3:ListBucket on
the bucket. Without s3:ListBucket, S3 answers 403, not 404, for an object that does not exist: ExistsAsync throws
Storage.AccessDenied instead of returning false, and DownloadAsync throws the same error instead of
Storage.ObjectNotFound.
Your own client
If the application registers its own IAmazonS3 first, for example with AddAWSService<IAmazonS3>() from
AWSSDK.Extensions.NETCore.Setup, that one is used. In that case, Region, the credentials, ServiceUrl and
ForcePathStyle from the options do not apply; Bucket and SignedUrlExpirationMinutes still do.
π Compatible services
ServiceUrl points the client to another service with the S3 API. With it, the address defines the destination and
Region applies only to request signing. A local MinIO, for example:
{
"Storage": {
"Bucket": "files",
"ServiceUrl": "http://localhost:9000",
"ForcePathStyle": true,
"AccessKey": "minioadmin",
"SecretKey": "minioadmin"
}
}
Keep development keys in appsettings.Development.json or in the Secret Manager, never in the versioned
appsettings.json.
πͺ£ Behavior on S3
- Streaming download β
DownloadAsyncreturns the S3 response stream, without loading the file into memory. Closing the stream releases the connection. - Delete with a query first β S3 answers success when deleting an object that does not exist. To return
falsein that case,DeleteAsyncqueries the metadata first, which costs one more call. - Missing bucket in the metadata query β the query response has no body, so
ExistsAsyncandGetInfoAsynccannot tell a missing bucket from a missing object: both givefalseandnull. In the other operations, a missing bucket throwsStorage.BucketNotFound. - Presigned URL with Signature V4 β up to 7 days. With temporary credentials (role), the URL stops working when the session expires, even before the requested expiration.
- Upload β the caller's stream is not closed. A seekable stream is sent from the start, and its size comes back in
Size.
π Dependencies
| Package | Version | Description |
|---|---|---|
Tooark.Storage |
4.x | Contract and common validations |
AWSSDK.S3 |
4.x | Amazon S3 client |
Microsoft.Extensions.Options.ConfigurationExtensions |
8.x/10.x | Reading the options from configuration |
Microsoft.Extensions.DependencyInjection.Abstractions |
8.x/10.x | Container registration |
π― Best Practices
- Role instead of keys β on ECS, EKS or EC2, leave
AccessKeyandSecretKeyempty and grant the permission to the role. - Permission only on the application's bucket β scope the policy to the bucket ARN, not
s3:*on*. - Private bucket β keep Block Public Access on and deliver the files through presigned URLs.
- CORS for direct upload β the write URL only works in the browser with a CORS rule that allows
PUTfrom the page's origin.
β οΈ Error Codes and Solutions
The configuration errors are InternalServerErrorException thrown at registration (AddTooarkStorageAws). The
operation errors are in the
Tooark.Storage README.
| Message | Description | Solution |
|---|---|---|
Options.Storage.Aws.CredentialsIncomplete |
Only one of the keys, or a session token without the keys | Provide both keys, or neither to use the default chain |
Options.Storage.Aws.ServiceUrlInvalid;{value} |
ServiceUrl is not an absolute http or https URL |
Use the full address, such as http://localhost:9000 |
π€ Contributing
Contributions are welcome! Start with CONTRIBUTING.md β it covers the development workflow, the coding and commit conventions and the pull request checklist. Bugs and feature requests go through the issue templates of the Tooark repository.
By participating you agree to the Code of Conduct.
π Help & Security
- β Questions, bugs, feature ideas β see SUPPORT.md for the right channel
- π Security vulnerabilities β do not open a public issue; follow SECURITY.md
π Support
If Tooark helps your projects, consider supporting its development:
- π GitHub Sponsors
- β Ko-fi
Every contribution helps keep the project maintained and improving. Thank you! π
π License
This project is licensed under the BSD 3-Clause License.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. 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.S3 (>= 4.0.104.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.13)
- Microsoft.Extensions.Options (>= 10.0.13)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.13)
- Tooark.Storage (>= 4.7.1)
-
net8.0
- AWSSDK.S3 (>= 4.0.104.3)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
- Tooark.Storage (>= 4.7.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.