Skip to content

Can't use SDK with AWS SSO credentials are mounted in docker container #2477

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

Closed
mabead opened this issue Nov 8, 2022 · 8 comments
Closed
Labels
bug This issue is a bug. credentials p0 This issue is the highest priority queued

Comments

@mabead
Copy link

mabead commented Nov 8, 2022

Describe the bug

I have the following code:

using Amazon;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using System;
using System.Threading.Tasks;

namespace WithOldSdk
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            var profileName = args.Length == 0 ? "default" : args[0];

            var sharedFile = new SharedCredentialsFile();

            if (!sharedFile.TryGetProfile(profileName, out var profile))
            {
                throw new ArgumentException($"AWS profile '{profileName}' was not found.");
            }

            if (!AWSCredentialsFactory.TryGetAWSCredentials(profile, sharedFile, out var credentials))
            {
                throw new NotSupportedException($"Failed to get AWS credentials from profile named '{profileName}'.");
            }

            var s3Client = new AmazonS3Client(credentials, RegionEndpoint.USEast1);

            var response = await s3Client.ListBucketsAsync();
            Console.WriteLine($"Found {response.Buckets.Count} buckets.");
        }
    }
}

with the following csproj file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="AWSSDK.S3" Version="3.7.8.23" />
    <PackageReference Include="AWSSDK.SSO" Version="3.7.0.150" />
    <PackageReference Include="AWSSDK.SSOOIDC" Version="3.7.0.150" />
  </ItemGroup>

</Project>

Given that we are using AWS SSO, before executing this program I have to run aws sso login. Then, I can run the program successfully like this:

PS C:\tmp\AwsSsoIssue\WithOldSdk> dotnet run
Found 327 buckets.

I can also run this program in docker by mounting my AWS credentials file in the docker container:

PS C:\tmp\AwsSsoIssue\WithOldSdk> docker run --rm -it -v "$(Get-Location):/src" -v "$env:USERPROFILE/.aws:/root/.aws:ro" -w /src mcr.microsoft.com/dotnet/core/sdk:3.1 dotnet run
Found 327 buckets.

So far, so good. I then modify my csproj file to use the latest AWS SDK. Here is how my csproj looks now:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="AWSSDK.S3" Version="3.7.101.10" />
    <PackageReference Include="AWSSDK.SSO" Version="3.7.100.10" />
    <PackageReference Include="AWSSDK.SSOOIDC" Version="3.7.100.10" />
  </ItemGroup>

</Project>

With this change, I can still run the program successfully:

PS C:\tmp\AwsSsoIssue\WithNewSdk> dotnet run
Found 327 buckets.

But then, if I run the program in docker in exactly the same way as before, I get an SSO error:

PS C:\tmp\AwsSsoIssue\WithNewSdk> docker run --rm -it -v "$(Get-Location):/src" -v "$env:USERPROFILE/.aws:/root/.aws:ro" -w /src mcr.microsoft.com/dotnet/core/sdk:3.1 dotnet run
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'Options property cannot be empty: ClientName')
   at Amazon.Runtime.Credentials.Internal.SSOTokenManager.GenerateNewTokenAsync(SSOTokenManagerGetTokenOptions options, CancellationToken cancellationToken)
   at Amazon.Runtime.Credentials.Internal.SSOTokenManager.GetTokenAsync(SSOTokenManagerGetTokenOptions options, CancellationToken cancellationToken)
   at Amazon.Runtime.SSOAWSCredentials.GetSsoCredentialsAsync(ICoreAmazonSSO sso)
   at Amazon.Runtime.SSOAWSCredentials.GenerateNewCredentialsAsync()
   at Amazon.Runtime.RefreshingAWSCredentials.GetCredentialsAsync()
   at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.S3.Internal.AmazonS3ExceptionHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
   at WithOldSdk.Program.Main(String[] args) in /src/Program.cs:line 31
   at WithOldSdk.Program.<Main>(String[] args)

Expected Behavior

Running the program in docker with the latest SDK should not create any SSO error since I am already logged in. It should behave the same as the old SDK did.

Current Behavior

As shown in the error above, the latest version of the AWS SDK raises an error while the old SDK does not.

Reproduction Steps

See description above.

Possible Solution

Did not find any

Additional Information/Context

No response

AWS .NET SDK and/or Package version used

AWSSDK.S3 -> 3.7.101.10
AWSSDK.SSO -> 3.7.100.10
AWSSDK.SSOOIDC -> 3.7.100.10

Targeted .NET Platform

.NET Core 3.1

Operating System and version

Windows 11

@mabead mabead added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Nov 8, 2022
@ashishdhingra
Copy link
Contributor

