yaobin.wen

Yaobin's Blog

View on GitHub
8 February 2021

Ansible Vault: Understanding How to Use Multiple Passwords

by yaobin.wen

(This article was posted as an answer here.)

This afternoon I also struggled on this. I think I’ve understood it a little bit more so I’d like to share it. But I’m also new to Ansible Vault so what I say here may not be completely correct. I used [1] as my main source of learning.

What May Have Confused You

[1] says a vault ID has the pattern label@source. But the symbol @ delivers the meaning of “inside”, “at”, or “of” which makes people think a vault ID test@password_file means a line inside the file password_file with the label test.

But this is the gotcha: according to my test, the entire content in password_file is used as the password. In your example above, the password you think is “my_test_pass”; but the password Ansible Vault sees is dev my_dev_pass\ntest my_test_pass\nprod my_prod_pass (note the white spaces and the End-of-Lines).

Therefore, test@file_path does not select the line “my_test_pass”. It actually means the following:

Using Multiple Password Files

Therefore, if you want to use different password files, you need to do it this way:

When you need to decrypt some content, you may or may not know what password the content was encrypted with. In this case, you can pass in all the possible vault IDs: ansible-vault decrypt dev@~/pass_dev.txt test@/tmp/pass_test.txt prod@./pass_prod.txt some_encrypted_file.yml. And vault will automatically figure out which password to use. This is talked about in this section of [1].

This also explains why the label part is only used as a hint. In fact, you can pass in the vault IDs with completely wrong labels:

ansible-vault decrypt prod@~/pass_dev.txt dev@/tmp/pass_test.txt test@./pass_prod.txt some_encrypted_file.yml

And ansible-vault is still able to decrypt the file, because, essentially, ansible-vault uses the label as the hint to see which password should be tried first. If it doesn’t succeed, it tries the other passwords.

But if you define the environment variable ANSIBLE_VAULT_ID_MATCH, ansible-vault will take the labels seriously and only try the passwords with matching labels, so the following will fail:

ANSIBLE_VAULT_ID_MATCH=1 ansible-vault decrypt prod@~/pass_dev.txt dev@/tmp/pass_test.txt test@./pass_prod.txt some_encrypted_file.yml

Other Things in Your Question

I may not be completely correct in this part: I guess ansible-vault maintains an internal list of “currently available vault IDs”. If no --vault-id is present on the command line, the only available vault ID is default. When --vault-id arguments are given, the default is overridden by whatever is provided.

Therefore, when you encrypted the target file using a --vault-password-file, without any other --vault-id, the only available vault ID was default. But by providing --encrypt-vault-id=test you were asking ansible-vault to encrypt the target file using a vault ID of “test” which was not available, hence the error “Did not find a match”.

Later, when you provided ansible-vault with only --vault-id abc@file_path but asked it to encrypt the target file using test, ansible-vault still couldn’t find the required vault ID, hence the error “Did not find a match” again.

You made the mistake because you thought test@file_path selects one password from all the available passwords in file_path, so by providing one password file, you thought you had provided multiple passwords. But that doesn’t seem to be how ansible-vault works. You need to provide multiple password files (or, technically, multiple password sources which could also be prompts and scripts).

References

Tags: Tech