Skip to content

CSHARP-4273: Cache AWS Credentials Where Possible. #894

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

Merged
merged 3 commits into from
Oct 7, 2022

Conversation

DmitryLukyanov
Copy link
Contributor

@DmitryLukyanov DmitryLukyanov commented Oct 6, 2022

Some notes:

  1. The spec requirement about dedicated thread is removed at this point. so we just save creds somewhere globally. Spec should be updated. cc: @blink1073
  2. There is an open question about clearing cache for CSFLE. (update: https://jira.mongodb.org/browse/DRIVERS-2464. It's about Azure, but I guess for Aws we can mimic their solution)

@DmitryLukyanov DmitryLukyanov requested review from JamesKovacs, BorisDog and blink1073 and removed request for BorisDog October 6, 2022 15:10
@@ -25,20 +25,27 @@ namespace MongoDB.Driver.Core.Authentication.External
{
internal class AwsCredentials : IExternalCredentials
{
// credentials are considered expired when: Expiration - now > 5 mins
private static readonly TimeSpan __overlapWhenExpired = TimeSpan.FromMinutes(5);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This value was suggested to change up to 5 mins. cc: @blink1073

@@ -987,7 +988,7 @@ tasks:
- func: run-aws-auth-test-with-aws-credentials-as-environment-variables
- func: run-aws-auth-test-with-aws-credentials-and-session-token-as-environment-variables
- func: run-aws-auth-test-with-aws-EC2-credentials
# ECS test is skipped untill testing on Linux becomes possible
# ECS test is skipped until testing on Linux becomes possible
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

@blink1073 blink1073 left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

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

Some minor comments to address but overall looking good.

@@ -25,20 +25,27 @@ namespace MongoDB.Driver.Core.Authentication.External
{
internal class AwsCredentials : IExternalCredentials
{
// credentials are considered expired when: Expiration - now > 5 mins
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be Expiration - now < 5 mins? For example if credentials expire at noon and it's currently 11:50am, noon - 11:50am = 10 minutes and credentials don't need to be refreshed yet. But at 11:55am, noon - 11:55am = 5 minutes and credentials need refreshing.

Note that this only affects the comment and not the implemented logic, which uses Expiration - now < 5 mins.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, it's typo, fixed

@@ -116,12 +123,23 @@ private async Task<AwsCredentials> CreateAwsCredentialsFromEc2ResponseAsync(Canc

private AwsCredentials CreateAwsCreadentialsFromAwsResponse(string awsResponse)
Copy link
Contributor

Choose a reason for hiding this comment

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

Spelling:
CreateAwsCreadentialsFromAwsResponse => CreateAwsCredentialsFromAwsResponse

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

{
_accessKeyId = Ensure.IsNotNull(accessKeyId, nameof(accessKeyId));
_expiration = expiration != null ? DateTime.Parse(expiration) : null;
Copy link
Contributor

Choose a reason for hiding this comment

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

The constructor should take the expiration as a DateTime?. See CreateAwsCredentialsFromAwsResponse below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed, done

var parsedResponse = BsonDocument.Parse(awsResponse);
var accessKeyId = parsedResponse.GetValue("AccessKeyId", null)?.AsString;
var secretAccessKey = parsedResponse.GetValue("SecretAccessKey", null)?.AsString;
var sessionToken = parsedResponse.GetValue("Token", null)?.AsString;
var expiration = parsedResponse.GetValue("Expiration", null)?.AsString;
Copy link
Contributor

Choose a reason for hiding this comment

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

We should do any input validation here in the factory method rather than delegating to the constructor. For example if the Expiration isn't a valid DateTime and fails parsing for any reason, it is better to throw in this factory method rather than in the constructor. We should also consider using DateTime.TryParse and how to best handle an error where the KMS sends back an invalid DateTime.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed, done

{
if (expiration != null)
{
throw new InvalidOperationException($"Expiration in AWS response is in invalid datetime format: {expiration}.");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

open to suggestions about error message

Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

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

LGTM

// 3. Ensure that a find operation adds credentials to the cache..
GetCache().Should().NotBeNull();

// 4. Override the cached credentials with an "Expiration" that is within thirty seconds of the current UTC time.
Copy link
Member

Choose a reason for hiding this comment

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

I updated mongodb/specifications#1281, with one tweak: this should be one minute.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated

@DmitryLukyanov DmitryLukyanov merged commit 3d67e80 into mongodb:master Oct 7, 2022
dnickless pushed a commit to dnickless/mongo-csharp-driver that referenced this pull request Aug 24, 2023
CSHARP-4273: Cache AWS Credentials Where Possible.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants