7

I use .env files in my node.js code to handles secrets in my dev environment configuration. I add .env to my project's .gitignore, to prevent secrets be committed to the git repository.

I found node.js's .env approach quite simple and productive.

What the equivalent of .env files in C#?

With this question I am not looking for a library to do the same in C# like (https://github.com/tonerdo/dotnet-env)

I like to know the c# way of handling the same thing with an emphasis on not committing secrets in config files to git repositories.

This is not an Azure question, so Azure Key Vault Azure App Services are out of scope here.

Update #1

Please note that I am not asking to to handle secrets in my .net applications.

I have been using the options in the document below for many years:

https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-6.0&tabs=windows

Once I started to learn node.js and using .env I wish I have the same in .net.

.env files save me from keep tweaking environment variables while I develop node.js apps on my developer laptop. In production I set the env variables.

On my local developer laptop I like to keep my environment variables in a .env text file. I trust my local laptop encrypted hard drive and there is no production passwords involved in my dev environment.

In essence I am trying to avoid the option below and the hassle of keep tweaking environment variables while I code.

enter image description here

Update #2

This scenario might highlight the advantage of .env files:

When I develop node.js apps, In VSCODE, I have the .env file open in a separate tab to keep changing variables and run my node.js application in the vscode terminal. The scenario is to try different service principles, different database credentials, network credentials etc while I debug/trace my application. To do the same in c# or .netcode projects quickly, I have to have a bash script to set the environment variables, tweak it every time before and trace/debug my application.

While it is important to remember to add the set-secret-env-vars.sh to the .gitignore file, please consider the node.js's standard .gitignore file already includes the .env because the process is standard and streamlined in node.js applications.

Please note that I used to use the set-secret-env-vars.sh approach while coding and debugging my node.js apps. Then learned about .env and found it more convenient. That is why I am trying to find a simialr approach for c# app development workflow.

Update #3

To my understanding, most of the options/workarounds discussed here are specific to an IDE or tool.

launch.json is feature of VSCODE. You need to launch your code using VSCODE if you want to benefit. With .env approach, I can run node app1.js or node app2.js etc.

What happened if I need to develop using JetBrain's Rider? It is a well respected .net IDE.

My point is that .env is not depending on any IDE and to my understanding it is very well adopted by many other platforms such as Python.

