34

We are planning to use ansible vault in our project to prevent leaking passwords or keys in git.

The idea is to put all our sensitive data into a plain file then encrypt this file with ansible-vault using a password before pushing to git.

To decrypt the file, we have to pass the vault password to ansible, I'm thinking about 3 possibilities:

  • Store it inside a server environnment variable
  • Pass it as an option to ansible-playbook command
  • Store it into a non versionned file.

Is there any other options, which is the best (and secure) way to store ansible-vault password , ansible best practices documentation is not saying anything on this.

2

5 Answers 5

15

The idea is to put all our sensitive data [...]

The meaning of "all" in this sentence should be analyzed very carefully before implementing the solution that you plan.

Ansible vault is a very useful tool, but it should be used only to store secrets that are:

  1. Specifically needed for the ansible deployments
  2. Easily made useless to owners that should become unaware of them, but that may illegitimately "remember" them (typically off-boarded employees)

The second point is critical.

Many people, and potentially the whole DevOps team, will have access to the ansible vault password and therefore all the secrets.

Therefore, for all the secrets stored in the vault, a condition should hold for which a person or machine with unauthorized access to them should be incapable of making any use of them if so is desired.

In concrete terms, if you use ansible to deploy a database and its users, you can store the passwords in the vault, but you will have to be very careful (and most likely consider another solution) if that service will be available from the Internet and without the need for any VPN authentication!

Users (DevOps) exposed to the secret, should be incapable of using "remembered" passwords if one security barrier is imposed on them (e.g., VPN access revoked). In addition to this, access to the source code repository (where the vault is stored) should be revoked as well before passwords are changed.

Under these conditions, ansible vault is a very useful tool.

Trying to store a secret that could be used by any person or machine on the Internet in the vault would be instead a mistake (e.g., VPN credentials of users).

Is there any other options, which is the best (and secure) way to store ansible-vault password

Under the conditions from the previous paragraph, I think that a good practice would be:

  1. Store the vault password in an external secure vault (something like Vault from HashiCorp or any SaaS for credentials management)
  2. Allow access to the external vault item to DevOps (they will need the password for testing) and the CI/CD system or ansible controller
  3. Keep a convention to use secrets! You will not be able to review changes to the secrets and you will not be able to grep for ansible variables in secrets files! So be thorough since the beginning. A good convention is to name all variables stored in the ansible vault with a secret_ prefix. When you will see something like:

    postgres.yml:

    postgres_password: "{{ secret_postgres_password }}"
    

    you will know that the value is stored in the ansible vault.

2
  • 1
    Good point about storing the Ansible Vault password somewhere more secure (HashiCorp Vault or SaaS vault such as AWS Secrets Manager). However, it still needs to be rotated (changed) if someone leaves the team, as they have had access to it even if briefly. This can be mitigated perhaps by using separate vaults (dev, test, production) i.e. secrets files in YAML. Ansible 2.4+ also lets you specify different passwords for such files using a 'vault ID' - docs page
    – RichVel
    Commented Jan 30, 2019 at 7:23
  • 1
    Ansible 2.3 introduced a feature that encrypts only the values in YAML files, not the whole file - this is simpler to maintain than the older convention you mention in point 3 at end of this answer.
    – RichVel
    Commented Feb 3, 2019 at 14:01
10

We are planning to use ansible vault in our project to prevent leaking passwords or keys in git.

Since you haven't yet implemented anything, you might reconsider this. Using a system like Ansible vault has a number of security downsides:

  • there is no audit trail of who has accessed it
  • when an employee leaves, it is easy for them to take the secret store with them
  • when an employee leaves, removing their access means changing the password and redistributing it to everyone else
  • a compromised Ansible vault password can be forever used on an old version of the vault, as stored in version control
  • secrets have to be static

A potentially much more secure, albeit more complex, system that does not have these downsides is to use Hashicorp Vault to store your secrets. You can then still pull values from it almost as easily as from Ansible vault by using https://github.com/jhaals/ansible-vault .

