Encrypting Pillar Data with GPG
This guide assumes the GPG renderer is available on the Salt master. On RHEL Linux this typically requires:
dnf install gnupg
1. Generate config file¶
Create the following config file: /etc/salt/master.d/gpg_renderer.conf
# This config file allows the salt master to decrypt gpg blocks when found in pillar or state files
# Renderer decryption key (Must be owned by the salt user, not root)
# The `gpg_keydir` directory must be readable by the user running the `salt-master` service (commonly `salt`).
gpg_keydir: /etc/salt/gpgkeys
Restart the salt master to load the config
2. Generate gpg keys¶
As root on the salt master we generate a set of gpg keys, then assign them to the salt user or which ever user you have assigned to run the salt-master service.
mkdir -p /etc/salt/gpgkeys
# Generate key as root
gpg --homedir /etc/salt/gpgkeys --full-generate-key
# Prompt answers:
# 1 Protocol: RSA
# 2 Key Length: 4096
# 3 Expiry: 0 (no expiry)
# 4 name: e.g. salt-master
# 5 email e.g. salt@lab.local
# fix ownership & perms
chown -R salt:salt /etc/salt/gpgkeys
chmod 700 /etc/salt/gpgkeys
find /etc/salt/gpgkeys -type f -exec chmod 600 {} \;
# verify key is visible as the salt account
sudo -u salt gpg --homedir /etc/salt/gpgkeys --list-secret-keys
3. Encrypt data¶
To encrypt data use the gpg command to generate the cipher text:
Ensure the recipient name (-r) matches the UID created during key generation (Prompt 4 above).
echo 'SuperSecretADJoinPassword!' | \
gpg --homedir /etc/salt/gpgkeys --armor --encrypt -r "salt-master"
You will get an output similar to:
-----BEGIN PGP MESSAGE-----
hQIMA58OzV1dGzRKAQ/9FhKhFKN5QPotVEClktekPoO+pu1AXjkDasKyWpTlIgBo
oqFpd/3P56HhhLnDRA9Nx/eAytsc76I3Rz0w9rx/HogJTv0eXj8ZijkZdO9dpxkN
hWJS8CDqiyumpunjZXXB0dn9YITejlVrJ8Y+hHBe8CTye5y0sGKlvuHbrp3kgyvh
IVxIrHNlu+LsJMBzowAO7V2lhHqzBXGUqSjxxtjZaI8IlbAjgVzRwfUG4tOiPOoo
9FL8mGeo50QcasraUlsAz9PQrKuj8u6bMNb0q4PoMb5il9v4R5pGXTKNK72K4xGA
VfXw8/phI71nXi3Md7CHfAAa8n5mfxhNDVVtTWt7wVsrsdtWPv/Rq7uBTHXYXcqo
oGlMZiigj/l0ys20/LEbLI9ymaXP1dPX+AvqKFZP151u9IUH0rNIhoBd29+RhGwP
wPdAo7RIxcStI+gE3DYT7qi6bZOsB6RMMVq6hsiJpKEQz3GxVvZRrStkjOTQ+G4l
zKPkcjYwH8bskG0C6fE6CxakmEC3n3ym8IUaKWCI+6wrvdfbcUvV7FQf8Kp7dIHj
1Z4bJbowXje+QqPYia/JB0aJNPnUg7vNPwCskz/BmkooPHHZF43G1eCSCEJrDCCl
BtPgdQVZAsaXxo1j5p1O5tROvpiU58bOO/LoakjJAtiymn7lbFFEvz0/m4BpbFjU
YAEJAhDEzi70XcyM19QsPeMd6wUWJlE/d4AbtX0v2uHyIAhkMLQd1luLoL/Nv8q4
b6r4Dp7I259oZY/wrp3g8m3MLH9huGnmFJ65M3Yq/D25PjXXKqwT1nPh8P9sWkVg
pA==
=x/Aq
-----END PGP MESSAGE-----
Copy the text block (including the "BEGIN PGP MESSAGE" ) and paste it as the value in your pillar file.
Example:
#!yaml|gpg
ad_join:
domain: lab.local
user: svc_adjoin
password: |
-----BEGIN PGP MESSAGE-----
<paste encrypted blob here>
-----END PGP MESSAGE-----
#!yaml|gpg instructs Salt to first process the file through the GPG renderer, then render the decrypted result as YAML.
Optionally you can update the top.sls file with how this pillar data should be distributed. In this example we are pushing this data to any minion who reports its OS as from the Microsoft Windows family:
base:
# Existing top entries remain
# ...
#
# Target minions where grain os matches "Windows"
'os:Windows':
- match: grain
- ad.ad_join
Commit and push and then run a git_pillar.update
salt-run git_pillar.update
4. Verify the pillar data is available to a minion¶
You can run the pillar.items command against a minion to verify the secret value is correctly decrypted and available to the minion.
#> salt 'win-test' pillar.items
win-test:
----------
ad_join:
----------
domain:
lab.local
password:
SuperSecretADJoinPassword!
user:
svc_adjoin
fileserver:
----------
artifact_root:
artifacts
base_url:
http://192.168.50.21
Warning
Anyone with access to the Salt master’s private GPG key can decrypt all encrypted pillar data.
Protect /etc/salt/gpgkeys appropriately.