HACKER Q&A
📣 TheBigDuck234

What tools should I use to manage secrets from env files?


My cofounder accidentally exposed a bunch of our API keys and we didn't know until we got a billing alert. I've wanted to use a secrets manager before and have asked a few friends what they use for advice, but I want to see what I may have missed.


  👤 klodolph Accepted Answer ✓
The place I work has a list of security guidelines that is, like, ten pages long and full of links to more detailed explanations.

The exact advice depends on how you’re running your services. My starting advice, for cloud, is this:

1. Run in multiple, separate accounts. Don’t put everything in one account. This could be as simple as having a beta account for testing and a separate production account.

2. Use cloud-based permissions systems when possible. For example, if you are running something on AWS Lambda, you create an IAM role for the Lambda to run as and manage permissions by granting them to the IAM role.

3. If that’s not possible, put your credentials in some kind of secrets management system. Create a process to rotate the secret on a schedule. I’d say 90 days is fine if you have to rotate it manually. If you can rotate it automatically, rotate it every 24 hours.

4. Set up logging systems like CloudTrail so you can see events afterwards.

Finally, as a note—people at your company should always authenticate as themselves. If you are TheBigDuck234, then you access your cloud resources using a TheBigDuck234 account, always.

This is just the start of things.


👤 mrl5
This is an interesting alternative to password manager, esp. if you want to version control your secrets https://github.com/getsops/sops

👤 starwatch
There are varying degrees to this but I'll focus on the early stage, low effort approaches I've found work.

For an easy, slightly hacky version I've used git-crypt (https://github.com/AGWA/git-crypt) with tiny teams. You'll need to share the decryption key (e.g. via 1password shared vaults).