Similar issue in PowerShell aws/aws-tools-for-powershell#299.

@ashishdhingra ashishdhingra removed the needs-triage This issue or PR still needs to be triaged. label Nov 8, 2022
@mabead
Copy link
Author

mabead commented Nov 8, 2022

Maybe related:

It looks like a similar problem was resolved in 537a981 (see #1850) but then the fix was lost in fbd05f4#diff-53123b41f5f6d93f2030a4f5c22f41724b1896dd082b5445f614837c91c29f5f.

It looks to me like a code generator was executed and the changes made in #1850 were lost.

@mabead
Copy link
Author

mabead commented Nov 10, 2022

Here's a workaround that I found. First, I modify my code to support both AWS credentials from environment variables or from credentials file:

using Amazon;
using Amazon.Runtime;
using Amazon.Runtime.CredentialManagement;
using Amazon.S3;
using System;
using System.Threading.Tasks;

namespace WithOldSdk
{
    // docker run --rm -it -v "$(Get-Location):/src" -v "$env:USERPROFILE/.aws:/root/.aws:ro" -w /src mcr.microsoft.com/dotnet/core/sdk:3.1 dotnet run
    // Found 327 buckets.
    internal class Program
    {
        static async Task Main(string[] args)
        {
            AWSCredentials credentials;

            if (Environment.GetEnvironmentVariable("AWS_ACCESS_KEY_ID") != null)
            {
                Console.WriteLine("Getting credentials from environment variables.");
                credentials = new EnvironmentVariablesAWSCredentials();
            }
            else
            {
                Console.WriteLine("Getting credentials from credentials files.");

                var profileName = args.Length == 0 ? "default" : args[0];

                var sharedFile = new SharedCredentialsFile();

                if (!sharedFile.TryGetProfile(profileName, out var profile))
                {
                    throw new ArgumentException($"AWS profile '{profileName}' was not found.");
                }

                if (!AWSCredentialsFactory.TryGetAWSCredentials(profile, sharedFile, out credentials))
                {
                    throw new NotSupportedException($"Failed to get AWS credentials from profile named '{profileName}'.");
                }
            }

            var s3Client = new AmazonS3Client(credentials, RegionEndpoint.USEast1);

            var response = await s3Client.ListBucketsAsync();
            Console.WriteLine($"Found {response.Buckets.Count} buckets.");
        }
    }
}

Then, when I want to run it in docker, I use the environment variables instead of mounting my credentials files

$accountId = aws configure get sso_account_id
$roleName = aws configure get sso_role_name
$accessToken = (Get-Content (dir $env:HOMEPATH\.aws\sso\cache -Exclude botocore*.json)[0] | ConvertFrom-Json).accessToken
$region = aws configure get region --profile dev
$roleCredentials = aws sso get-role-credentials --account-id $accountId --role-name $roleName --access-token $accessToken --region $region | ConvertFrom-Json
docker run --rm -it -v "$(Get-Location):/src" -e AWS_SESSION_TOKEN=$($roleCredentials.roleCredentials.sessionToken) -e AWS_ACCESS_KEY_ID=$($roleCredentials.roleCredentials.accessKeyId) -e AWS_SECRET_ACCESS_KEY=$($roleCredentials.roleCredentials.secretAccessKey) -e AWS_DEFAULT_REGION=$region  -w /src mcr.microsoft.com/dotnet/core/sdk:3.1 dotnet run

Then, the program runs successfully:

Getting credentials from environment variables.
Found 332 buckets.

@ik130 ik130 added p1 This is a high priority issue p0 This issue is the highest priority and removed p1 This is a high priority issue labels Nov 11, 2022
@CamileDahdah
Copy link
Contributor

Hello there,
My team is working on fixing the bug. We realized that the issue occurs when the cached SSO token files in .aws directory are set to Read Only. The problem is when you pass this docker argument -v "$env:USERPROFILE/.aws:/root/.aws:ro", you are setting the .aws directory to read-only because you are using ":ro".
For a workaround, you can remove ":ro" from the argument.

@CamileDahdah
Copy link
Contributor

Hello @mabead,

Just wanted to inform you that a fix was pushed. Please re-open ticket if you still encounter the same problem.

Thank you.

@github-actions
Copy link

⚠️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.

@mabead
Copy link
Author

mabead commented Dec 16, 2022

Thanks a lot @CamileDahdah 👍 Do you know if nuget packages that include the fix are already available for consumption?

@CamileDahdah
Copy link
Contributor

CamileDahdah commented Dec 16, 2022

No problem! Yes Nuget packages should be up-to-date by now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. credentials p0 This issue is the highest priority queued
Projects
None yet
Development

No branches or pull requests

4 participants