One vault password for the whole estate means anyone who can run a
development playbook can decrypt production credentials. Vault IDs exist to
break that: separate passwords, separate labels, separate reach.
They work — but not in the way the name suggests, and the gap between the
two is worth measuring rather than assuming.
The syntax
A vault ID is label@source:
Read-only / Safethree sources, one label
# Prompt for the password interactively
ansible-vault view --vault-id prod@prompt group_vars/prod/vault.yml
# Read it from a file
ansible-vault view --vault-id prod@~/.vault/prod-pass group_vars/prod/vault.yml
# Run an executable and use its stdout - the client-script form
ansible-vault view --vault-id prod@~/.vault/prod-client.py group_vars/prod/vault.yml
The label is recorded in the file header when you encrypt:
Read-only / Safethe label lands in the header— Executed on ansible-core 2.21.3.
$ ansible-vault encrypt --vault-id prod@.prod-pass prod-secrets.yml; head -1 prod-secrets.yml
$ANSIBLE_VAULT;1.2;AES256;prod
Multiple IDs can be offered at once, and DEFAULT_VAULT_IDENTITY_LIST
makes that the default for every invocation:
Read-only / Safeoffering several, without repeating yourself
# ansible.cfg
[defaults]
# Equivalent to passing --vault-id for each. Tried in order.
vault_identity_list = dev@~/.vault/dev-pass, prod@~/.vault/prod-pass
# Which one is used when encrypting, since the list has more than one
vault_encrypt_identity = dev
--encrypt-vault-id overrides vault_encrypt_identity for a single
command. Without either, offering more than one identity and running an
encryption makes the choice ambiguous, so set it deliberately — encrypting
production material under the development label because it happened to be
first in the list is a mistake that is invisible until somebody reads the
header.
What the label actually enforces
Here is the part that matters. Four executed runs against the same file,
encrypted under the label prod.
Read-only / SafeA. only the dev password offered— Executed on ansible-core 2.21.3. The dev password is genuinely different from the prod password.
Also expected. You offered the right password; it worked.
Now the one that changes how you should think about this.
Read-only / SafeC. the PROD password, offered under the label 'dev'— Executed on 2.21.3, vault_id_match at its default of False. The file header says prod. The identity offered is labelled dev.
[ERROR]: Failed to view 'prod-secrets.yml': Decryption failed
(no vault secrets were found that could decrypt).
exit=1
Same password, same file, refused — because the label does not match.
Read-only / Safethe setting and its default— Executed on ansible-core 2.21.3 with no configuration file present.
$ ansible-config dump | grep VAULT_ID_MATCH
DEFAULT_VAULT_ID_MATCH(default) = False
The documented description, from ansible-config list:
If true, decrypting vaults with a vault id will only try the password
from the matching vault-id.
Designing the scheme
Labels should name the key, because that is what the label selects.
Read-only / Safea scheme that maps to who may decrypt what
dev -> anyone on the engineering team
staging -> engineering team
prod -> platform on-call rota only
payments -> payments team only; prod does not open it
ca-2026 -> the signing material, two-person access
Two rules that keep it honest.
One label per group of people who may decrypt. If two labels always
travel together — everyone with prod also has staging — the second one
is documentation, not separation. That may be fine, but know which it is.
Production credentials must not be reachable from a developer
workstation. This is the whole objective, and vault IDs alone do not
achieve it. The password file for prod should not exist on a laptop. If
it does, the label scheme is describing an intention that the filesystem
contradicts.
Knowledge check
Knowledge check · 4 questions
Q1. On ansible-core 2.21.3 with default settings, a file encrypted under the label prod is opened with --vault-id dev@file, where that file contains the production password. What happens?
Q2. A team believes their vault ID scheme prevents the development password from opening production files. With default settings, what actually provides that separation?
Q3. Which are correct about enabling vault_id_match on an existing repository? Select all that apply.
Q4. A vault ID scheme is sufficient to keep production credentials off a developer workstation, since the developer is only given the development label.
Passing score: 75%. Answers are checked in this browser.