This secret storage solution fits natively into any Salt infrastructure. This
means SaltStack provides the functionality for this service out of the box. It
simply requires some configuration and initial setup. The following sections
will outline each stop in the process.

For a really high level overview here’s how each of these components fit
together:

The Salt Master will be the central storage server. All secrets will be stored
within the pillar data on the master (usually /srv/pillar/). Each secret is
stored on the master in a GPG encrypted cipher. The public and private GPG keys
are only ever stored on the master. GPG keys never need to be shared to
minions. The python-gnupg library needs to be installed on any minion
wanting to request secure keys. Lastly, assuming you’ll want to secure your
encrypted secrets with a GPG key passphrase, you’ll need a configured GPG agent
to unlock these secrets upon request, without the requirement of entering a
passphrase each time.

The secret store is housed on the SaltStack master within the Pillar system.
This allows for the secrets to be available to any connected system, with
access limitations defined by the Pillar top file. In some of my early
discussions about this architecture there was some concern about the privacy
and general access to the secret store server. It should be noted that the
SaltStack master should restrict general access just as any “vault” would. If
you can’t trust your administrators that have root access to your systems with
the secrets stored on your server, well, I’d say you have bigger problems. This
configuration assumes access to the SaltStack master is restricted to those
with root access to the general infrastructure.

Note

Anyone with root access on the SaltStack master will be able to retrieve any
encrypted secret.

The pillar system sits at the heart of this secret storage solution. This is
where the data is stored and where limitations on access to the data is
configured. In this example I assume the default path for pillar data,
/srv/pillar.

First, if it doesn’t yet exist, create the pillar path:

mkdir -p /srv/pillar

Second, populate a default top.sls file. This file is where you map data to
minions.

base:'*':-cache'alpha':-vault1'bravo':-vault2

In the example above I’ve made accessible anything in the cache.sls file to
all machines. The vault1.sls is accessible only to the host alpha, and
vault2.sls only available to bravo. You’ll of course want to update these
values to represent your own system names.

The SaltStack minions will generally be the source for queries against the
secret store. By defining restrictions within the Pillar configuration you can
limit which machines have access to specific secrets or groups of secrets.
Secrets are queried from the minions using the pillar module. I’ve included
a few examples below:

The command below will query for the value of the secret1 key. This key
represents a key-value store within one of the “vaults” available to this
system.

salt-call pillar.item secret1

If you would like to request all secrets available to a specific system you can
use a similiar command:

salt-call pillar.items

Note

Different outputters can be used when retrieving these secrets.
Outputters include --json, --raw, --txt, yaml_out, and more.