<p>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.</p>
<h2>References</h2>
<ul>
<li>[1] Ansible 2.10 (latest as of 2021-02-08) <a href="https://docs.ansible.com/ansible/latest/user_guide/vault.html" rel="nofollow noreferrer">Encrypting content with Ansible Vault</a></li>
</ul>
<h2>What May Have Confused You</h2>
<p>[1] says a <code>vault ID</code> has the pattern <code>label@source</code>. But the symbol <code>@</code> delivers the meaning of &quot;inside&quot;, &quot;at&quot;, or &quot;of&quot; which makes people think a vault ID <code>test@password_file</code> means a line inside the file <code>password_file</code> with the label <code>test</code>.</p>
<p><strong>But this is the gotcha</strong>: according to my test, the <strong>entire content</strong> in <code>password_file</code> is used as the password. In your example above, the password <strong>you think</strong> is &quot;my_test_pass&quot;; but the password <strong>Ansible Vault sees</strong> is <code>dev my_dev_pass\ntest my_test_pass\nprod my_prod_pass</code> (note the white spaces and the End-of-Lines).</p>
<p>Therefore, <code>test@file_path</code> does not select the line &quot;my_test_pass&quot;. It actually means the following:</p>
<ul>
<li>At <strong>encryption</strong>, it means &quot;use the entire content in <code>file_path</code> as the password to encrypt the given message and marks the result with the label <code>test</code>&quot;.</li>
<li>At <strong>decryption</strong>, it means &quot;use the entire content in <code>file_path</code> as the password to decrypt everything that is marked with the label <code>test</code>&quot;.</li>
</ul>
<h2>Using Multiple Password Files</h2>
<p>Therefore, if you want to use different password files, you need to do it this way:</p>
<ul>
<li>Create three files (I put them at different folders intentionally for demo): <code>~/pass_dev.txt</code>, <code>/tmp/pass_test.txt</code>, <code>./pass_prod.txt</code>.</li>
<li>Put the passwords into the correct files. Example: <code>my_dev_pass</code> into <code>pass_dev.txt</code>.</li>
<li>When you encrypt the file <code>my_dev_file.yml</code>, you have two options:
<ul>
<li>You can specify just one vault ID: <code>ansible-vault encrypt --vault-id dev@~/pass_dev.txt my_dev_file.yml</code></li>
<li>You can specify multiple vault IDs but must also use <code>--encrypt-valut-id</code> to tell <code>ansible-vault</code> which one should actually be used to encrypt the file: <code>ansible-vault encrypt --vault-id dev@~/pass_dev.txt test@/tmp/pass_test.txt prod@./pass_prod.txt --encrypt-vault-id dev my_dev_file.yml</code></li>
</ul>
</li>
</ul>
<p>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: <code>ansible-vault decrypt dev@~/pass_dev.txt test@/tmp/pass_test.txt prod@./pass_prod.txt some_encrypted_file.yml</code>. And vault will automatically figure out which password to use. This is talked about <a href="https://docs.ansible.com/ansible/latest/user_guide/vault.html#passing-multiple-vault-passwords" rel="nofollow noreferrer">in this section of [1]</a>.</p>
<p>This also explains why the <code>label</code> part is only used as a hint. In fact, you can pass in the vault IDs with completely wrong labels:</p>
<pre><code>ansible-vault decrypt prod@~/pass_dev.txt dev@/tmp/pass_test.txt test@./pass_prod.txt some_encrypted_file.yml
</code></pre>
<p>And <code>ansible-vault</code> is still able to decrypt the file, because, essentially, <code>ansible-vault</code> uses the <code>label</code> as the hint to see which password should be tried first. If it doesn't succeed, it tries the other passwords.</p>
<p>But if you define the environment variable <code>ANSIBLE_VAULT_ID_MATCH</code>, <code>ansible-vault</code> will take the labels seriously and only try the passwords with matching labels, so the following will fail:</p>
<pre><code>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
</code></pre>
<h2>Other Things in Your Question</h2>
<p>I may not be completely correct in this part: I guess <code>ansible-vault</code> maintains an internal list of &quot;currently available vault IDs&quot;. If no <code>--vault-id</code> is present on the command line, the only available vault ID is <code>default</code>. When <code>--vault-id</code> arguments are given, the <code>default</code> is overridden by whatever is provided.</p>
<p>Therefore, when you encrypted the target file using a <code>--vault-password-file</code>, without any other <code>--vault-id</code>, the only available vault ID was <code>default</code>. But by providing <code>--encrypt-vault-id=test</code> you were asking <code>ansible-vault</code> to encrypt the target file using a vault ID of &quot;test&quot; which was not available, hence the error &quot;Did not find a match&quot;.</p>
<p>Later, when you provided <code>ansible-vault</code> with only <code>--vault-id abc@file_path</code> but asked it to encrypt the target file using <code>test</code>, <code>ansible-vault</code> still couldn't find the required vault ID, hence the error &quot;Did not find a match&quot; again.</p>
<p>You made the mistake because you thought <code>test@file_path</code> selects one password from all the available passwords in <code>file_path</code>, so by providing one password file, you thought you had provided multiple passwords. But that doesn't seem to be how <code>ansible-vault</code> works. You need to provide multiple password files (or, technically, multiple password sources which could also be prompts and scripts).</p>