Allan Xu
  • 7,998
  • 11
  • 51
  • 122
  • Does this answer your question? [How can I save application settings in a Windows Forms application?](https://stackoverflow.com/questions/453161/how-can-i-save-application-settings-in-a-windows-forms-application) – Progman Oct 12 '22 at 19:02
  • @Progman, the post you are referring to is a different topic. The node.js's .env files bring a significant convenient for dev environment that I think it is missing from .net. Let me update my post. – Allan Xu Oct 13 '22 at 22:01

2 Answers2

3

If you are taking about .Net applications, then you could use User secrets in your local. This will not be checked in as the file is not part of the solution and no need to even keep it in gitignore

Usage : In Visual Studio, right-click the project in Solution Explorer, and select Manage User Secrets from the context menu.

Refer https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-6.0&tabs=windows for more details

WisdomSeeker
  • 854
  • 6
  • 8
  • Okay. Now i don't understand the problem. What do you mean by *"hassle of keep tweaking environment variables while I code"*. The user secrets is indeed kept as a system file and is not checked in. It will be used for the local development. In prod, you are using env variable set in server. – WisdomSeeker Oct 14 '22 at 05:40
  • Are you looking for something like a different setting file for each environment? Like https://stackoverflow.com/questions/46364293/automatically-set-appsettings-json-for-dev-and-release-environments-in-asp-net-c – WisdomSeeker Oct 14 '22 at 05:44
  • "Now i don't understand the problem". Please see my Update #2. – Allan Xu Oct 14 '22 at 20:46
2

I'll give you what I consider a solid answer, but at the same time acknowledging that there are other options.

What dotenv does is basically create environment variables for the NodeJS process. Then those are accessed through process.env. That's all.

If you want the equivalent in C#, that's already available out of the .Net Configuration box.

Speaking in terms of ASP.net, it comes with pre-defined configuration sources. One of them is the non-prefixed environment variables source. This one picks up data from environment variables that follow a standardized name convention.

Say you have appsettings.json like this:

{
    "SecretSection": {
        "Username": "myUsername",
        "Password": "CatOnKeyboard"
    }

If you were to have that JSON config file, you probably have a class declared in C# (named, say, MySecretSection) with the properties Username and Password that you configure in your services like this:

var cfgSection = builder.Configuration.GetSection("SecretSection");
builder.Services.Configure<MySecretSection>(cfgSection);

This would allow you to obtain access to the section's data using the Options pattern:

public class SomeService
{
    public SomeService(IOptions<MySecretSection> secretOptions)
    {
        // Now you can use the username and password:
        var opts = secretOptions.Value;
        System.Diagnostics.Debug.Print($"{opts.Username} : {opts.Password}");
    }
}

Ok, but the secret data definitely should not be there, in appsettings.json, exposed to the public.

If you want, you can do what dotenv does and simply create environment variables for each of the secrets.

  1. SECRETSECTION__USERNAME with a value of myUsername.
  2. SECRETSECTION__PASSWORD with a value of CatOnKeyboard.

And that's it. Asp.Net will automatically pick up those environment variables that, according to the naming convention, represent the hierarchical key SecretSection:Username and SecretSection:Password.

Response to your Update #2

To do the same in c# or .netcode projects quickly, I have to have a bash script to set the environment variables, tweak it every time before and trace/debug my application.

No. Why? Do EXACTLY the same thing you do with your .env but the file would be launch.json. And you do it exactly the same way: Keep tweaking and running, no scripting involved. Is it maybe that you don't know that you can set environment variables in launch.json (VS Code)/launchSettings.json (Visual Studio)?

Response to your Update #3

I understand what you mean. I will now welcome you officially to the far superior .Net configuration system.

You see, you have lived in the NodeJS world with a very limited configuration package (dotenv), whereas .Net offers you a far, far superior configuration system.

Do you want to avoid scripting? Do you want to just update one file and re-run, no recompilation and not bound to an IDE? .Net has your back: Make your tweaks in appsettings.json or appsettings.<environment>.json and restart. If you want, you can even avoid restarting if you tweak with the configuration's configuration.

Side Note: I created a configuration package for all your JavaScript needs (server and browser) that mimics what .Net offers: wj-config

José Ramírez
  • 872
  • 5
  • 7
  • Thank you for help. But .env saves me from keep tweaking environment variables while I develop node.js apps. In production I set the env variables. With the workflow you explained above I have to keep tweaking env variables. – Allan Xu Oct 13 '22 at 21:56
  • Not really. Do you keep tweaking .env files? No, you set them up once and that's it. In .Net, you set your development env variables in launch.json and that's it (or LaunchSettings.json if you use Visual Studio). When you deploy maybe you set them once as secrets in Kubernetes once and that's it. You don't have to continuosly set them everywhere. You set them once per environment depending on the deployment method and infrastructure and that's it. – José Ramírez Oct 14 '22 at 04:32
  • "Do you keep tweaking .env files? ", yes I do. Please see my update #2. – Allan Xu Oct 14 '22 at 20:45
  • Updated my answer to answer you. Basically it is exactly the same thing in C#. – José Ramírez Oct 14 '22 at 22:32
  • Also note that, if the data you're tweaking is not a secret and can be in source control, you can forget environment variables and just use a file called `appsettings.Development.json` and change your values there. – José Ramírez Oct 14 '22 at 22:35
  • Than you so much for engaging with this discussion. Please see my Update #3 – Allan Xu Oct 15 '22 at 17:19
  • @AllanXu, I updated my response for your Update #3. – José Ramírez Oct 15 '22 at 19:08
  • 2
    .Net offers a "far, far superior configuration system", and likewise a far more confusing system. Probably why the question is asking for a "simple and productive" solution. – Stian Jørgensrud Apr 13 '23 at 06:46
  • I suppose people are entitled to their opinions. Cheers! – José Ramírez Apr 14 '23 at 03:57
  • So, using `appsettings.json`, if I were to build a docker image for my C# application, would I be setting the environment variables (i.e. `SECRETSECTION__PASSWORD`) inside of the docker image? – TranquilMarmot Jun 12 '23 at 05:37
  • 1
    @TranquilMarmot yes, that is one way to do it. You can also apply the environment variable's value through K8s secrets instead of hardcoding it in the Docker image. – José Ramírez Jun 12 '23 at 07:58