Pillar encryption

If the “Infrastructure as Code” (IaC) approach is used to manage the systems, secret data should never be tracked in plain text in the Git repository. Salt offers the option of encrypting pillars using GPG.

This means that the secret is tracked by Git in encrypted form. The corresponding GPG key is required to decrypt the secret. Decryption is performed by the Salt master.

Pillar? Secrets?

Secrets are stored within pillars. The pillars are therefore are encrypted, which ultimately represents a secret.


Creation of the GPG key pair

A new key pair without password protection should be created.

Create GPG key
mkdir /etc/salt/gpgkeys
chmod 700 /etc/salt/gpgkeys
gpg --gen-key --homedir /etc/salt/gpgkeys

The directory /etc/salt/gpgkeys may only be read by the user executing the salt master.

Which user executes the master?
ps aux | grep salt-master

The user name is displayed in the first column.

Set authorizations
chown -R <user>:<group> /etc/salt/gpgkeys

Configuration of the Salt master

The configuration gpg_keydir must now be transferred to the salt master.

Salt master configuration
echo 'gpg_keydir: /etc/salt/gpgkeys' > /etc/salt/master.d/gpg-pillar.conf
systemctl reload-or-restart salt-master

Creation of an encrypted secret

First of all, the key ID must be found out:

Find out the key ID
gpg --homedir /etc/salt/gpgkeys --list-secret-keys 
sec   rsa3072 2023-09-05 [SC] [expires: 2025-09-04]
      940CBABC0E803D252E7853F3AE0F5E016A10900C
uid           [ultimate] Test User <test@example.com>
ssb   rsa3072 2023-09-05 [E] [expires: 2025-09-04]

The key ID of the GPG key is: 940CBABC0E803D252E7853F3AE0F5E016A10900C

The encrypted secret can be created as follows:

Create encrypted secret
echo -n 'supersecret' | gpg --trust-model always -ear 940CBABC0E803D252E7853F3AE0F5E016A10900C --homedir /etc/salt/gpgkeys
-----BEGIN PGP MESSAGE-----

hQGMA7vGc9C+pa4RAQwAnSpElvq4Ag0GEFlrHn/gduGRj0/aDxlZgXuXEniGNwjG
3N2+oN13Hd1sHEv5gEBXTyes/LAIyXA8nYuG1wmF1A6F110tKJM0jueq5sSdrEsV
WmXXNAVUHIHDyj01rZVgN6GdEYdFHgZ2bgi2zlVWRDQO8CHJeUrQEMMuC6o6jdj7
4l4b1Fi0QSQt49kNUqmT/iqmQvjzz7XYoLZYlCoyYje8qe0dqJIRjMdPhNd6PnfN
vJKRKD4AOk29dPEhhPOYbJ5SeMALfNnpR7h1opK/IazOlFr6fS4ipjWUYog+QdHk
BrOmty1jH5wsStYoIm+g2SicovDLUujl1yD126nsKck/6s5mCiX8PhwIdfoVYIDp
SMyl+Fe5gEE9o6AiYOYJN51IUbjVJCxz6vyj5abbGXVfiooV02+JIlVlCliAqzd2
nuUpxWzPRO8J95XLL0MlZlGb9vZioTWEaocMCYnG7mhAK1DGZGb8pfTtJZyco5gU
IqxAwplFPNxeZfM6r8a60kYBoYP7YWdZXzfQafZiTNbU0A1Ud4YJcqXbuOzIgQHi
jlco7OyzdMCb5TBAfqyJPZd0Dkzef6/ER0rLSl+1cKaGzrAcZ8oy
=g+n0
-----END PGP MESSAGE-----
Use of an alias

The command gpg --trust-model always -ear 940CBABC0E803D252E7853F3AE0F5E016A10900C --homedir /etc/salt/gpgkeys can also be defined as an alias.

Create alias
echo "alias gpg_encrypt='gpg --trust-model always -ear 940CBABC0E803D252E7853F3AE0F5E016A10900C --homedir /etc/salt/gpgkeys'" >> ~/.bashrc
source ~/.bashrc
echo -n 'supersecret' | gpg_encrypt

Use of the encrypted secret

The PGP message created can now be defined as a pillar.

secret.sls
secret.sls
srvsaltpillarsecret.sls
123456789101112131415161718
#!yaml|gpg
---
data1: this is not encrypted
data2: |
    -----BEGIN PGP MESSAGE-----

    hQGMA7vGc9C+pa4RAQwAnSpElvq4Ag0GEFlrHn/gduGRj0/aDxlZgXuXEniGNwjG
    3N2+oN13Hd1sHEv5gEBXTyes/LAIyXA8nYuG1wmF1A6F110tKJM0jueq5sSdrEsV
    WmXXNAVUHIHDyj01rZVgN6GdEYdFHgZ2bgi2zlVWRDQO8CHJeUrQEMMuC6o6jdj7
    4l4b1Fi0QSQt49kNUqmT/iqmQvjzz7XYoLZYlCoyYje8qe0dqJIRjMdPhNd6PnfN
    vJKRKD4AOk29dPEhhPOYbJ5SeMALfNnpR7h1opK/IazOlFr6fS4ipjWUYog+QdHk
    BrOmty1jH5wsStYoIm+g2SicovDLUujl1yD126nsKck/6s5mCiX8PhwIdfoVYIDp
    SMyl+Fe5gEE9o6AiYOYJN51IUbjVJCxz6vyj5abbGXVfiooV02+JIlVlCliAqzd2
    nuUpxWzPRO8J95XLL0MlZlGb9vZioTWEaocMCYnG7mhAK1DGZGb8pfTtJZyco5gU
    IqxAwplFPNxeZfM6r8a60kYBoYP7YWdZXzfQafZiTNbU0A1Ud4YJcqXbuOzIgQHi
    jlco7OyzdMCb5TBAfqyJPZd0Dkzef6/ER0rLSl+1cKaGzrAcZ8oy
    =g+n0
    -----END PGP MESSAGE-----

Prüfung

Once the Pillar file has been created, it must be assigned to the target system in the top.sls file. The pillar can then be reloaded and output.

Check Pillar
salt '*' saltutil.refresh_pillar
salt '*' pillar.get data2
host:
    supersecret