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
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tooark.Storage.Aws" Version="4.7.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tooark.Storage.Aws" Version="4.7.1" />
                    
Directory.Packages.props
<PackageReference Include="Tooark.Storage.Aws" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tooark.Storage.Aws --version 4.7.1
                    
#r "nuget: Tooark.Storage.Aws, 4.7.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tooark.Storage.Aws@4.7.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tooark.Storage.Aws&version=4.7.1
                    
Install as a Cake Addin
#tool nuget:?package=Tooark.Storage.Aws&version=4.7.1
                    
Install as a Cake Tool

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

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 β€” DownloadAsync returns 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 false in that case, DeleteAsync queries the metadata first, which costs one more call.
  • Missing bucket in the metadata query β€” the query response has no body, so ExistsAsync and GetInfoAsync cannot tell a missing bucket from a missing object: both give false and null. In the other operations, a missing bucket throws Storage.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

  1. Role instead of keys β€” on ECS, EKS or EC2, leave AccessKey and SecretKey empty and grant the permission to the role.
  2. Permission only on the application's bucket β€” scope the policy to the bucket ARN, not s3:* on *.
  3. Private bucket β€” keep Block Public Access on and deliver the files through presigned URLs.
  4. CORS for direct upload β€” the write URL only works in the browser with a CORS rule that allows PUT from 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:

Every contribution helps keep the project maintained and improving. Thank you! πŸ™


πŸ“„ License

This project is licensed under the BSD 3-Clause License.

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.7.1 34 10/17/2026
4.7.0 105 9/30/2026