Cannot access to secrets .net core with Docker

4.1k views Asked by At

In my .net core Api i use secrets.json:

{"UserServiceSecretKey": "secretKey123456"}

Evidently in my .csproj:

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <UserSecretsId>6da803bf-439d-4e34-8735-195d652e8366</UserSecretsId>
  <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>

And use in my Startup.cs ConfigureServicesMethod():

 var secretKey = Configuration["UserServiceSecretKey"];
        if (string.IsNullOrEmpty(secretKey))
            Console.WriteLine("Error: KEY UserServiceSecretKey cannot be null...");

If run the application on IISExpres it works (get the secret key).

But if i run the Api in docker like docker-compose, then in runtime the secret key is not obtained: enter image description here

In my docker-compose.override file i have:

tresfilos.users.service:
environment: 
  - ASPNETCORE_ENVIRONMENT= Development
  - ASPNETCORE_URLS= https://+:443;http://+:80
ports:
  - "7002:80"
  - "7003:443"
volumes:
    - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
    - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

Additional, i have defined the APPDATA environment variable:

enter image description here

How can i access to secret key when i run the Api in docker ?

3

There are 3 answers

4
Vivek Bani On BEST ANSWER

Docker secrets are loaded into memory as files inside /run/secrets directory, not as mounted directory, so you need to read it from memory

There are 3 steps,

1. docker-compose file

version: "3.9"
services:
  redis:
    image: redis:latest
    deploy:
      replicas: 1
    secrets:
      - my_secret
      - my_other_secret
secrets:
  my_secret:
    file: ./my_secret.txt
  my_other_secret:
    external: true

note: you can add secrets to docker either by using a file or by defining as external resource, which means that it has already been defined in Docker, either by running the docker secret create command or by another stack deployment. If the external secret does not exist, the stack deployment fails with a secret not found error.

2. Install a nuget package

Microsoft.Extensions.Configuration.KeyPerFile

3. Add a config entry to Startup.cs

config.AddKeyPerFile(directoryPath: "/run/secrets", optional: true);

0
Darrell On

In your compose file, you are mounting the dotnet usersecrets json file into the container at a path that the application host will expect - so that bit is fine - i.e the user secrets themselves are being placed inside the container and are therefore available to be loaded into its IConfiguration:

volumes:
    - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro

The reason these UserSecrets are not being loaded by your application when it runs as a container is most likely because this only happens automatically for "Development" environments. If you look closely at the environment variables you are setting on the container:

environment: 
  - ASPNETCORE_ENVIRONMENT= Development

You have an extra space? I suspect this is causing IHostEnvironment.IsDevelopment() to returen false, and so the host won't auto add the UserSecrets configuration provider to the configuration builder.

Note: Another answer talks about docker secrets. The format of these is different from the UserSecrets.json secrets. Therefore if you want to just use UserSecrets.json and have those apply to your application when running it with compose, mounting in the usersecrets.json is the correct way to go, not using docker secrets. However docker secrets can be used in addition or instead of User Secrets. UserSecrets are not recommended for production scenarios.

0
aam On

I encountered the exact same problem just now. Turned out I was targeting the wrong directory.

In my Dockerfile the local user's app was mounted in /app not /root. Changing the volume path in the docker-compose.override solved the problem and I was able to access the user secret.

volumes:  
 - ${APPDATA}/Microsoft/UserSecrets:/app/.microsoft/usersecrets:ro