How to store your secrets in your local development environment?
By Steve Carrupt
Published or Updated on Apr 22, 2022
I've been exposed to different methods to store sensitive data in my local dev environment over the years. From keeping secrets in version control to saving them in a password manager. Which ones should your team use or avoid?
version control
Your team should avoid storing secrets and API keys in plaintext in their repository. It seems common sense, but it always surprises me how often I saw teams doing that during my career. By saving those credentials in your repository, you decided to share them with anyone who has access to it. That might include external consultants and contractors.
Git makes it painful to remove sensitive data from the source code history. Thus, it is not enough to delete those data from your current version as they still exist in Git history. Knowing previous passwords may also help an attacker guess future passwords.
Finally, following the Twelve-Factor principles for configuration is a recommended engineering practice. You should be able to make your codebase open source anytime without compromising your credentials.
dotenv
Another approach is using dotenv and keeping your secrets in a file with your non-sensitive data. dotenv will load those secrets into your programming language environment.
You don't want to check that file into your public repository. It can be a costly mistake.
Also, if someone has access to your machine, such as an administrator, it is easy for him to read the content of that file.
.bash_profile
A better idea would be to save your secrets in your .bash_profile. Then, you will have access to those variables in each of your shell sessions.
Your .bash_profile file might become significant when you are working on different projects. Moreover, you cannot define similar variable names for each of your projects. Thus, it will force you to prefix your variables and not follow a good naming convention (e.g., PROJECT_1_API_KEY).
It also suffers from the same disadvantages as a dotenv file. An administrator of your machine could access your .bash_profile file. You might also commit your secrets to your public dotfiles repository by accident.
Another overlooked issue is your terminal exports the environment variables to all processes running under a session. A crash reporter tool could create a snapshot and sends logs along with those variables. The vendor that received that report can now read these sensitive data.
direnv and Lastpass
You could use direnv to restrict the export scope of your environment variables. direnv uses a .envrc file that you create in your project directory. By entering a folder via your terminal, direnv will export the variables in your session. As soon as you leave the folder, direnv will unload them. It also allows you to have the same variables name between different projects.
Yet, you will experience the same problems as the dotenv and bash_profile files. You could commit these files by mistake, or someone could access them.
To remediate these problems, you could combine direnv with LastPass. At first, you should create a note in LastPass containing your secrets.
LastPass provides a command-line tool to query your vault. On macOS, you can install it as follows:
brew install lastpass-cli
You should also login into your LastPass' account via the command line:
lpass login $my_username
Finally, you can add the following line to your .envrc file:
# .envrc
export $(lpass show --notes $my_project_secrets | xargs)
Each time you enter your project directory, direnv will execute that command. Then, LastPass will ask you to enter your vault password. Finally, direnv will export the secrets listed in your note to your shell session.
Unfortunately, LastPass stores your secrets on their infrastructure, which you don't control. Although your data are encrypted and only you can decrypt them using your vault password. The risk that someone stole your data is low.
Security-wise, sharing a unique account between many people is not a great idea. Every time someone leaves your team, you would want to change your vault password. Besides, it is easy to save your private passwords into your shared account by mistake. It happened to many of my colleagues 😂. So, I recommend you pay for a LastPass Team license, so your team can share notes and passwords.
Finally, you could also keep your credentials for your other applications such as AWS, Google Analytics, etc in your vault.
direnv and KeepassXC
Your company might not have access to LastPass. It forbids you from storing sensitive data on external infrastructure. In those cases, your team could replace Lastpass with KeepassXC. KeepassXC is open-source and also provides a command-line tool. The command to export a note is:
# .envrc
export $(keepassxc-cli show $my_database.kdbx_path $entry_name -a notes | xargs)
KeepassXC uses a local database file to store the data. Your team can then share that file using your company infrastructure. Thus, it would be a great idea to set up a daily backup of that file if someone accidentally deletes it.
Also remember to have separate databases for your shared and private passwords.
HashiCorp Vault
You could also bring out the heavy artillery by deploying HashiCorp Vault to your server. HashiCorp Vault is a tool for accessing and deploying secrets across applications and infrastructure. It also provides plugins for auto-rotating your secrets.
You could also retrieve your secrets by using direnv. Another way is to access them from your application. The latter approach is safer as your secrets won't live in a session. But it also introduces new problems. You might need to deploy Vault on many nodes to provide high availability.
HashiCorp Vault also provides a browser plugin, although only for Chrome. Thus, you will have to install it yourself and even change some code. Also, the plugin doesn't provide all the convenient features of other plugins (e.g., generate and auto-populate passwords).
Another disadvantage is your team or company needs to maintain the Vault infrastructure. You have to keep it updated with security fixes.
Takeaways
Your team should not store its sensitive data in their version control. Each of the other solutions has advantages and disadvantages. Unfortunately, mistakes can happen, and cyber-security attacks are on the rise. That's why I prefer to store my project credentials in a password manager.
I've used direnv and LastPass in many projects for different teams. The benefits of not juggling between private and team-specific databases or managing infrastructure outweighed the risks of storing secrets in a 3rd party infrastructure.