Secrets vault
The secrets vault stores passwords, API keys and tokens that your Salt states, runbooks and Ansible playbooks need. A secret's value can be set or replaced, but nobody can read it back through the console or the API.
To open the vault: choose Administration > Secrets vault.
Add a secret
Only Gardience admins can add, change or delete secrets.
- Go to Add or replace a secret.
- Enter a Name. Names use lowercase letters, digits and underscores, start with a letter, and are 2 to 64 characters long.
- Enter a Description of what it is for.
- Enter the Value.
- Tick the node groups that may receive the secret. At least one is required.
- Choose Save secret.
The table then shows the secret's name, the groups and machines it is released to, its version, and who changed it last. Values are never shown.
Scoping: which machines receive a secret
When you save a secret, Gardience records the list of machines that Salt matches to the ticked node groups at that moment. That list, not the group, is the secret's scope. Only those machines receive it.
So a machine that joins a group later does not receive the secret until the scope is captured again. If Gardience cannot find out a group's members when you save, it refuses the save; try again in a moment.
To capture the scope again from the groups' current members: enter the secret's name in Add or replace a secret, leave Value empty, tick the same node groups, and choose Save secret. The value stays the same, and the new machine list is recorded in the audit log.
The scope is a list of machine IDs. Salt confirms each machine's ID with that machine's own key, so a machine cannot claim to be another one to receive its secrets.
Replace a value or delete a secret
To replace a value:
- Choose Replace value on the secret. The form fills in the name.
- Enter the new value.
- Tick the node groups again. The form does not keep them.
- Choose Save secret.
The version number goes up by one each time the value changes.
To delete a secret, choose Delete and confirm. Runs that still use it will fail.
After any change, Gardience refreshes the affected machines, so added machines receive the secret and removed machines lose it.
Secrets kept in HashiCorp Vault or CyberArk Conjur
A secret does not have to be copied into Gardience. It can stay in your HashiCorp Vault or CyberArk Conjur, and Gardience fetches it each time it is used: a playbook run, a machine's pillar, a Git sync. The fetched value is kept in memory for at most a minute and never written to disk. Scope, auditing and redaction work exactly as for a stored secret.
To connect a store (admins):
- Open Administration > Secrets vault and go to Outside secret stores.
- HashiCorp Vault: the address, sign-in by Token or AppRole (role id and secret id), the KV mount and version (1 or 2), and the namespace for Vault Enterprise. CyberArk Conjur: the address, the account, the login (for example
host/gardience) and its API key. - If the store's certificate comes from an internal certificate authority, paste the CA certificate (PEM).
- Choose Save.
The token, secret id or API key is sealed with the server's key and never shown again. Changing the store's address discards it. Give Gardience a policy that can only read the paths it needs.
To add a secret that lives in a store: fill in the name and node groups as usual, open Or keep the value in HashiCorp Vault or CyberArk Conjur, pick the store, give the path (HashiCorp: the path inside the KV mount, plus the field, such as password; Conjur: the variable id), and choose Test to check that Gardience can read it. The test shows only the length of the value.
If a store cannot be reached when a secret is needed, the run fails and its log says which secret and why. A machine's other secrets are still delivered.
How secrets are delivered
Secrets reach machines through Salt pillar. Pillar is per-machine data that the Salt master sends to each agent over Salt's encrypted connection. When an agent asks for its pillar, the Salt master asks Gardience which secrets that machine may receive and passes on only those.
Because secrets travel in pillar, they are never sent as job arguments, so they do not appear in Salt's job history.
Use a secret
In a Salt state, read it from pillar:
app_db_password:
file.managed:
- name: /etc/app/db.pass
- mode: '0600'
- show_changes: False
- contents: "{{ pillar['gardience_secrets']['db_password'] }}"show_changes: False keeps the file's contents out of the job result.
In an Ansible playbook, list the name in the runbook's Vault secrets field and refer to it as {{ db_password }}. See Ansible playbooks.
What the vault protects
- At rest: values are encrypted with AES-256-GCM in Gardience's data volume.
- From the console and API: values cannot be read back by anyone, admins included.
- From job history: values travel in pillar, not as job arguments.
- From machines outside the scope: a machine receives only the secrets scoped to it.
- In playbook output: values of 4 characters or more are replaced with
********in run logs. - In the audit log: creating, changing, re-scoping, deleting and releasing a secret are recorded without the value. The audit log records
secret.releasedwith the secret names each time the set of secrets a machine receives changes.
What the vault does not protect
- A machine in scope. The value is in that machine's pillar. Anyone with administrator rights on it, or anyone who can run commands on it through Gardience or Salt, can read the secret there.
- What your states and commands do with it. If a state writes the value to a file, puts it on a command line, or prints it, the value ends up there and in that job's result. Output masking applies only to playbook runs.
- The data volume and backups. The encryption key is stored in the same data volume as the encrypted values, and backups contain both. Anyone who can read the whole data volume or a backup can recover the values. Store backups encrypted and off the server.
- Short values in output. Values shorter than 4 characters are not masked in playbook output.
- Machines added to a group after you saved. They do not receive the secret until the scope is captured again (see above).