Encrypt and rotate encryption on a Salt pillar¶
Let’s generate some encrypted pillars and then rotate the keys on them.
Setup¶
Install packages¶
pipx install salt-gnupg-rotate yq
pip install salt-gnupg-rotate yq
Make tutorial directories to work in¶
We will create a new directory for some test pillars and a directory for a temporary gnupg keyring:
mkdir -p rotate-tutorial/{.gnupg/private-keys-v1.d,pillar}
cd rotate-tutorial
chmod 700 .gnupg
Tell gpg
to use this new keyring home directory¶
export GNUPGHOME=$(pwd)/.gnupg
echo $GNUPGHOME
Create the new keyring and list the keys¶
# this will create the empty keyring
gpg --list-keys
# now we can create a new key
echo "Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: salt-controller-key1
Name-Email: tutorial@foo.bar
Expire-Date: 0
%no-protection" | gpg --batch --gen-key
Now list the available secret keys, you should see the key
salt-controller-key1
:
gpg --list-secret-keys
Create some encrypted files¶
Let’s create a completely encrypted file with the contents Hello!
, using the
encryption key salt-controller-key1
and then verify that we can decrypt it:
# create the encrypted file
echo -n 'Hello!' | gpg --encrypt --armor -r salt-controller-key1 > pillar/encrypted_file.gpg
# decrypt the file using the original key
cat pillar/encrypted_file.gpg| gpg --decrypt
Now let’s create a yaml file with one value that has been encrypted:
# encrypt some secret data
echo -n "my-secret-value" | gpg --encrypt --armor -r salt-controller-key1
# create a yaml pillar with an encrypted value
vim pillar/encrypted_pillar.sls
You will need to create a file with a structure similar to:
my-secret-key: |
-----BEGIN PGP MESSAGE-----
<encrypted data>
-----END PGP MESSAGE-----
Once the file has the correct format and encrypted data save and exit your editor.
Create a new secret key we can use to rotate encryption¶
echo "Key-Type: 1
Key-Length: 2048
Subkey-Type: 1
Subkey-Length: 2048
Name-Real: salt-controller-key2
Name-Email: tutorial@foo.bar
Expire-Date: 0
%no-protection" | gpg --batch --gen-key
Now list the available secret keys, now you should see both of the keys
salt-controller-key1
and salt-controller-key2
:
gpg --list-secret-keys
Rotate encryption using salt-gnupg-rotate
¶
First you can just verify that the script can decrypt and re-encrypt the data
using the specified key salt-controller-key2
for re-encryption without errors
by running without the --write
flag:
salt-gnupg-rotate \
--directory ./pillar \
--decryption-gpg-homedir .gnupg \
--encryption-gpg-homedir .gnupg \
-r salt-controller-key2
This should run without error, listing each of the files loaded from the
pillar/
directory.
Now let’s re-run that same command but at a higher logging verbosity so that we can see the contents of the decrypted and re-encrypted blocks in the files:
salt-gnupg-rotate \
--directory ./pillar \
--decryption-gpg-homedir .gnupg \
--encryption-gpg-homedir .gnupg \
-r salt-controller-key2 \
-l trace
Let’s actually write the changes out to disk this time after re-encryption:
salt-gnupg-rotate \
--directory ./pillar \
--decryption-gpg-homedir .gnupg \
--encryption-gpg-homedir .gnupg \
-r salt-controller-key2 \
--write
Check that the encrypted data was rotated¶
To do this we will delete the key that was originally used to encrypt the
pillars salt-controller-key1
and then try to decode them using only the new
key salt-controller-key2
.
First let’s delete the key `salt-controller-key1``:
fingerprint=$(gpg --list-keys salt-controller-key1 | grep -Ev '^(pub|sub|uid)' | head -n1 | awk '{print $1}')
gpg --batch --yes --delete-secret-key "${fingerprint}"
gpg --batch --yes --delete-key "${fingerprint}"
Now let’s try to decrypt the encrypted data:
cat pillar/encrypted_file.gpg | gpg --decrypt
cat pillar/encrypted_pillar.sls | yq '."my-secret-key"' -r | gpg --decrypt
Both of the values should decrypted using the new key salt-controller-key2
🚀