For years, I’ve always found myself having conversations about secret storage for local development environments. To those who ask, my response is always never add your secrets to your ~/.bash_profile. The reason is simple, you will either accidentally leak a secret or commit it. There exists a delicate balance between the productivity gain by having the environment variable exposed while keeping that secret safe and out of your environment by default.

But why is this bad?

All that glitters is not gold when it comes to environments. For example, using a local .env file allows you to set the environment for your project, but it may not always be excluded within .gitignore. Similarly, if you set your secrets in ~/.bash_profile, you may accidentally commit your secret token to your personal dotfiles repo on GitHub.

To put another overlooked issue into perspective, when you set environment variables within your shell, it is exported to all the processes that run within the context of that shell session. When you run VSCode, Atom, a debugging tool, or anything of the like from your command line environment, your ENV variables are available to those processes. When things like debugging utilities or crash reporters get called, they grab a snapshot of the issue, and more often than not, environment variables are sent with the logs.

If you have a privileged API token for a service like Stripe, Amazon or GitHub always in your environment, then the vendor who received that debug output from you now can access to that data.

On-Demand Setting of Secrets

Moving to an on-demand approach for setting and unsetting secrets is my preferred approach. I am only setting a token to the ENV if I know I absolutely need it. On-demand secret setting allows me to control when and what processes can view the token. There are different approaches you can take to limit exposure from running configuration management systems or secret managers like Vault locally and federating the encrypted secrets. That is one approach, but not all companies have the same approach or development work stream.

This is where using setter functions within Bash/Zsh can help manage your environment.

Add Secrets — A secret setter

addsecret is a helper function that creates a directory within your $HOME directory called .private/. The script takes two arguments, what you want your secret to be called and the value. If adding the secret is successful, it will give you the environment variable that will be exported when you set it, along with the set command for your secret.

Integrating Within Your Environment

To allow for seamless integration with your shell profile, you can add the following to your bash profile so your secret setters are loaded for every new shell session:

You can even do fun things like adding an indicator to your shell prompt since HAS_token-name is exported when it’s set:

Conclusion

This method helps keep secrets directly out of the bash environment, until explicitly called. This will not only give you an organized directory for your secrets, but it also gives you peace of mind around what is automatically loaded into your environment.

I would suggest you cat ~/.bash_profile | grep export or run the export command and review the secrets your environment is currently configured to always set.

Share this post