Secure handling of passwords during development

During the development and deployment of an application I come in contact with a number of passwords for local development, testing, staging, code shipment, deployment and monitoring.

The risk involved varies: when I start an application on my local machine admin:password might be sufficient. But what about systems visible in a corporate or public network?

In the early phase of my carrier I learned a lot of Don’ts. But what about the alternatives? I want to present some here.

This Blog post contains best practices to protect password from leaking during development, code sharing, screen sharing, automated testing and deployments.

Monitor screen showing greenish windows with undefined hacking stuffEven during development we handle application secrets

Password Storage

Don’t: store the passwords in a local file, it might get uploaded or stolen. Don’t write them on paper, it might get copied or lost and typing them by hand limits password length.

Do: I advice you to store passwords in a password manager for the following reasons:

  • Password length is no issue any more, as they are auto-filled. What about 35 characters?
  • Password randomness neither. I don’t type them by hand. No idea where to find all the symbols on my keyboard.
  • Password reusal neither. Whenever you set a password you should always create a new random password… very easy with a password manager.

I personally have good experience with Bitwarden and 1Password. Don’t forget to have an encrypted backup.

Password Sharing

Don’t: Including passwords in internal documentation, mails or similar is risky. They might get stolen, appear on the screen while screen sharing, on pictures and are visible when working in public.

Do: I prefer unshared personal accounts, but in projects some credentials need to be shared, eg. the database user of staging application database or a test user. Our password manager allows sharing passwords within the project team.

Password Mailing

Don’t: Send the password in an unencrypted message, such as mail, SMS, chat message or similar.

Do: How to send passwords to a colleague who has no access to the password manager though. I use Bitwarden Send as follows:

  1. Generate a random password
  2. Create a sharing link with one time access
  3. Send the link to the colleague
  4. Wait until she/he confirms she/he has the password
  5. Create the account or encrypt the data/the shared password with the sent one

Application Configuration

Don’t: commit the passwords with the code into your repository. You cannot delete them anymore. A distant commit still contains them. If you want to open-source the project things only get worse. Passwords might also leak during screen sharing sessions, office pictures or when working in public spaces.

Do: use environment variables to configure the application. At Sandstorm this allows me to deploy an application without ever knowing the production database password. I deploy an app, enable the “with database” option and our Kubernetes operator takes care of the rest. It creates a new database and a new database user, provides the credentials via environment variables to the application and takes care of the daily backups.

Continuous Integration Pipelines

This is similar to the Application: use environment variables and hide the credentials in the project configuration of our e.g. Gitlab. Now you can restrict access to the credentials even further.

Continuous Deployment

As mentioned at Sandstorm we usually do not bother creating a database user by hand. It is part of our automated application deployment. This eliminated the need to share production passwords entirely.

Command Line

Don’t: inlining the password in shell commands shows them on the screen and stores them in the local command history. I want to avoid both.

# do not do this, it exposes your password my-shell-command --user christoph --password 3j2Dzap1CcT

Do: Usually it is more save to use a password prompt, if the command supports it.

# some commands prompt for a missing password my-shell-command --user christoph --password Password:

If this is not feasible you can either use a local file or a local environment variable (if present).

# You can use a local environment variable my-shell-command --user christoph --password $PASSWORD # … or file you delete immediatly after my-shell-command --user christoph --password $(cat pass) # … or directly paste from the clipboard # this example is for OS X my-shell-command --user christoph --password $(pbpaste)

If your password contains special characters by chance, you need to adjust the command a bit.

Secure Shell Connections

I do not need this very often, but it is very handy. Let’s assume you want to migrate data from server A to server B. You can connect to both servers via SSH using your private key. Now you can directly download the data from server A to server B. With the -A flag:

ssh -A server-B.sandstorm.de # the following commands is executed on server B scp server-A.sandstorm.de:data.tgz .

For scp the local private key is used for authentication. It does not leave the local machine - or in my case the YubiKey. Nonetheless you should only connect with -A to servers you trust.

As always feedback is highly welcome - and thanks for reading.