Skip to content

Updated credential providers to provide Async version for generating credentials. #3681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

ashishdhingra
Copy link
Contributor

@ashishdhingra ashishdhingra commented Feb 28, 2025

Description

Updated credential providers to provide Async version for generating credentials.

NOTE:
Async methods don't have parameter for CancellationToken since the GetCredentialsAsync() doesn't have it.

Motivation and Context

Issue #3626 and #3613
Existing customer PR #3627

Testing

  • Added test cases for TestAssumeRoleAWSCredentialsAsyncGet and TestEC2InstanceMetadataSecureCredentialsSuccessAsync.
  • Dry-run
    • DRY_RUN-e95a1656-57b3-44db-88d5-d14060e1e1db completed successfully.
    • DRY_RUN-d0d12849-b226-472a-ad45-a6156c073b3f completed successfully.
    • DRY_RUN-63e31fe8-dc91-4fcc-b06f-9a7fde0edfb6 completed successfully.
    • DRY_RUN-5d396d86-4d29-45b4-aca3-dcaca3a2a684 completed successfully (for commit 33a2493).
    • DRY_RUN-1a5ceffe-09c6-406f-a5ae-d49a72438f2b completed successfully (for commit e9ede6c)

References for SAML Federation:

Federated SAML credentials cannot be tested via shared credentials file. I was able to step through the code and hack way around. The problem is that EndpointDiscoveryHandler.ProcessEndpointDiscovery() uses non-async version to get credentials.

Testing Customer's scenario:

  • Create a new role named TestEC2ReadOnlyRole with AmazonEC2ReadOnlyAccess permission policy and below trust relationship with the account:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::<<ACCOUNT-ID>>:root"
                },
                "Action": "sts:AssumeRole",
                "Condition": {}
            }
        ]
    }
  • In ~/.aws/config file, setup below profile:
    [default]
    region = us-east-2
    output = json
    
    [profile testassumerole]
    source_profile = default
    role_arn = arn:aws:iam::<<ACCOUNT-ID>>:role/TestEC2ReadOnlyRole
    
    The main credentials for default profile are configured in ~/.aws/credentials.
  • While debugging via Visual Studio, set AWS_PROFILE environment variable to testassumerole.

While the async path for ICoreAmazonSTS.CredentialsFromAssumeRoleAuthenticationAsync() is triggered in V4 branch for this PR, but below are my observations which highlight that sync path is triggered at some point. Comparison between V3 and V4 stack trace is also mentioned.

@normj / @dscpinheiro Prior to implementation of SRA, SDK used CredentialsRetriever (refer stack trace in customer's issue #3626). It emitted InvokeAsync() versions. Is there an equivalent in SRA world? Now EndpointDiscoveryHandler always uses sync version at EndpointDiscoveryHandler.ProcessEndpointDiscovery(). We have removed CredentialsRetriever in V4 in commit. Please suggest if async invocation for retrieving credentials is no longer possible in V4!

V3 Call stack:
While debugging it worked fine.

>	AWSSDK.Core.dll!Amazon.Runtime.RefreshingAWSCredentials.GenerateNewCredentialsAsync() Line 273	C#
 	AWSSDK.Core.dll!Amazon.Runtime.RefreshingAWSCredentials.GetCredentialsAsync() Line 154	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 99	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.RetryHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 135	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CompressionHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 57	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CallbackHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 61	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.EC2.dll!Amazon.EC2.Internal.AmazonEC2PostMarshallHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 57	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.BaseEndpointResolver.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 43	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Marshaller.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 56	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.EC2.dll!Amazon.EC2.Internal.AmazonEC2PreMarshallHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 80	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CallbackHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 61	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 53	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 165	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.MetricsHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 94	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.RuntimePipeline.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 152	C#
 	AWSSDK.Core.dll!Amazon.Runtime.AmazonServiceClient.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.AmazonWebServiceRequest request, Amazon.Runtime.Internal.InvokeOptionsBase options, System.Threading.CancellationToken cancellationToken) Line 278	C#
 	AWSSDK.EC2.dll!Amazon.EC2.AmazonEC2Client.DescribeTagsAsync(Amazon.EC2.Model.DescribeTagsRequest request, System.Threading.CancellationToken cancellationToken) Line 16218	C#
 	AWSSDK.EC2.dll!Amazon.EC2.AmazonEC2Client.DescribeTagsAsync(System.Threading.CancellationToken cancellationToken) Line 16180	C#
 	V4Test.dll!Program.<Main>$(string[] args) Line 7	C#

