Hacker News new | past | comments | ask | show | jobs | submit login

> Is this... normal? I don't understand why they might want to serialize/access all of my env vars. Does anyone have a suggestion for that behaviour?

All processes get a copy of all environment variables [edit for clarity: all environment variables, from the global environment].

Unless one goes out of one's way to prevent this from happening.

> the process args included "JSON.stringify(process.env)" part

And this app choses to receive the env vars in a JSON format. NBD really, in light of the above points.

Environment variables are not secret at all. Quite the opposite: because all processes get a copy of them. They're just variables that are associated with- / stored in- the environment, instead of e.g. in code itself. They absolutely should not be considered to be secure in any way.

Managing secrets is always tricky. Even a naive attempt at trying to avoid using env vars generally leaks stuff in some way - shell command history will record secrets passed-in at launch time, plus any running process (with sufficient permissions) can get a list of running processes, and can see the command line used to invoke a process.

And once one gets past the naive solutions, it usually adds some friction somewhere along the line. There's no easy, transparent, way to do things, as far as I am aware. They all have some cost.

There are quite a few articles on the web about stuff this topic as a whole. I don't think anything particularly new will come from HN users here, it'll mostly be repeating the same already known/discussed stuff. As I myself am doing here, really.

You might find it helpful to consider something like Hashicorp's Vault, or similar, for proper management of secrets.




Using env vars for secrets has become semi-normalised because of container-based development and deployment. It's okay-ish in the limited context and scope of a container, but it's not good at all in a host OS or VM context. Some dev practices have leaked through, possibly because it's an approach that works in all environments even if it's not best practice


I think it was actually normalised long before container-based development was even a thing. It's always just been standard common practice — both in development and for live deployment.

With the assumption being that it's safe, if the box itself is safe (is secure and is running trusted processes).

You have to store the secrets somewhere, and at point of usage they are no longer secret. So one has to assume that any truly determined adversary will undoubtedly get hold of all secrets anyhow.

Anything else is all about minimising risk. And, as with all security practices, there is always a cost/benefit analysis that has to be made, and there will be some kind of cost/benefit tradeoffs made throughout the system / system design, as a result.

But regarding your original point: I would actually think that container-based development makes it easier to provide secrets to only the containers that need them, because e.g. with Docker, environmental variables can easily be specified in separate env files that are passed only to specific containers.


Thanks, I appreciate the detailed explanation.

I'm familiar with Vault and been using that at work — but we tend to fetch values from Vault and export them as env variables in the end anyway. Obviously we don't want to hardcode these values in the code either. So env vars are not good for secrets, hardcoding is terrible — what's good/secure then?


Env vars are fine for secrets, as long as you provide the right env vars to the right processes. You can unset them before launching a new process, or better still, not "export" the sensitive ones to all processes.


This ^^

Just avoid putting secrets in the global environment if it is a concern, and instead just pass necessary secrets locally in the environment when launching a specific app.


Ideally you would fetch values directly from Vault, e.g. using the REST API, ideally with SSL (but that depends on the environment your app is running in /etc.) or using the vault command.

One can either access the Vault REST API directly inside the app itself, or one can pull data from it in a script file that launches the app, etc. and set any necessary environment vars dynamically before launching the app.

e.g. in a launch script you might do something like (sorry, no idea how to do preformatted text on HN) :

SOME_KEY=$(curl [access-your-vault-appropriately-here-using-access-tokens-etc] | jq whatever)

Or, in wrapper launch scripts, instead of using the REST API directly with curl, instead use the vault command directly, if it's installed, e.g.

SOME_KEY=$(vault kv get foo/whatever)

Although you'd also need to do some calls upfront first, to authenticate and get an access token, before querying for data/secrets.

But doing these kinds of calls, in the global environment gives those secrets to, well, everything in the global environment.

If you need to pass a vault secret to some specific app, then you want to read from the vault as close to that app's launch as possible, e.g. in a wrapper script that launches that app (instead of launching it 'naked', and leaving it to read from global environment) - or by actually accessing the vault directly from within the app (which isn't gonna be possible with third-party stuff, unless it already supports your vault natively)




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: