aws / amazon-s3-encryption-client-dotnet

An encryption client that allows you to secure your sensitive data before you send it to Amazon S3.
https://aws.github.io/amazon-s3-encryption-client-dotnet/
Apache License 2.0
14 stars 10 forks source link

Why no constructor overload that takes RegionEndpoint in AmazonS3EncryptionClientV2? #23

Closed sunilshahi closed 3 years ago

sunilshahi commented 3 years ago

We were using AmazonS3EncryptionClient to do some client side encryption and couple of month ago I saw a Obsolete warning that read like this.

This feature is in maintenance mode, no new updates will be released. Please transition to https://www.nuget.org/packages/Amazon.Extensions.S3.Encryption and see https://docs.aws.amazon.com/general/latest/gr/aws_sdk_cryptography.html for more information.

No big deal. looks like this class has been moved to new namespace available with a separate nuget package and there is a new class AmazonS3EncryptionClientV2 which which should be used instead of AmazonS3EncryptionClient.

However, upon looking into using the new nuget package and migrating I found out that AmazonS3EncryptionClientV2 does not have a constructor overload that takes Region endpoint.

image

No such overload in AmazonS3EncryptionClientV2

image

going over the documentation I see that we can use AWSConfigs.AWSRegion to specify the region. This works for most cases however fails in following situation.

I have two different S3 buckets I need to use and they are located in two different regions. say bucket "us-east-1" and "us-west-1" and I have 2 classes say ServiceA that accesses bucket in us-east-1 and ServiceB that accesses bucket in us-west-1.


    public class ServiceA
    {
        private readonly IAmazonS3 _s3;
        public ServiceA(IAmazonS3 s3)
        {
            _s3 = s3;
            //just for test
            Console.WriteLine(_s3.Config.RegionEndpoint.DisplayName);
        }
    }
    public class ServiceB
    {
        private readonly IAmazonS3 _s3;

        public ServiceB(IAmazonS3 s3)
        {
            _s3 = s3;
            //just for test
            Console.WriteLine(_s3.Config.RegionEndpoint.DisplayName);
        }
    }

And I have registered these 2 service with DI container like this.


services.AddTransient<ServiceA>(sp => 
{
    var settings = new
    {
        AccessKey = "access-key-1", //dummy
        SecretKey = "secret-key-1", //dummy
        KmsKeyId = "kms-key-1",     //dummy
        Region = "us-east-1"        //real 
    };

    var credential = new BasicAWSCredentials(settings.AccessKey, settings.SecretKey);

    AWSConfigs.AWSRegion = settings.Region;  //<======setting region

    var encryptionContext = new Dictionary<string, string>();
    var encryptionMaterial =
        new EncryptionMaterialsV2(settings.KmsKeyId, KmsType.KmsContext, encryptionContext);
    var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy);
    var s3 = new AmazonS3EncryptionClientV2(credential, configuration, encryptionMaterial);

    return new ServiceA(s3);
});

services.AddTransient<ServiceB>(sp =>
{
    var settings = new
    {
        AccessKey = "access-key-2",  //dummy
        SecretKey = "secret-key-2",  //dummy
        KmsKeyId = "kms-key-2",      //dummy
        Region = "us-west-1"         //real 
    };

    var credential = new BasicAWSCredentials(settings.AccessKey, settings.SecretKey);

    AWSConfigs.AWSRegion = settings.Region; //<======setting region

    var encryptionContext = new Dictionary<string, string>();
    var encryptionMaterial =
        new EncryptionMaterialsV2(settings.KmsKeyId, KmsType.KmsContext, encryptionContext);
    var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy);
    var s3 = new AmazonS3EncryptionClientV2(credential, configuration, encryptionMaterial);

    return new ServiceB(s3);
});

If I do this, both ServiceA and ServiceB get different instance of AmazonS3EncryptionClientV2 however, the region on both ends up being same. Looks like only first call to AWSConfigs.AWSRegion = settings.Region; is being considered and second or after calls are being ignored.

image

The Question

I cannot move both my s3 buckets to same region for reasons I cannot go into details here.

Why does AmazonS3EncryptionClientV2 not have option to pass region?
How can I accomplish this so that each instance has different region?

Environment

See my sample code for this here. https://github.com/sunilshahi/SampleS3 https://github.com/sunilshahi/SampleS3/blob/master/SampleS3/Program.cs


This is a :question: general question

ashishdhingra commented 3 years ago

Hi @sunilshahi,

Good morning.

Thanks for posting the guidance question. To specify the region while using AmazonS3EncryptionClientV2, you may use the following code, as an example:

var asymmetricAlgorithm = RSA.Create();
var encryptionMaterial = new EncryptionMaterialsV2(asymmetricAlgorithm, AsymmetricAlgorithmType.RsaOaepSha1);
var configuration = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2);
configuration.RegionEndpoint = RegionEndpoint.USEast2; // Replace with appropriate region
AmazonS3EncryptionClientV2 encryptionClient = new AmazonS3EncryptionClientV2(configuration, encryptionMaterial);

Hope this helps.

Thanks, Ashish

sunilshahi commented 3 years ago

@ashishdhingra Thank you for the response. Not sure why I did not think of checking for this inside other parameters.

This solves my problem. thanks.

github-actions[bot] commented 3 years ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.