Live data from Hacker News

Don’t use environment variables for configuration

nibblestew.blogspot.com

261–270 of 296 posts

Re: Don’t use environment variables for configuration

#261

Earlier quoted context omitted.

Or you could, you know, auth to vault and pull the creds from vault inside of your app?

You could, but then you’ll have replaced a universal and standardized abstraction with a hard commitment to one very specific approach. That doesn’t come cheap.

One thing that I like, which this approach allows for, is live configuration. For things like databases and such which allow for the regular rolling of credentials.

It's not simple by itself, but it simplifies other things.

Re: Don’t use environment variables for configuration

#262

Earlier quoted context omitted.

> Indeed, sometimes it seems like 90% of the Docker code out there is converting environment variables into configuration files. This is a consequence of Docker's choice of the "image" as an abstraction layer. It's not trivial to say "run this image but with this config file added" (yes you could bind mount one in, or create a new derived image, but those are both harder and come with more pitfalls). In most common d…

For automation you will store them in a file anyway, but then how is it different from a bind mount?

More usually, in k8s configmap.

Re: Don’t use environment variables for configuration

#263
post #84

Earlier quoted context omitted.

In typical Linux setups, cmdline is world-readable, but environ is not. So you never should put secrets in cmdline, but they are ok to be in environ. And that is pretty much the only difference between the two.

The environment is inherited by child processes. I think that is a very important difference.

Of the relevant Linux syscalls neither fork or clone touch argv or environ at all, on the other hand execve requires passing both argv and envp explicitly

Re: Don’t use environment variables for configuration

#264

Earlier quoted context omitted.

> Unfortunately they are visible to other users on the system, so they're no good for credentials. If you’re concerned about your own software logging credentials, command line arguments are negative in two regards: They’re highly visible when the process is running; they’re often automatically logged. > They aren't in the environment block, so a quick and dirty "dump all my environment variables to stdout" procedure…

> You also now have a config file: how is it stored? Hum... Your environment variables must be stored at some place too, so the server can be launched. You can store the files at the exact same place.

Sure — you throw them in the Kube secret manager.

But now you have multiple config files (smart) or your entire config outside the repo (not smart). This isn’t always the wrong approach — SSH keys get loaded this way, for instance.

ENV variables naturally provide a way to layer content from different sources in a way that files don’t, so if you have a relatively simple config from multiple providers (eg, getting AWS session token from the host plus your environment config from the launch ENVs) it’s easier to use the K-V store nature of ENV variables versus multiple files.

Again, multiple config files isn’t always wrong — but using that to store single strings instead of ENV variables is a code smell, for sure.

Re: Don’t use environment variables for configuration

#265
post #90

Earlier quoted context omitted.

Environ isn't actually key-value, it's only convention that applications (/libraries) parse it in the name=value form. But the underlying mechanism is similar to cmdline: array of pointers to strings. You could parse cmdline same way if you'd want.

Don't POSIX and portable C both require key=value? If so, isn't that more than just convention?

Righto, I was considering Linux only, I don't personally care much for POSIX. I don't think ISO C standard sets any strong requirements. But yes, if you want maximum portability then you probably should be pretty conservative with environment.

Re: Don’t use environment variables for configuration

#266
post #90

Earlier quoted context omitted.

Environ isn't actually key-value, it's only convention that applications (/libraries) parse it in the name=value form. But the underlying mechanism is similar to cmdline: array of pointers to strings. You could parse cmdline same way if you'd want.

Don't POSIX and portable C both require key=value? If so, isn't that more than just convention?

I don't know about POSIX, but C doesn't mandate an implementation. The C Standard says about getenv():

Quote:

The getenv function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are implementation-defined.

The implementation shall behave as if no library function calls the getenv function.

Returns

The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the getenv function. If the specified name cannot be found, a null pointer is returned.

End quote. The takeaway from me is that yes, environments do define a key/value store of some sort, but how they're implemented isn't stated. It can be an array of strings in "key=value" format stored in RAM, but it could just as well be a hash table stored in ROM.

Re: Don’t use environment variables for configuration

#267
post #266

Earlier quoted context omitted.

Don't POSIX and portable C both require key=value? If so, isn't that more than just convention?

I don't know about POSIX, but C doesn't mandate an implementation. The C Standard says about getenv(): Quote: The getenv function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are implementation-defined. The implementation shall behave as if no library function calls…

Also, the specification of getenv does not exclude of having other data in environment that is just not retrievable by getenv but would be accessible e.g. through the third argument to main that is mentioned in the common extensions section.

Re: Don’t use environment variables for configuration

#268
post #73
post #47

Earlier quoted context omitted.

> a command line build tool used by individuals that takes arguments and caches them in a per-project file That is literally one of the worst ideas I’ve ever heard of. And I’ve heard many bad ideas recently.

What's the alternative? That's how make, cmake, msbuild, ninja,docker, and basically every other build tool I'm aware of works

You take the arguments every time? Or you read them from a configuration file.

But you do not automatically add them to the configuration file unless the user explicitly tells you to do so.

Re: Don’t use environment variables for configuration

#269
post #176

Earlier quoted context omitted.

I used to agree with (2), but now I think Meh, it's an implementation detail whether the program uses my environment variable 'directly' or with a child process, it's not meaningful to make that distinction. When it is meaningful (and this is supported today) is to set them just for specific programs/invocations, rather than exporting for a long-running interactive shell (and everything within it) willy-nilly. More i…

Iiuc you are advocating for setting env vars at the call site, like `FOO_SECRET=hunter2 foobar`? In that case, why not just use command-line args and call it like `foobar --secret=hunter2`?

Because in the latter case the commandline of the executed process (which may be exposed in various places, including a simple process list) is `foobar --secret=hunter2` and in the former case it's just `foobar`.

Re: Don’t use environment variables for configuration

#270
post #131

Strongly disagree. Environment variables are, IMHO, best tool for some simple configuration in unix. They match perfectly with behavior of the ecosystem and other tools in it (like unix shell). Yes, if your OS is some unversal JS machine, then JSON would be better, if it is Lisp machine, then you would use S-expressions, but on Unix machine, environment/args are way to go. There are two realistic alternatives - confi…

Why I don't like environment variables: 1. I worry about programs dumping all their environment variables to log files - credentials are now on disk, ingested into log storage... 2. Environment variables are inherited by child processes by default. This is undoubtable useful. But it can also cause problems. I wish the ghosts of unix past had forseen the need for a way to mark particular variables as, say, 'sensitive'…

> I wish the ghosts of unix past had forseen the need for a way to mark particular variables as, say, 'sensitive' and 'noexport', allowing them to opt out of the default behaviour.

The default behavior is a non-exported variable. If you want child processes to see it, you must export it.

Post reply on HN