Secure Pillar in SaltStack with GPG

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.

Let’s go!

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.

secret-key: |

  Version: GnuPG v1
  -----END PGP MESSAGE-----
secret-key-2: |


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

Pro tip!

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.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s