Storing Secrets

Get secrets out of code! Always avoid putting passwords, API keys, etc in your code, especially if your code is in git, and avoid storing them in plaintext. Never try to encrypt it yourself; danger lies this way. Always use a widely known and trusted tool that is specifically made for this purpose.

If you are running on a desktop system,

Use your keychain. This is secured by your login session, i.e. the username and password you use to login to your desktop.

If using python, see . The python code is identical regardless of which OS you’re using.

For keychain access on the command line:

If you are running without a desktop

Automated service accounts, cron jobs, etc, that don’t have access to a login session keychain can still be secured. Several approaches are possible. Use whichever you see fit.

  • The goal is to make a secret available to one process, and no other. This technique puts the secret into root’s home directory, and makes the secret available to only one process running under another user, via sudo, su, and env. You could use a different directory if you wish, provided its permissions are adequately locked down.


    /root/bin/launchmyapp.sh


    /etc/sudoers.d/10_LAUNCHMYAPP


    Now "someuser" can launch the app via sudo, and when command_to_run runs, it will have the $SECRET environment variable available. It is important that the command command_to_run should not be writable by the user. The only way the user can access this secret is via the sudo command, and if that command doesn't leak it, it's secure.

     

  • Selinux / apparmor: In addition to permission bits, consider using selinux or apparmor to restrict access to just the application that needs it. These tools can make a file inaccessible except if a process is running in a particular context, and the only way to get into that context is by being launched by a particular parent process. Thus, your valid script launched your valid way will have access to the secret, whereas the same script running as the same user, launched by a compromised httpd process (or whatever) cannot. You may find this useful: .

  • Many users on the internet recommend using encryption via pgp, gpg, pass, openssl, etc. If the secret is encrypted but the decryption key is equally available, it is snakeoil, fake security. It adds a layer of complexity and false sense of security. Tools such as pgp and openssl are valuable for other purposes, but not this one. Don’t use fake encryption.

  • If you cannot use the previous technique to move secrets into root’s home directory, store your secrets in a dedicated location, outside your code repository, so you don’t accidentally publish via git push or similar. Ensure the permissions are as locked down as possible. I repeat and emphasize, see the comments above, about selinux or apparmor.
    Example:

Â