You then have to manage authentication to Hashicorp Vault, though, and that is the turtle question. For humans, I think the best solution is to prompt for a password periodically and expire the token after a short amount of time; for machines, to use the AWS authentication backend or similar. You can never entirely get rid of the need for authentication somewhere, but you can make it harder for an attacker to gain access to it.

Now, if setting up and administering a secrets server is too much for you, then certainly you can just use Ansible vault. Why store the password at all on the individual machines though? For interactive use, you can just prompt for the password, and users can store it in their password manager of choice. iTerm on OS X has a password manager that integrates with Keychain.app that makes this particularly easy there.

2
  • 2
    The best way to use ansible vault is not to use it .. Thank you for pointing that out !
    – storm
    Commented Feb 8, 2018 at 8:09
  • 1
    For small to medium organizations, I'd recommend looking at a cloud-based secrets manager such as AWS Secrets Manager - this is far less work than running a highly available cluster for HashiCorp Vault, but a big improvement on the security you get with Ansible Vault, including auditing and granular access control. Of course, you do end up depending on that service but that can be encapsulated with some app coding and Ansible work. The major benefit is that some secrets don't need to be managed by Ansible at all, e.g. DB passwords - just let the app get secret from the secrets manager.
    – RichVel
    Commented Jan 30, 2019 at 7:26
5

This quite much goes to what internal policies you have on handling sensitive data.

I'd like to tell you my approach to this and explain what I see as pros and cons. I keep the Ansible Vault password in a file on the control machine and have a environment variable pointing to it:

export ANSIBLE_VAULT_PASSWORD_FILE=/deep/dark/place

I have that on my workstation (as I need to test & develop playbooks), some colleagues have it as well, and of course we have it on the main Ansible control machine.

Pros:

  • not in a shared location/repository (it's a non versioned file as you say)
  • one does not need to know your Ansible vault password to run a play (this is under the condition that you have a CI tool, e.g. Jenkins, where you can easily launch playbooks)

Cons:

  • not easy to rotate the password
  • everyone who works on your playbooks needs to have it on his workstation

The cons do have mitigations, but again it's up to the policies and rules you have adopted in you day to day operations.

1
  • 1
    Nice combinaison .. check the other answer though it may be of interest to you.
    – storm
    Commented Feb 8, 2018 at 8:12
2

I store them in my terminal session using keyctl. When I open a terminal session, I input my passwords once.

keyctl allows you to store passwords at different levels, I have chosen session level but you can store it at user or host level.

To perform that, define property vault_identity_list in file ansible.cfg :

vault_identity_list = my_key@./scripts/my_key.py

Create a python script named my_key.py in directory ./scripts with this content :

#!/usr/bin/python
# coding: utf8

import subprocess
import sys
import getpass

key_name = "my_key"
try:
  keyid = int(subprocess.Popen("keyctl request user {} @s".format(key_name), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read())
  print subprocess.Popen("keyctl print {}".format(str(keyid)), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.read().rstrip()
except ValueError:
  sys.stderr.write("Password for '{}' : ".format(key_name))
  password = getpass.getpass("").rstrip()
  subprocess.Popen("keyctl add user {} '{}' @s".format(key_name, password), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  print password

Now, when you type ansible-playbook -e @my_vault.vault ..., it asks you password only once per sessions.

Whith this approach, you can use easily several vaults (each of them with a python script, I don't find a way to use the same script with all vaults).

1

Take a look on this project to manage your ansible vault encrypting passwords https://github.com/Smile-SA/ansible-vault-manager

It handle multiple keyring storage platforms with plugins (for now only AWS SSM implemented). Morehover integration with a current Ansible project is very easy...

1
  • It would help if you make the easier more concrete rather than adding something generic. I read the README of the github page, but could you change the answer so it contains a clear example? I would like to try it.
    – 030
    Commented Nov 11, 2019 at 15:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.