V4 Call stack:

>	AWSSDK.Core.dll!Amazon.Runtime.AssumeRoleAWSCredentials.GenerateNewCredentials() Line 105	C#
 	AWSSDK.Core.dll!Amazon.Runtime.RefreshingAWSCredentials.GetCredentials.__GenerateCredentialsAndUpdateState|11_0() Line 166	C#
 	AWSSDK.Core.dll!Amazon.Runtime.RefreshingAWSCredentials.GetCredentials() Line 150	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.ProcessEndpointDiscovery(Amazon.Runtime.IRequestContext requestContext, bool evictCacheKey, System.Uri evictUri) Line 136	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.DiscoverEndpoints(Amazon.Runtime.IRequestContext requestContext, bool evictCacheKey) Line 112	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.PreInvoke(Amazon.Runtime.IExecutionContext executionContext) Line 101	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 72	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.ChecksumHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 52	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.RetryHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 135	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CompressionHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 56	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CallbackHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 61	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.EC2.dll!Amazon.EC2.Internal.AmazonEC2PostMarshallHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 57	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.BaseEndpointResolver.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 43	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.BaseAuthResolverHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 47	C#
 	[Async Call Stack]	
 	[Async] AWSSDK.Core.dll!Amazon.Runtime.Internal.CallbackHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 61	C#
 	[Async] AWSSDK.Core.dll!Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 53	C#
 	[Async] AWSSDK.Core.dll!Amazon.Runtime.Internal.MetricsHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 93	C#
 	[Async] V4Test.dll!Program.<Main>$(string[] args) Line 7	C#

It ultimately calls async version while invoking Signer to sign the request:

>	AWSSDK.Core.dll!Amazon.Runtime.RefreshingAWSCredentials.GetCredentialsAsync() Line 183	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Signer.SignRequestAsync(Amazon.Runtime.IRequestContext requestContext) Line 158	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Signer.PreInvokeAsync(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Signer.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 57	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 76	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.ChecksumHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 52	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.RetryHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 135	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CompressionHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 56	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CallbackHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 61	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.EC2.dll!Amazon.EC2.Internal.AmazonEC2PostMarshallHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 57	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.BaseEndpointResolver.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 43	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.BaseAuthResolverHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 47	C#

But looks like at some point(s) we make sync calls. And it might fail at the previous sync stack trace while assuming role, on platforms like Android which don't support sync calls (per customer's issue).

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have read the README document
  • I have added tests to cover my changes
  • All new and existing tests passed

License

  • I confirm that this pull request can be released under the Apache 2 license

@ashishdhingra ashishdhingra marked this pull request as draft February 28, 2025 19:22
@dscpinheiro dscpinheiro added the v4 label Feb 28, 2025
@ashishdhingra ashishdhingra force-pushed the user/ashdhin/V4-CredentialProviders-AsyncVersions branch 2 times, most recently from 997906f to 75f984d Compare March 4, 2025 21:16
@ashishdhingra ashishdhingra marked this pull request as ready for review March 4, 2025 21:27
@ashishdhingra ashishdhingra force-pushed the user/ashdhin/V4-CredentialProviders-AsyncVersions branch 2 times, most recently from c4612e8 to e90cbf2 Compare March 4, 2025 22:50
Copy link
Contributor

@dscpinheiro dscpinheiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took an initial pass but as discussed offline there's a lot of code that had to be duplicated and I'm not sure it's the best approach.

For the question in the description, we removed the credential retriever pipeline handler and the signers now retrieve credentials themselves. The async method in the signer just invokes the sync version:

public virtual System.Threading.Tasks.Task SignAsync(
IRequest request,
IClientConfig clientConfig,
RequestMetrics metrics,
BaseIdentity identity,
CancellationToken token = default)
{
Sign(request, clientConfig, metrics, identity);
#if NETSTANDARD
return Task.CompletedTask;
#else
return Task.FromResult(0);
#endif
}
#endif


