Best Practices for Getting Sensitive Information Into Your Application
Many apps need access to sensitive information such as:
- API Keys
- Database Credentials
- SSL Certificates
- Shared Secrets
The common practices of today can become the potential security holes of tomorrow, so I’ll focus on some of the current concerns first, then give some suggestions of places to look for better options.
The Wrong Way
Hardcoding passwords used to be a surprisingly commonly used option - simply hardcoding the secret somewhere in the code. Sometimes it would be obfuscated in some fashion so it couldn’t be dumped simply using
strings, but this approach still has two major flaws:
- It can be read (even if it requires a bit of work) from anyone who has access to the source or the binary (if it’s a compiled language).
- It is very difficult to change. When your secret gets compromised or needs to change, you have to edit the code, rebuild/package and re-deploy. You don’t want to be woken up at 2 a.m. to dig through old code to find and change a key that got leaked. If you do move to a more secure method, you may want to take the opportunity to rotate keys and passwords.
Plain Text Config
Another common, less than ideal solution is to store the secrets in plain text in configuration files. The advantage over hardcoding is that they can be found and changed easily. The problem is that anyone who has access to your source code, or your source code repository, can see your secrets. If you later decide to hide these, you’ll have to scrub your repository history to remove all traces of the secrets.
If you have sensitive information in your git repository, you’ll want to scrub it from the history after you’ve found a new solution.
One thing to note is that non-sensitive keys and passwords which are generally used for development or testing purposes, such as publicly available testing credentials, self-signed certs, etc., are fine to leave in plain text in the repository in some sort of configuration file. If the answer to “would this be ok if it were made public?” is “yes,” then it is fine to leave in plain text.
Environment variables don’t live inside the code repository and they’re easy to change. However, depending on the type of server you’re running (a container vs a multi-purpose VM, for example), you may expose yourself to the possibility of leaking secrets accidentally. Environment variables are more difficult to control access to than something like a file, and might be read by a tool or framework and end up in logs, an error page, or any number of bad places.
The Right Way
The good news is that many deployment/orchestration tools come with some sort of secrets management. Since there are so many tools and best practices can change from time to time, I’ll just briefly mention some of the more popular ones here.
Use Ansible Vaults.
Use Chef Vaults.
Use Docker Secrets.
Docker recently released secrets for Docker Swarm. These are stored securely in the Swarm and made available on an individual basis to containers running in the Swarm as per the configuration. These are then mounted into the container as files under
Use Kubernetes Secrets.
If you don’t find what you’re looking for mentioned above, try searching in the official docs or forum for whatever tool you’re using. As with anything security related, try to find up-to-date information and discuss any security concerns with your team.