CC BY-SA 4.0
2021-02-09T07:30:07.797Z
Your answer is very detailed. Thanks. But the question was about how to store multiple passwords in a single file. As you pointed out, now Ansible team silently removed this text from the manual. So the correct answer is simply "this is not possible because it was a bug in the manual". Having multiple files could be fine also but I don't get why one can't give a folder to ansible and ansible reads the file names as vault IDs. They could improve that.
yurtesen
CC BY-SA 4.0
2021-02-09T00:51:27.677Z
2022-02-28T17:55:47.917Z
2022-02-28T17:55:47.917Z
yaobin
<p>I totally misunderstood you. Here is a new attempt to actually answer your question. :)</p>
<ol>
<li>Create a passwords file:</li>
</ol>
<pre><code>root@2ca77340d571:/# cat .passvaults
dev my_dev_pass
test my_test_pass
prod my_prod_pas
</code></pre>
<ol start="2">
<li>Create a file to encrypt:</li>
</ol>
<pre><code>root@2ca77340d571:/# cat extravaulty.yml
chocolate:banana
</code></pre>
<ol start="3">
<li>Encrypt the file:</li>
</ol>
<pre><code>root@2ca77340d571:/# ansible-vault encrypt --vault-id=dev@.passvaults extravaulty.yml
Encryption successful
</code></pre>
<ol start="4">
<li>View the raw file:</li>
</ol>
<pre><code>root@2ca77340d571:/# cat extravaulty.yml
$ANSIBLE_VAULT;1.2;AES256;dev
33336336336238326137393764316333623231336238323931306166626434653164326330656566
3561356333343435663538623661363661373461356461300a663361666331323031623530343930
62633230636566643339663637386438336539383162346634393031633165333033396238363163
6134383233346538330a326266626261346638303738313862656337396237343231326231656139
34376334663664343164303462356431306539316232323761386164643735376330
</code></pre>
<p>and the decrypted file:</p>
<pre><code>root@2ca77340d571:/# ansible-vault view --vault-id=dev@.passvaults extravaulty.yml
chocolate:banana
</code></pre>
<p>As I understand it, when you use <code>--vault-id=dev@.passvaults</code> you are telling it to use <code>dev</code> as a hint (not the vault password) and <code>.passvaults</code> as the file where the encrypt/decrypt password is.</p>
<p>This means that you can also do this:</p>
<pre><code>root@2ca77340d571:/# ansible-vault view --vault-id=prod@.passvaults extravaulty.yml
chocolate:banana
</code></pre>
<p>Or this</p>
<pre><code>root@2ca77340d571:/# ansible-vault view --vault-id=.passvaults extravaulty.yml
chocolate:banana
</code></pre>
<p>Which is not intuitive to me.
Does this help?</p>

