Reasoning about environment variables, secrets, and how to be safe

I think I’m probably showing my native-developer origins here. No worries if this is not something you deem worth the time clarifying.

I was thinking a bit more about secrets in Fly and how they can be set via the command line, which then sets environment variables at runtime. I don’t have the best understanding why this is a good security practice. I’d love a thought or two here or in the docs on how to reason about this vs. say including secrets in a text file. Not that I’ve done this, but it appears to be possible to get env variables from a running process, so the value-add isn’t obvious on the surface to me at least.

Maybe this is just me, but I’d love to see some thoughts / religion on this to build my intuition around when I might be about to do something stupid security-wise.

I don’t doubt you guys know what you’re doing, but I don’t want to cargo cult setting some env variables without understanding the value-add. Thank you!

Our secrets implementation is meant to isolate them in such a way that even if someone gets access to our API and database, they can’t decrypt them. When you set a secret, the API writes to Vault. But it doesn’t have access to read/decrypt. The process that launches your VMs gets a role that can read (but not write) your secrets, and injects them as environment variables.

It’s also mild protection against a developer on your org extracting secrets. You are correct that they could inject code and read the env vars, but I think the little bit of extra friction is helpful. It’s always bothered me that I can just read Heroku config variables from my CLI.

People do encrypt secrets in their repositories and then use one Fly secret to decrypt them. This is built in Rails functionality even. We don’t love putting secrets in GitHub, but I think it’s somewhat reasonable to do that.

Kurt, thank you for your quick and helpful response here! Gives me a better way to think about this. If you haven’t already done so, I’d definitely recommend adding some of this context to your secrets explanations in the docs. Really appreciate it.

There’s also the 12 factor guidelines that Heroku brought to the forefront for cloud deployments. The idea here is that exactly the same codebase can be used for production, staging and any number of unknown future environments — maybe one deployment per branch / pull request, which Heroku supports. This is pretty much impossible to do with files, because we don’t even know how many files we’d need. I’ve also seen one deployment per customer, and there again I wouldn’t want one file per customer in the codebase.

The encryption part of it is security-friction — not everyone in the company needs to see the Stripe production key or the AWS IAM access keys, and while a malicious employee could add code to read the env vars it’ll show up on pull request and code review etc, so enough of a prevention measure.

Thanks Sudhir! Really appreciate it. Also this is some great reading. Thanks for sharing.