[Fact]
[Trait(TestBase.CategoryAttribute, "Credentials")]
public async Task TestAssumeRoleAWSCredentialsAsyncGet()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI This test doesn't run in our build system (it skips the RequiresIAMUser category that's applied to the parent class).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for letting me know. Do we have reasoning for excluding the test RequiresIAMUser category?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not the case for the test you added, but for some other operations (such as https://github.com/aws/aws-sdk-net/blob/main/sdk/test/Services/SecurityToken/IntegrationTests/GetFederationToken.cs), it requires an IAM user (and our build system assumes a role in a separate account to run tests).

From https://docs.aws.amazon.com/STS/latest/APIReference/API_GetFederationToken.html:

Returns a set of temporary security credentials (consisting of an access key ID, a secret access key, and a security token) for a user. A typical use is in a proxy application that gets temporary security credentials on behalf of distributed applications inside a corporate network.
You must call the GetFederationToken operation using the long-term security credentials of an IAM user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed test case in latest commit e9ede6c. Will initiate a dry run.

@ashishdhingra
Copy link
Contributor Author

I took an initial pass but as discussed offline there's a lot of code that had to be duplicated and I'm not sure it's the best approach.

For the question in the description, we removed the credential retriever pipeline handler and the signers now retrieve credentials themselves. The async method in the signer just invokes the sync version:

public virtual System.Threading.Tasks.Task SignAsync(
IRequest request,
IClientConfig clientConfig,
RequestMetrics metrics,
BaseIdentity identity,
CancellationToken token = default)
{
Sign(request, clientConfig, metrics, identity);
#if NETSTANDARD
return Task.CompletedTask;
#else
return Task.FromResult(0);
#endif
}
#endif

@dscpinheiro Thanks for the review. I understand the signer will call Async version based on stack trace I shared earlier:

AWSSDK.Core.dll!Amazon.Runtime.RefreshingAWSCredentials.GetCredentialsAsync() Line 183	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Signer.SignRequestAsync(Amazon.Runtime.IRequestContext requestContext) Line 158	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Signer.PreInvokeAsync(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.Signer.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 57	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 76	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.ChecksumHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 52	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#

I'm referring to sync call in below stack trace after AmazonEC2PostMarshallHandler.InvokeAsync():

AWSSDK.Core.dll!Amazon.Runtime.AssumeRoleAWSCredentials.GenerateNewCredentials() Line 105	C#
 	AWSSDK.Core.dll!Amazon.Runtime.RefreshingAWSCredentials.GetCredentials.__GenerateCredentialsAndUpdateState|11_0() Line 166	C#
 	AWSSDK.Core.dll!Amazon.Runtime.RefreshingAWSCredentials.GetCredentials() Line 150	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.ProcessEndpointDiscovery(Amazon.Runtime.IRequestContext requestContext, bool evictCacheKey, System.Uri evictUri) Line 136	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.DiscoverEndpoints(Amazon.Runtime.IRequestContext requestContext, bool evictCacheKey) Line 112	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.PreInvoke(Amazon.Runtime.IExecutionContext executionContext) Line 101	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 72	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.ChecksumHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 52	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.RetryHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 135	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CompressionHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 56	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.CallbackHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 61	C#
 	AWSSDK.Core.dll!Amazon.Runtime.Internal.PipelineHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 82	C#
 	AWSSDK.EC2.dll!Amazon.EC2.Internal.AmazonEC2PostMarshallHandler.InvokeAsync<Amazon.EC2.Model.DescribeTagsResponse>(Amazon.Runtime.IExecutionContext executionContext) Line 57	C#

EndpointDiscoveryHandler takes place of CredentialsRetriever in this flow and as part of SRA change, it was updated to make sync call. Please review.

@ashishdhingra ashishdhingra force-pushed the user/ashdhin/V4-CredentialProviders-AsyncVersions branch 2 times, most recently from 06a4959 to e5a45f5 Compare March 6, 2025 21:12
@ashishdhingra
Copy link
Contributor Author

For the question in the description, we removed the credential retriever pipeline handler and the signers now retrieve credentials themselves. The async method in the signer just invokes the sync version:

public virtual System.Threading.Tasks.Task SignAsync(
IRequest request,
IClientConfig clientConfig,
RequestMetrics metrics,
BaseIdentity identity,
CancellationToken token = default)
{
Sign(request, clientConfig, metrics, identity);
#if NETSTANDARD
return Task.CompletedTask;
#else
return Task.FromResult(0);
#endif
}
#endif

@dscpinheiro Thanks for the feedback. I had discussed this with @normj and fixed it in commit e5a45f5. Please review.

@ashishdhingra ashishdhingra requested a review from normj March 8, 2025 06:37
@ashishdhingra ashishdhingra force-pushed the user/ashdhin/V4-CredentialProviders-AsyncVersions branch 3 times, most recently from 422e83f to 66a2926 Compare March 10, 2025 19:57
Copy link
Member

@normj normj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One minor nit but otherwise looks good.

ICoreAmazonSTS coreSTSClient = GetSTSClient(region);

var credentials = coreSTSClient.CredentialsFromAssumeRoleAuthentication(RoleArn, RoleSessionName, Options);
_logger.InfoFormat("New credentials created for assume role that expire at {0}", credentials.Expiration.ToString("yyyy-MM-ddTHH:mm:ss.fffffffK", CultureInfo.InvariantCulture));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Norm changed these logs to DebugFormat. Is reverting them back to Info intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest commit e9ede6c. Will initiate a dry run.

ICoreAmazonSTS coreSTSClient = GlobalRuntimeDependencyRegistry.Instance.GetInstance<ICoreAmazonSTS>(ServiceClientHelpers.STS_ASSEMBLY_NAME, ServiceClientHelpers.STS_SERVICE_CLASS_NAME,
new CreateInstanceContext(new SecurityTokenServiceClientContext { Action = SecurityTokenServiceClientContext.ActionContext.AssumeRoleAWSCredentials, Region = region, ProxySettings = Options?.ProxySettings }));
if(coreSTSClient == null)
new CreateInstanceContext(new SecurityTokenServiceClientContext { Action = SecurityTokenServiceClientContext.ActionContext.AssumeRoleAWSCredentials, Region = region, ProxySettings = Options?.ProxySettings }));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Remove extra space before new CreateInstance... (this happens in sdk/src/Core/Amazon.Runtime/Pipeline/Handlers/EndpointDiscoveryHandler.cs too).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest commit e9ede6c. Will initiate a dry run.

/// a runtime dependency. This interface is implemented by the AmazonSecurityTokenServiceClient
/// defined in the AWSSDK.SecurityToken assembly.
/// </summary>
public interface ICoreAmazonSTS_SAML
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Why did you delete ICoreAmazonSTS_SAML but not the ICoreAmazonSTS_WebIdentity interface? Would consolidating all the methods in a single interface be an option since this is targeting V4?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest commit e9ede6c. Will initiate a dry run.

};
var role = await iam.CreateRoleAsync(createRoleRequest);

var sourceCredentials = FallbackCredentialsFactory.GetCredentials();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The FallbackCredentialsFactory is deprecated and it should not be used anymore (the replacement is DefaultAWSCredentialsIdentityResolver but as I mentioned in the other comment this test doesn't run in the build system so in my opinion we should remove it).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed test case in latest commit e9ede6c. Will initiate a dry run.

@ashishdhingra ashishdhingra force-pushed the user/ashdhin/V4-CredentialProviders-AsyncVersions branch from e9ede6c to 24a7da3 Compare March 13, 2025 21:40
@ashishdhingra ashishdhingra force-pushed the user/ashdhin/V4-CredentialProviders-AsyncVersions branch from 24a7da3 to 3c94a2a Compare March 14, 2025 17:15
@ashishdhingra ashishdhingra merged commit 978251f into v4-development Mar 14, 2025
1 check passed
@dscpinheiro dscpinheiro deleted the user/ashdhin/V4-CredentialProviders-AsyncVersions branch March 15, 2025 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants