Skip to content
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

Using SSO in .NET Core with Docker Compose #3438

Closed
davidkeaveny opened this issue Aug 12, 2024 · 7 comments
Closed

Using SSO in .NET Core with Docker Compose #3438

davidkeaveny opened this issue Aug 12, 2024 · 7 comments
Labels
bug This issue is a bug. credentials p2 This is a standard priority issue

Comments

@davidkeaveny
Copy link

Does anyone have a good example of how to get a .NET 8 application running locally in Docker Compose if I am using SSO? All the examples I have seen at the moment assume you want to put your secrets into appsettings.json, which is not really a good practice. I'm using the current SDK libraries:

  • AWSSDK.Extensions.NETCore.Setup/3.7.301
  • AWSSDK.SecurityToken/3.7.400.2
  • AWSSDK.SSO/3.7.400.2
  • AWSSDK.SSOOIDC/3.7.400.2

My application code looks something like this:

var builder = Host.CreateApplicationBuilder(args);

var options = builder.Configuration.GetAWSOptions();
builder.Services.AddDefaultAWSOptions(options);
builder.Services.AddAWSService<IAmazonSQS>();

var host = builder.Build();
host.Run()

and my Docker Compose file is:

services:
  my-app:
    environment:
      - AWS_PROFILE=my-sso-profile
      - AWS_REGION=ap-southeast-2
      - AWS_CONFIG_FILE=/app/.aws/config
    volumes:
      - ~/.aws:/app/.aws:ro

If I then sign in to AWS SSO and then launch the app in Docker Compose:

> aws sso login --profile my-sso-profile
> docker compose up -d

then my app will report the following:

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)

If I browse the running container, I can see the .aws file has mounted successfully, and I can see its contents.

If I am going to be running this in EKS once I deploy to an actual environment rather than running locally, I want it to use the role associated with the deployment; that part seems to work okay.

Any idea how I can resolve this issue?

@dscpinheiro
Copy link
Contributor

We received a similar report with the error message you're seeing a couple of years ago (#2477). The root cause was the SDK was not handling the :ro flag properly (it tried to cache the SSO token but it wasn't accounting for a read-only file system).

However, that should be fixed in the latest version (I just tried it with a sample console app and it succeeded - although I used a standalone docker run command instead of docker compose). If removing the flag isn't possible, would you be able to share more details about your environment? It's possible we may have missed an edge case.


And yes, when deploying to EKS the SDK will use the container credential provider - fetching credentials from the environment and not the shared configuration file.

@bhoradc bhoradc added bug This issue is a bug. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. p2 This is a standard priority issue labels Aug 13, 2024
@ashishdhingra ashishdhingra transferred this issue from aws/dotnet Aug 13, 2024
@davidkeaveny
Copy link
Author

HI @dscpinheiro , this is what I'm currently running:

  • Windows 11 Pro 23H2
  • Docker Desktop 4.32.0 (157355)
  • AWS CLI 2.17.32

The NuGet packages I have direct references to are:

  • AWSSDK.Core 3.7.400.2
  • AWSSDK.Extensions.NETCore.Setup 3.7.301
  • AWSSDK.SecurityToken 3.7.400.2
  • AWSSDK.SSO 3.7.400.2
  • AWSSDK.SSOOIDC 3.7.400.2

I am building my Docker image to run as non-root, and my Docker file looks like this:

FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
WORKDIR /app
USER $APP_UID

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["my-app/src/MyProject/MyProject.csproj", "my-app/src/MyProject/"]
RUN dotnet restore "my-app/src/MyProject/MyProject.csproj"
COPY . .
WORKDIR "/src/my-app/src/MyProject"
RUN dotnet build "MyProject.csproj" -c Release -o /app/build --no-restore

FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish /p:UseAppHost=false --no-restore

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyProject.dll"]

I have tried running without the :ro flag, and it doesn't seem to make any difference.

Is there any other information that I can give that might help?

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Aug 20, 2024
@davidkeaveny
Copy link
Author

I've created a simple solution to illustrate the problem : https://github.com/davidkeaveny/aws-sso-docker

If I set the AWS_PROFILE and AWS_SSO_SESSION environment variables in the docker-compose.yml, sign in to my AWS session, and then run the application, it errors:

info: AWSSDK[0]
      Found credentials using the AWS SDK's default credential search
fail: Microsoft.Extensions.Hosting.Internal.Host[11]
      Hosting failed to start
      Amazon.Runtime.AmazonServiceException: Unable to get IAM security credentials from EC2 Instance Metadata Service.
         at Amazon.Runtime.DefaultInstanceProfileAWSCredentials.FetchCredentials()
         at Amazon.Runtime.DefaultInstanceProfileAWSCredentials.GetCredentials()
         at Amazon.Runtime.DefaultInstanceProfileAWSCredentials.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.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
         at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
         at MyProject.QueueLister.ExecuteAsync(CancellationToken stoppingToken) in /src/QueueLister.cs:line 9
         at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
         at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)

If I replace those environment variables with AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN instead, then the application runs as expected and lists SQS queues. It's only when I try to use SSO that it fails.

@dscpinheiro dscpinheiro added needs-triage This issue or PR still needs to be triaged. needs-review and removed needs-triage This issue or PR still needs to be triaged. labels Aug 20, 2024
@dscpinheiro
Copy link
Contributor

Hi @davidkeaveny, sorry for the delay in the response but I believe I found out why you were running into that problem.

The SDK caches a few values when authenticating with SSO in the ~/.aws/sso/cache folder (and unlike the ~/.aws/config file, that location cannot be changed via environment variables). By setting AWS_CONFIG_FILE, the SDK ended up looking for credentials in the wrong place.

If I update the docker-compose file to map the ~/.aws local folder to the home folder in the container, the application works as expected:

services:
  my-app:
    image: my-app
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      - AWS_REGION=ap-southeast-2
      - AWS_PROFILE=my-profile
      - AWS_SSO_SESSION=my-sso-session
    volumes:
      - ~/.aws:/home/app/.aws
2024-08-30 13:03:08 my-app-1  | info: AWSSDK[0]
2024-08-30 13:03:08 my-app-1  |       Found credentials using the AWS SDK's default credential search
2024-08-30 13:03:08 my-app-1  | info: Microsoft.Hosting.Lifetime[0]
2024-08-30 13:03:08 my-app-1  |       Application started. Press Ctrl+C to shut down.
2024-08-30 13:03:08 my-app-1  | info: Microsoft.Hosting.Lifetime[0]
2024-08-30 13:03:08 my-app-1  |       Hosting environment: Production
2024-08-30 13:03:08 my-app-1  | info: Microsoft.Hosting.Lifetime[0]
2024-08-30 13:03:08 my-app-1  |       Content root path: /app
2024-08-30 13:03:09 my-app-1  | Found queue https://sqs.ap-southeast-2.amazonaws.com/111122223333/lambda-dlq
2024-08-30 13:03:09 my-app-1  | Found queue https://sqs.ap-southeast-2.amazonaws.com/111122223333/lambda-on-failure
2024-08-30 13:03:09 my-app-1  | Found queue https://sqs.ap-southeast-2.amazonaws.com/111122223333/lambda-on-success

Can you try it and let us know if that works for you too? And as I mentioned in other reply, when you deploy your application to EKS you won't need to set these environment variables manually, the service will handle that for you.

@dscpinheiro dscpinheiro added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed needs-review labels Aug 30, 2024
@davidkeaveny
Copy link
Author

davidkeaveny commented Sep 1, 2024

Thanks @dscpinheiro your solution works for me!

There isn't a huge amount of documentation around using SSO with Docker Compose - is this nugget of information worth capturing somewhere?

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Sep 2, 2024
@dscpinheiro
Copy link
Contributor

Probably, as you said our documentation could be better.

If you have specific suggestions, please leave feedback on our developer guide page about SSO (https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/sso.html) and our docs team will review it.

Copy link

github-actions bot commented Sep 3, 2024

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.

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 p2 This is a standard priority issue
Projects
None yet
Development

No branches or pull requests

4 participants