CC BY-SA 4.0
2020-12-07T19:57:51.300Z
Nice try... But if you encrypt using `ansible-vault encrypt --vault-id=test@.passvaults extravaulty.yml` you can still decrypt it using `ansible-vault view --vault-id=prod@.passvaults extravaulty.yml`. On top of that, you can even encrypt using a non-existent vault id `ansible-vault encrypt --vault-id=blah@.passvaults extravaulty.yml`. It seems to me that it use the `.passvaults` file as a whole, because any character change in any vault id line cause decryption problem. So, next time you may want to test your solution :)
yurtesen
CC BY-SA 4.0
2020-12-09T11:53:24.017Z
Hi. I did test the solution and this is what I said above: `As I understand it, when you use --vault-id=dev@.passvaults you are telling it to use dev as a hint (not the vault password) and .passvaults as the file where the encrypt/decrypt password is.`. I think that the first part of the `@` bit is a hint and not the vault id necessarily.
migueldavid
CC BY-SA 4.0
2023-03-28T07:38:01.177Z
@migueldavid is right. It does not take the proper passwort but the whole file to encrypt and decrypt the vault. Try changing the content of `.passvaults` and you will see that ainsible-vault fails.
Orri
CC BY-SA 4.0
2020-12-07T12:06:51.930Z
2020-12-07T12:06:51.930Z
migueldavid
<p><strong>Update</strong>: As @yaobin pointed out. It appears they removed the part about the multiple passwords being in a single file. It was here as can be seen from web archive:<br />
<a href="https://web.archive.org/web/20201202040251/https://docs.ansible.com/ansible/latest/user_guide/vault.html" rel="nofollow noreferrer">https://web.archive.org/web/20201202040251/https://docs.ansible.com/ansible/latest/user_guide/vault.html</a><br />
But now it is gone:<br />
<a href="https://web.archive.org/web/20210128225633/https://docs.ansible.com/ansible/latest/user_guide/vault.html" rel="nofollow noreferrer">https://web.archive.org/web/20210128225633/https://docs.ansible.com/ansible/latest/user_guide/vault.html</a><br />
So I am not sure if this problem can be solved anymore the way that was described in the manual at the time. It was apparently a manual bug :(</p>
<hr />
<p>The manual says at storing passwords in files section:</p>
<blockquote>
<p>To store a vault password in a file, enter the password as a string on
a single line in the file. Make sure the permissions on the file are
appropriate. Do not add password files to source control. If you have
multiple passwords, you can store them all in a single file, as long
as they all have vault IDs. For each password, create a separate line
and enter the vault ID, a space, then the password as a string. For
example:</p>
</blockquote>
<p>and there is an example:</p>
<pre><code>dev my_dev_pass
test my_test_pass
prod my_prod_pass
</code></pre>
<p>However there is no usage exampes for this file. I tried many different ways. If I use <code>--vault-password-file</code> the <code>ansible-vault</code> sees only <code>default</code> entry independent of the number of entries in file. With <code>--encrypt-vault-id=test</code> I get:</p>
<pre><code>ERROR! Did not find a match for --encrypt-vault-id=test in the known vault-ids ['default']
</code></pre>
<p>If I use <code>--vault-id abc@file_path</code> with <code>--encrypt-vault-id=test</code> then I get error</p>
<pre><code>ERROR! Did not find a match for --encrypt-vault-id=test in the known vault-ids ['abc']
</code></pre>
<p>What is the purpose of the password file described in the Ansible manual and how does one use it?</p>
<p>Thanks!</p>

CC BY-SA 4.0
2021-02-08T22:21:05.257Z
Do you mind adding the link to the quoted documentation? It looks like you quoted from [this section](https://docs.ansible.com/ansible/latest/user_guide/vault.html#storing-passwords-in-files) which says "To store a vault password in a file, ... Do not add password files to source control." But I can't find the words of "If you have multiple passwords, you can store them all in a single file..." Were you using a different version of Ansible? (Or maybe they updated the page so your quoted words no longer exist.)
yaobin
<ansible><ansible-vault>
How to store/retrieve multiple ansible-vault passwords within/from a single file
yurtesen
# How to store/retrieve multiple ansible-vault passwords within/from a single file

(Asked by: username_0 on 2020-12-05)

Update: As @username_1 pointed out. It appears they removed the part about the multiple passwords being in a single file. It was here as can be seen from web archive:
https://web.archive.org/web/20201202040251/https://docs.ansible.com/ansible/latest/user_guide/vault.html
But now it is gone:
https://web.archive.org/web/20210128225633/https://docs.ansible.com/ansible/latest/user_guide/vault.html
So I am not sure if this problem can be solved anymore the way that was described in the manual at the time. It was apparently a manual bug :(

The manual says at storing passwords in files section:

To store a vault password in a file, enter the password as a string on
a single line in the file. Make sure the permissions on the file are
appropriate. Do not add password files to source control. If you have
multiple passwords, you can store them all in a single file, as long
as they all have vault IDs. For each password, create a separate line
and enter the vault ID, a space, then the password as a string. For
example:

and there is an example:
dev my_dev_pass
test my_test_pass
prod my_prod_pass

However there is no usage exampes for this file. I tried many different ways. If I use --vault-password-file the ansible-vault sees only default entry independent of the number of entries in file. With --encrypt-vault-id=test I get:
ERROR! Did not find a match for --encrypt-vault-id=test in the known vault-ids ['default']

If I use --vault-id abc@file_path with --encrypt-vault-id=test then I get error
ERROR! Did not find a match for --encrypt-vault-id=test in the known vault-ids ['abc']

What is the purpose of the password file described in the Ansible manual and how does one use it?
Thanks!

**Tags:** ansible, ansible-vault

> **Comments:**
> **username_1**: Do you mind adding the link to the quoted documentation? It looks like you quoted from [this section](https://docs.ansible.com/ansible/latest/user_guide/vault.html#storing-passwords-in-files) which says "To store a vault password in a file, ... Do not add password files to source control." But I can't find the words of "If you have multiple passwords, you can store them all in a single file..." Were you using a different version of Ansible? (Or maybe they updated the page so your quoted words no longer exist.)  

---

## 2 answers

### Answer by username_1 on 2021-02-09. Score: 4

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.
References

[1] Ansible 2.10 (latest as of 2021-02-08) Encrypting content with Ansible Vault

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:

At encryption, it means "use the entire content in file_path as the password to encrypt the given message and marks the result with the label test".
At decryption, it means "use the entire content in file_path as the password to decrypt everything that is marked with the label test".

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

Create three files (I put them at different folders intentionally for demo): ~/pass_dev.txt, /tmp/pass_test.txt, ./pass_prod.txt.
Put the passwords into the correct files. Example: my_dev_pass into pass_dev.txt.
When you encrypt the file my_dev_file.yml, you have two options:

You can specify just one vault ID: ansible-vault encrypt --vault-id dev@~/pass_dev.txt my_dev_file.yml
You can specify multiple vault IDs but must also use --encrypt-valut-id to tell ansible-vault which one should actually be used to encrypt the file: ansible-vault encrypt --vault-id dev@~/pass_dev.txt test@/tmp/pass_test.txt prod@./pass_prod.txt --encrypt-vault-id dev my_dev_file.yml



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).

> **Comments:**
> **username_0**: Your answer is very detailed. Thanks. But the question was about how to store multiple passwords in a single file. As you pointed out, now Ansible team silently removed this text from the manual. So the correct answer is simply "this is not possible because it was a bug in the manual". Having multiple files could be fine also but I don't get why one can't give a folder to ansible and ansible reads the file names as vault IDs. They could improve that.  

---

### Answer by username_2 on 2020-12-07. Score: 2

I totally misunderstood you. Here is a new attempt to actually answer your question. :)

Create a passwords file:

root@2ca77340d571:/# cat .passvaults
dev my_dev_pass
test my_test_pass
prod my_prod_pas


Create a file to encrypt:

root@2ca77340d571:/# cat extravaulty.yml
chocolate:banana


Encrypt the file:

root@2ca77340d571:/# ansible-vault encrypt --vault-id=dev@.passvaults extravaulty.yml
Encryption successful


View the raw file:

root@2ca77340d571:/# cat extravaulty.yml
$ANSIBLE_VAULT;1.2;AES256;dev
33336336336238326137393764316333623231336238323931306166626434653164326330656566
3561356333343435663538623661363661373461356461300a663361666331323031623530343930
62633230636566643339663637386438336539383162346634393031633165333033396238363163
6134383233346538330a326266626261346638303738313862656337396237343231326231656139
34376334663664343164303462356431306539316232323761386164643735376330

and the decrypted file:
root@2ca77340d571:/# ansible-vault view --vault-id=dev@.passvaults extravaulty.yml
chocolate:banana

As I understand it, when you use --vault-id=dev@.passvaults you are telling it to use dev as a hint (not the vault password) and .passvaults as the file where the encrypt/decrypt password is.
This means that you can also do this:
root@2ca77340d571:/# ansible-vault view --vault-id=prod@.passvaults extravaulty.yml
chocolate:banana

Or this
root@2ca77340d571:/# ansible-vault view --vault-id=.passvaults extravaulty.yml
chocolate:banana

Which is not intuitive to me.
Does this help?

> **Comments:**
> **username_0**: Nice try... But if you encrypt using `ansible-vault encrypt --vault-id=test@.passvaults extravaulty.yml` you can still decrypt it using `ansible-vault view --vault-id=prod@.passvaults extravaulty.yml`. On top of that, you can even encrypt using a non-existent vault id `ansible-vault encrypt --vault-id=blah@.passvaults extravaulty.yml`. It seems to me that it use the `.passvaults` file as a whole, because any character change in any vault id line cause decryption problem. So, next time you may want to test your solution :)  
> **username_2**: Hi. I did test the solution and this is what I said above: `As I understand it, when you use --vault-id=dev@.passvaults you are telling it to use dev as a hint (not the vault password) and .passvaults as the file where the encrypt/decrypt password is.`. I think that the first part of the `@` bit is a hint and not the vault id necessarily.  
> **username_3**: @username_2 is right. It does not take the proper passwort but the whole file to encrypt and decrypt the vault. Try changing the content of `.passvaults` and you will see that ainsible-vault fails.  

---

