Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Security

Safest way to store remote DB connection credentials?

The TLDR: What's the safest (and most performant) way of locally storing user credentials (such as a password) for a remote database connection?:

This question isn't really limited to any language, as I would imagine best-practices would be language- and DB-agnostic (could be used for API credentials, for example).

My Use Case: I have a pretty standard abstraction class for my PHP PDO interactions with MySQL (we'll called it Database()), but that code gets submitted to a repo on CodeCommit and obviously hardcoding private $pass = 'password' is a bad idea because the plaintext password is then just sitting in a repo somewhere (and available to anyone we share repo access with).

Presently I have a localized /credentials/ directory outside of the webroot on the server that stores MySQL user passwords in separate files, with the filename matching the corresponding username used while connecting to MySQL. On instantiation of a new Database(), the password is read directly from the appropriate file and whitespace is trimmed (in PHP, that's via file_get_contents() and trim(), respectively).

This approach lets myself and others commit to our repo without exposing DB connection credentials - but the connection passwords (and usernames, for that matter) are still sitting in plaintext on the server (in the /credentials/ dir).

I thought about just encrypting/decrypting the file contents, but wonder about the performance impact of decrypting a credential file every time I create a new Database() instance, which could be multiple times across a page/view. Is that worth it? Is there a better, more modern best-practice for storing such credentials? I thought about caching the password for all the Database() instances (so I only decrypt once per pageload, for example) - but this seems like a bad idea to me.

Would really love some thoughts or recommendations if anyone has them. Obviously if the server is compromised, it probably doesn't really matter regardless - but my thought process was that I could eventually combine credential encryption with some form of integrity check or attestation before running scripts (verify there's been no tampering with a script before it runs). Together I thought this might be a good way of preserving DB data integrity in the case a processing server was compromised (or atleast for long enough for us to figure out something is wrong).

Edit: Changed Topic to Security, edited contents for clarity.

2 Answers

Kevin Korte
Kevin Korte
28,149 Points

I'm not 100% sure it's the most secure way, but it seems secure enough, that I've always stored my database credentials as environment variables, so they stay out of the code base entirely.

This usually means to set them, when I fired up the server from a console, I either included them at that time (here's an example that is language agnostic) language server start --db_user='kevin' --db_pass="password" or, I might set that as a file only on my local machine, and then instead just call that file, that then runs that console command, so I can shorten my command.

In node, I've often have a local package, and can just run npm start run and that would fire it up.

That's always been my approach.

Hmm, yeah I know a lot of people use env vars - but that also concerns me because then that variable is globally accessible. Seems to me that might present a host of its own issues. Env vars are global, so they're accessible anywhere in the code (and therefore at direct risk should a particular piece of code be exploitable by a user).