Encrypting your Pillar data is recommended because it contains your most valuable information like passwords and keys used in your infrastructure. Pillar data is held by the Salt master and only send through an encrypted bus to Minions when used in a state file. Using Pillar makes sure that sensitive information is only available on the servers that need access. The weak spot here is the Salt master and all other places where your Pillar sls files are stored in plain text. You may for example use GitHub or another external code hosting service.
Encrypting your Pillar data can be done with GPG. This means that you encrypt the values with a public GPG key. This single public key is used by all the developers within your organization to encrypt sensitive information. The private key is only available on the Salt master (not the Minions!). Without the private key the encrypted data can not be decrypted.
I assume that you are already running a Salt master and one or more Minions. We are first going to create a GPG key pair and than use it to encrypt some Pillar data.
Generate the key pair.
Create a directory named gpgkeys in the SaltStack configuration directory. Make sure nobody else has access to this folder and create the key pair.
mkdir -p /etc/salt/gpgkeys chmod 0700 /etc/salt/gpgkeys gpg --gen-key --homedir /etc/salt/gpgkeys
Export the public key
Export the public key and import it in your development environment.
I normally place the public key in the Salt configuration so if I switch my workplace or someone else is working on the project, he/she can use it as well.
gpg --export -a "salt-gpg" > salt-gpg-pub.key gpg --import salt-gpg-pub.key
Start encrypting values
Encrypt values with the gpg command. Encrypting a complete file is possible as well. We can use it to encrypt SSL certificates for example.
echo -n "secret-value" | gpg --armor --batch --trust-model always --encrypt -r salt-master-gpg
cat << EOF | gpg --armor --batch --trust-model always --encrypt -r salt-gpg
Using encrypted values in Pillar
You can use the PGP messages in your Pillar files like bellow. Be sure to start with “#!yaml|gpg” and add a space and a vertical bar after every key name. Indenting is important as with all other files.
#!yaml|gpg secret-key: | -----BEGIN PGP MESSAGE----- Version: GnuPG v1 hQEMA6PfZaXaBkAuAQf/Sswb3Jmxal8BMzVWz3IsJsNlEWJ3SPApzb9LZMOW HaT6sVk9X3G6zGtUoWI6V/F/Rj9I6r3cUJhpNNBJAaZU/D45K0ERzT0pKaes OYCXtRzVRlmVUGkAbpnHxBEHO/OKU7Ps4i5tiqMPLbHS26lB1j7l7S+v+kQr kK6LUM6bo0r3FiLy0R5SjitbPw1/nFjhK/CB3wfCYoNqi4WJy3cRubBqvXgM zPA6lcZTHgU5XcCDw0iJzrrCVeJlIUsXH9hVdu6RmLUMk8gUj6tBAvY0hEhO pz/sI+3LL+Ag8G6ON/v7b0VRvtp2/lGU5MV2eYnuXNJHARhyN4/NFzdEZH1L uSw0VZdEDvlJJxzii5vStc66q1bItQ7zJ9vmNETvcvJ2H1+PdLB4yfegg6Az yUIeKEiNWpc= =GGPi -----END PGP MESSAGE----- secret-key-2: | -----BEGIN PGP MESSAGE----- ...
A standard configured Salt master refreshes the Pillar data ones a minute. If you don’t have so much time, you can manually refresh it with:
salt '*' saltutil.refresh_pillar
Now requesting a Pillar item on the Salt master will show you the decrypted value.
gijs@Carbon:~$ sudo salt test-minion pillar.item secret-key test-minion: secret-value
I recommend to only encrypt sensitive data and to make sure that this data is replaceable. A users public SSH key does not have to be encrypted while your MySQL root password needs encryption. If you make sure that the values can be replaced easily. There is no need to backup you private key (and it’s extra secure 🙂 ). If the machine running your Salt master crashes you can generate a new GPG key pair and values.