Use Ansible Vault With macOS Keychain

Vault is a useful feature of Ansible that allows you to store secrets within your configuration management repository. Rather than storing sensitive information in plain text files, Vault transparently manages encrypted files. When you want to edit a file, Vault prompts you for a password used to decrypt the file.

While Vault is useful, it’s tedious to type your password each time you want to access a Vault file. For example, you’re prompted for a Vault password each time you run a playbook that uses a Vault. One approach is to put the password in a plain-text file, and protect it using UNIX file permissions. Then you can point to that file using the --vault-password-file argument. This technique hearkens back to the old days of .netrc files.

It turns out there’s a better way. We can use the system’s keychain to store the password securely, and retrieve it via a script that Ansible will execute when it needs the password to decrypt a Vault file. I’m on macOS (R.I.P. OS X), so I’ll use the macOS Keychain. Using this technique on Linux with Gnome Keyring or KWallet is left as an exercise for the reader (or a follow-up blog post).

Store Ansible Vault Password in the Keychain

  • Open Keychain.app. Create an entry in your Login keychain for the Ansible Vault password.

Example Keychain Entry

Or you can add a Keychain entry via the command line like this:

$ security add-generic-password \
  -a johnnyappleseed \
  -s ansible-vault-password \
  -w secret
  • Create a file named, vault_password_file, and make the file executable. (The file can be named anything you want, but we’ll use this name for the purposes of this example.)
  • Edit vault_password_file to have the following contents.
#!/bin/bash

# Keychain query fields.
# LABEL is the value you put for "Keychain Item Name" in Keychain.app.
LABEL="ansible-vault-password"
ACCOUNT_NAME="johnnyappleseed"

/usr/bin/security find-generic-password -w -a "$ACCOUNT_NAME" -l "$LABEL"
# This could be $HOME/.ansible.cfg for example.
[defaults]
vault_password_file = /path/to/vault_password_file

Now, when you run a command like, ansible-vault view ./group_vars/vault.yml, a Keychain dialogue will pop up requesting access to the password. Click “Allow”, and you’re done!

Wait, did I just teach you to trade typing your password for a mouse click? Not really. On macOS I have “Full keyboard access” enabled, so instead of clicking “Allow”, I just hit the spacebar. So, technically, the spacebar is now my Ansible Vault password. If you don’t want to click or type anything, then you can choose, “Always Allow”, in the Keychain dialogue, but it’s a little less secure.

Summary

This technique makes working with Ansible Vault files painless, yet is still secure. It solves the problem of working with Ansible Vault passwords by a human during development or manually running a playbook. It doesn’t say much about using Vault in automated environments like continuous integration or automated deployment systems. That’s a story for another day. If you have techniques that you like in this area, drop me a line. I’d love to hear about it.

References

  • OS X keychain & ansible-vault by Gerhard Lazu.
    The article that inspired this post. My technique doesn’t use a temporary file.
  • If you’re looking for a cross-platform solution the Python Keyring module looks promising.