As your need for security grows (but you're still not working with a giant team) you're better off using non-committed .env files locally (with need-to-be-shared dev keys stored in shared vaults in 1password) and prod GCP/AWS secrets managers remotely.

Once you work with a bigger team you'll need to start minting API keys limited in scope to each individual, for them to work with locally. The prod keys will only live in the remote environment, managed by some kind of secret manager offered by the platform and will need to be rotated frequently.


👤 solardev
Does your team already use a password manager? (If not, they probably should)

Some of them have secrets management built-in too, like:

- https://1password.com/developers/secrets-management

- https://bitwarden.com/products/secrets-manager/


👤 thomascountz
For Mac, I use `security set-generic-password` and `security find-generic-password` to manage secrets using Keychain.

Inspiration here: https://gist.github.com/bmhatfield/f613c10e360b4f27033761bbe...

Then you can share a dotfile that includes:

export OPENAI_API_KEY=$(keychain-environment-variable OPENAI_API_KEY)

And share/set the variable in Keychain.


👤 hiatus
If you are in AWS you can use Secrets Manager or Parameter Store and encrypt via KMS with access to everything mediated by IAM.

👤 pak9rabid
I use a hybrid approach of .env files and whatever secret manager my cloud platform has available (in this case, AWS Secrets Manager), where anything that's sensitive that needs to be present within the .env file is essentially a macro that gets resolved later by a library I've written.

For example, my .env file may have something like this in it:

DB_PASSWORD = @AWS::db_password

Whenever my library reads a value that begins with `@AWS::`, it knows to resolve (and cache) that value by querying AWS's Secrets Manager at runtime and looking for the config setting set there (`db_password` in this case).

This is nice because I can check-in these .env files since they don't contain anything sensitive, but still gives me the flexibility to hard-code in secrets when working locally in my dev env.


👤 proaralyst
If you're already using systemd, you can use its built-in credentials manager[0] which uses a combination of an on-disk key and the TPM2 to encrypt secrets at rest.

Probably annoying if you have more than one machine though

[0]: https://man.archlinux.org/man/systemd-creds.1


👤 withinboredom
I would suggest NOT using env files. They are a hack. The environment belongs in the environment, not a file on disk; and if it is on a file on the disk, it belongs outside your repository.

There is a script in the repository that will bootstrap your local env by storing encrypted secrets into ~/.config/ by asking some questions that you get from the shared passwords manager for development credentials. The key to decrypt them is password protected and requested at application boot.


👤 ali_piccioni
In priority,

1. Stop using API keys. Configure SSO integration for developers and OIDC for automation. For example, this is very easy to setup with AWS.

2. If the above is not possible, then store credentials encrypted at rest. Decrypt them only at runtime. For example, SOPS to store encrypted credentials into the repo, then AWS KMS holds the decryption key. The SOPS Readme is very helpful.


👤 theozero
Another new (open source!) tool to check out in this space is https://dmno.dev

It's a bit different than most of the other tools listed here, in that it is designed to generally solve the papercuts of dealing with config (both sensitive and not), and is not coupled to storing your sensitive config in a specific platform (paid or otherwise).

You define a simple schema for all of your config, and you get validations, built-in documentation, full type safety, and the ability to compose config together in any way you choose. You can also easily share config across a monorepo (if you are using one).

Additionally, our drop-in integrations (node, vite, nextjs, astro, remix, more on the way) go a bit deeper and do things like help you detect and stop leaked secrets, redact secrets in logs, and deal with the footguns of boot vs build time config in hybrid rendering environments.

As for storing/syncing sensitive data, we currently have 2 plugins but more are in the works and will be guided by user demand. The first lets you store your secrets encrypted within your repo (like dotenvx, git-crypt, etc), and the second lets you sync with 1password. Personally we think the 1password plugin makes sense for a lot of teams, since they are probably already using it. You can wire up individual items to your schema, or pull from dotenv style text blobs. You can (and should!) segment items into multiple vaults, and use multiple service accounts to access them. You can even mix and match plugins to pull secrets from multiple services.

(see https://dmno.dev/docs/plugins/encrypted-vault/ + https://dmno.dev/docs/plugins/1password/)

In the future, we'll have deeper support for things like key rotation and single-use keys, k8s, way more backends, etc. It's all open source, so come and tell us what you need (or even help us build it) and we'll make it happen!

If it's not obvious already, I am the creator :)

PS - Feel free to hit me up for more info or a demo - theo at dmno dot dev


👤 gchamonlive
I usually have .env files in the repositories with the structure and examples. It's a kind of documentation. But I have a template file that gets filled by the CD pipeline with the necessary set of secrets that the deployment need.

I advise against dynamic secrets. In my opinion deployment should be immutable. If you need to change secrets, you need another deployment. The usual exception is where the deployment is too costly or you can't do zero-downtime blue-green/canary deployments.

The template file can be something like a .env.j2 and the secrets can be pulled from something like hashicorp vault, which enables you granular permission for the pipeline runners to read just the necessary kinds of secret that particular deployment needs.

You need however to put a little effort into creating these pipelines, but the benefits are huge.


👤 CMCDragonkai
Usually `.env` files are sourced into your development shell and also ignored by `.gitignore`.

The problem with `.env` files is that you're leaving credentials unencrypted on disk and it's easy to leak these files during screen sharing and with multiple projects there will eventually there will be so many secrets spread/sprawled everywhere that you lose track of what credentials are being used and what are expired. You want to be able to inject the required keys only when needed and leave no trace behind when not needed.

I wrote about this in our documentation for Polykey: https://polykey.com/docs/how-to-guides/developers/developmen...

We are still working out the kinks but I expect that one should be able to easily do `. <(polykey secrets env project-vault)` in whatever development shell you have, perhaps even reference a schema for expected keys.


👤 PaulHoule
What about https://dotenvx.com/ ?

👤 lasermike026
Don't store secrets in env files. Use a secrets manager and a password manager. Configure SSO for everything. Use MFA for everything. Rotate your keys regularly. Do not allow long-lived user accounts to exists.

https://aws.amazon.com/secrets-manager/ https://keepersecurity.com/

What is a long-lived user account? https://g.co/gemini/share/84c224b18bf0


👤 jamesmkenny
Oh! That's never nice, but it's always better when someone else does it.

Check out https://onboardbase.com/. It's pretty handy for keeping secrets secret.


👤 radiator
Using https://www.gopass.pw, which stores secrets in git, and thus also works for teams. Also possible to access the secrets programmatically.

👤 swoorup
A while ago, I had this exact problem and I threw a template together using a combination of age + passage + agenix (nix) solution to automate my secret management solution.

https://github.com/Swoorup/passage-nix-secrets-template

EDIT: This is meant to used in a nix-based deployment setting, and also you don't want to commit the identities file unless you use yubikeys (Something which I forgot to mention in the readme).


👤 rguldener
I heard good things about Infisical (open source, end to end encryption of secrets): https://infisical.com/

👤 jumploops
The tl;dr here is:

1. Load secrets dynamically at runtime

2. Share internal creds via e.g. 1Pass

Environment variables (+managing them with .env files) are a better start than putting keys in your codebase, but this can also be leaky/hard to keep up to date.

Most cloud providers have some sort of secret management tool. Vault by Hashicorp is another solid option if you want to run your own.

If you’re hosted on AWS, I’m personally a big fan of Credstash[0], which is basically a simple wrapper around DynamoDB+KMS.

Cheaper than the AWS Secrets product and fast enough.

I previously built a config that would take secrets from Credstash, env vars, and .env files (in that order). This offered the best of both worlds for local and remote deployments.

[0]https://github.com/fugue/credstash


👤 cpach
If you want an overview of available tools, I published one a while ago: https://hsm.tunnel53.net/article/secrets-management/

If you want something simpler, have a look at SOPS: https://github.com/getsops/sops



👤 juliend2
So far, I find Ansible Vault to be good enough for this (when using Ansible at least): https://docs.ansible.com/ansible/latest/vault_guide/index.ht...

You still have to "manage" the vaults' passwords, though.


👤 Hikikomori
AWS SSM for service credentials.

For users use federated auth/sso with temporary credentials or static user keys that require 2fa with aws-vault.


👤 dp-hackernews
You may wish to consider these also;

git-crypt - https://www.agwa.name/projects/git-crypt/

Or

blackbox - https://github.com/StackExchange/blackbox


👤 moi2388
If you develop in .Net, User Secrets. Best idea ever.

If you don’t, .env files with a proper .gitignore

Or AWS secrets manager, GitHub secrets, Azure KeyVault and inject them.

If you run on something like Azure, use Managed Identities. Passwords shouldn’t be used period. API keys should be securely injected in a pipeline from a vault.


👤 hk1337
You could put them all in Secrets Manager or Parameter Store, whichever is appropriate for the secret, then have your CI process fetch the secrets and setup your environment. That way, developing locally does not depend on access to AWS Secrets Manager or Parameter Store.

👤 mahmoudgalal
I use Onboardbase, it has a lot of features, where I can manage different environments, and its very easy and developer friendly most of the team is very responsive for your thoughts

https://onboardbase.com


👤 cdaringe
People keep talking about cloud vault providers, but a lot of my secrets are mine alone. I just macos keychain at devtime. There a nice little libs for interacting with it with your language of choice

👤 dsmurrell

👤 TheBigDuck234
We ended up going with Doppler for secrets management. Was super easy to set up. I looked at a few others, but we would either need to self host or they were going to be clunky to set up. No more .env files to leak!

👤 two_cents
https://github.com/tellerops/teller works good for me.

At work we use Ansible to fetch secrets from Hashicorp Vault.


👤 ulises22

👤 igor47
I wrote a little tool for this! https://github.com/igor47/dcsm

👤 samgranieri
I use direnv with a global gitignore, 1Password and chezmoi. There’s also secrets pulled down from vault.

👤 ramon156
You can have a shared password manager, 1password is good for this. I forgot how expensive it is, but for families its like 3 euros

👤 techn00
New account, mentions going with Doppler, a few "use doppler" comments as well. Sketchy as fuck

👤 faangguyindia
IP whitelisting. Use private IPs and VPN (for connecting to developement platform)

This way credentials leak will not do much


👤 mise_en_place
You could use SSM or the Secrets Manager. Although IAM is it's own nightmare realm.

👤 aaomidi
Getting rid of secrets to begin with.

👤 TZubiri
Read()

👤 smallerfish
Doppler is nice.

👤 presentation
I really enjoy using Doppler. https://doppler.com