Skip to content

Commit bfde7a8

Browse files
committed
Final review changes
1 parent 704db99 commit bfde7a8

File tree

1 file changed

+70
-19
lines changed
  • docs/applications/configuration-management/secrets-management-with-salt

1 file changed

+70
-19
lines changed

docs/applications/configuration-management/secrets-management-with-salt/index.md

Lines changed: 70 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,50 +13,101 @@ title: "Secrets Management with Salt"
1313
contributor:
1414
name: Linode
1515
external_resources:
16+
- '[Salt Pillar Walkthrough](https://docs.saltstack.com/en/latest/topics/tutorials/pillar.html)'
1617
- '[Using Environmental Variables in SLS Modules](https://docs.saltstack.com/en/latest/topics/tutorials/states_pt3.html#using-environment-variables-in-sls-modules)'
1718
- '[Salt GPG Renderer](https://docs.saltstack.com/en/latest/ref/renderers/all/salt.renderers.gpg.html)'
1819
- '[Salt SDB Documentation](https://docs.saltstack.com/en/latest/topics/sdb/)'
1920
- '[Salt SDB Modules](https://docs.saltstack.com/en/latest/ref/sdb/all/index.html)'
2021
---
2122

22-
Salt is a powerful configuration management tool. It allows you to control your server configurations with flat files that are easily shared with others on your team. However, it is common to need access to sensitive data like API keys and database passwords within these state files. Because this information is typically stored as plain text, this creates a serious security flaw, especially when this data could be stored in a remote repository. This guide will explore the known methods for securing your secrets within Salt.
23+
Salt is a powerful configuration management tool which helps you manage your server deployments with configuration *state* files. These files are easily shared with others on your team and can be checked in to version control systems like Git.
2324

24-
## Pillar Files
25+
A common problem when working with Salt's state files is the need access to sensitive data, like API keys and database passwords, within those files. Directly embedding that information as plain-text inside your state files can represent a security vulnerability, especially if you were to check those files into version control. This guide will explore some common methods for securing your secrets within Salt.
2526

26-
The most obvious method for storing secrets in Salt is to employ a Pillar. Pillars are designed to house global values that are intended for specific minions. By putting your secrets into Pillars and not into state files you can effectively remove those secrets from version control by not committing your Pillars. This method requires some extra planning however, especially because not *all* Pillar data is sensitive, and so some Pillar files might still make it into version control. You could create a special directory at `/srv/pillar/secrets` and add that folder to your `.gitignore` file to separate your sensitive and non-sensitive data. For quick reference, it might also be necessary to create a `pillar.example` file, like those provided by Salt formulas, that lists all the known variable keys so that you can shorten the time it takes to set up a Salt system.
27+
## Salt Pillar
2728

28-
You can also supply Pillar values as a dictionary through the command line, and these files will override any Pillar values set in your Pillar files.
29+
A primary method for storing secrets in Salt is to keep them in Salt's *Pillar* feature. Salt Pillar is designed to maintain secrets and other variable information in a single location (generally, on the Salt master) and then deliver that information to specific minions. If you separate your secrets out from your states and into pillar files, you can ignore those files in your version control system.
2930

30-
salt '*' state.apply pillar='{"mysecret": "secret"}'
31+
{{< note >}}
32+
In addition to storing secrets, Salt Pillar can also maintain non-sensitive data; for example, the versions of the packages you want to install on your minions. So, you may still want to track some pillar files in version control.
33+
34+
To handle this distinction, you could create a special directory at `/srv/pillar/secrets` and add set your version control system to ignore that directory (when using Git, list this directory in your `.gitignore` file). Keep all sensitive data inside pillar files within this directory, and maintain non-sensitive data in pillar files in `/srv/pillar` or another subfolder.
35+
{{< /note >}}
36+
37+
### Anatomy of Pillar Data Files
38+
39+
Pillar data is kept in `.sls` files which are written in the same YAML syntax as states. These are generally stored within `/srv/pillar` on the Salt master, but this location can be configured via the `pillar_roots` option in your master's configuration.
40+
41+
For example, let's say your minion runs an application which accesses the Linode API. This pillar file keeps your API token in a variable called `linode_api_token`:
42+
43+
{{< file "/srv/pillar/app_secrets.sls" >}}
44+
linode_api_token: YOUR_API_TOKEN
45+
{{< /file >}}
46+
47+
As with state files, a top file (separate from your states’ top file) maps pillar data to minions. This example top file maps your `app_secrets` pillar data to your app server:
48+
49+
{{< file "/srv/pillar/top.sls" >}}
50+
base:
51+
'appserver':
52+
- app_secrets
53+
{{< /file >}}
54+
55+
{{< note >}}
56+
You may want to create a `pillar.example` file (like those provided by Salt formulas) that lists all the known variable keys for your pillar but does not contain the actual secrets. If you check this file into your version control, other users that clone your states' repository can duplicate this example pillar file and more quickly set up their own deployments.
57+
{{< /note >}}
58+
59+
### Accessing Pillar Data inside Salt States
3160

32-
The downside of this approach is that there are times when Pillar data could show up in the output that Salt generates, like when `file.managed` displays diffs of a modified file. To avoid displaying these diffs, you can set `file.managed`'s `show_diff` flag to false.
61+
To inject pillar data into your states, use Salt's Jinja template syntax. While Salt uses the YAML syntax for state and pillar files, the files are first interpreted as Jinja templates (by default).
62+
63+
This example embeds the API token from Salt Pillar in a file on your Linode (which could later be consumed by your app to access the Linode API). The data is accessed through the `pillar` dictionary:
64+
65+
{{< file "/srv/salt/setup_app.sls" >}}
66+
api_token:
67+
file.managed:
68+
- name: /var/your_app/api_token
69+
- contents: {{ pillar['linode_api_token'] }}
70+
{{< /file >}}
71+
72+
### Passing Pillar Data at the Command Line
73+
74+
You can also supply pillar values as a dictionary through the command line, and values files will override any values set in your pillar files. This example command would apply the `A_DIFFERENT_API_TOKEN` value instead of the original `YOUR_API_TOKEN` from the previous example:
75+
76+
salt '*' state.apply pillar='{"linode_api_token": "A_DIFFERENT_API_TOKEN"}'
77+
78+
{{< caution >}}
79+
There are times when pillar data could show up in the output that Salt generates, like when `file.managed` displays diffs of a modified file. To avoid displaying these diffs, you can set `file.managed`'s `show_diff` flag to false.
80+
{{< /caution >}}
3381

3482
## Environment Variables
3583

36-
Similar to passing in Pillar data via the command line, another way to keep sensitive values out of version control is to use environment variables. For example, you might issue the following command:
84+
Another way to keep sensitive values out of version control is to use environment variables. The method for passing environment variables to your states is similar to how pillar data can be passed via the command line. For example, you might issue the following command:
3785

38-
SUPERSECRET="secret" salt '*' state.apply example.sls
86+
LINODE_API_TOKEN="YOUR_API_TOKEN" salt '*' state.apply example.sls
3987

40-
The environment variable is referenced by a Salt state file through `salt['environ.get']('SUPERSECRET')`.
88+
The environment variable is referenced by a Salt state file through the `salt['environ.get']('ENVIRONMENT_VARIABLE_NAME')` syntax. The previous `setup_app` example state can be adapted to use an environment variable as follows:
4189

42-
{{< file "/srv/salt/example.sls" >}}
43-
my_managed_file:
90+
{{< file "/srv/salt/setup_app.sls" >}}
91+
api_token:
4492
file.managed:
45-
- name: /tmp/example
46-
- contents: {{ salt['environ.get']('SUPERSECRET') }}
47-
{{</ file >}}
93+
- name: /var/your_app/api_token
94+
- contents: {{ salt['environ.get']('LINODE_API_TOKEN') }}
95+
{{< /file >}}
4896

49-
As it is with the Pillar example mentioned above, you'll want to keep `file.managed`'s diffs from appearing on screen when dealing with sensitive information by setting `show_diff: false`. For more information, see [Using Environment Variables in SLS Modules](https://docs.saltstack.com/en/latest/topics/tutorials/states_pt3.html#using-environment-variables-in-sls-modules).
97+
As with the previous pillar example, you'll want to keep `file.managed`'s diffs from appearing on screen when dealing with sensitive information by setting `show_diff: false`. For more information, see [Using Environment Variables in SLS Modules](https://docs.saltstack.com/en/latest/topics/tutorials/states_pt3.html#using-environment-variables-in-sls-modules).
5098

5199
## GPG Encryption
52100

53-
You can use the [GPG renderer](https://docs.saltstack.com/en/latest/ref/renderers/all/salt.renderers.gpg.html) to decrypt GPG ciphers that are located in your Pillar files before those values are passed to Salt minions. This means that any value in a Pillar file can be encrypted, allowing state files to be stored in version control. This approach requires that the GPG secret key is stored on your Salt master, and it makes sense to include the public key in version control so that is available to your team.
101+
You can use Salt's [GPG renderer](https://docs.saltstack.com/en/latest/ref/renderers/all/salt.renderers.gpg.html) to decrypt GPG ciphers that are located in your pillar files. This decryption step happens before your pillar data is passed to your minions. As a result, any value in a pillar file can be encrypted. Because the values are encrypted, you can store your pillar files in version control securely.
102+
103+
This approach requires that the GPG secret key is stored on your Salt master. It also makes sense to include the public key in version control so that your team members can use it to encrypt new data for your pillar files.
54104

55105
## SDB
56106

57-
Salt comes with a database interface called SDB that was initially created to store non minion-specific data, such as passwords. It was designed to connect to a package like [keyring](https://docs.saltstack.com/en/latest/ref/sdb/all/salt.sdb.keyring_db.html), but other options are available, such as [Consul](https://docs.saltstack.com/en/latest/ref/sdb/all/salt.sdb.consul.html) and [Vault](https://docs.saltstack.com/en/latest/ref/sdb/all/salt.sdb.vault.html#module-salt.sdb.vault). These databases are set up using a configuration profile in `/srv/salt/master.d`. To access data, you supply an `sdb://` url, such as `password: sdb://mysecrets/mypassword`. For more information on SDB, reference the [Salt SDB documentation](https://docs.saltstack.com/en/latest/topics/sdb/).
107+
Salt comes with a database interface called *SDB* that was initially created to store non-minion-specific data, such as passwords. It was designed to connect to a package like Salt's [*keyring*](https://docs.saltstack.com/en/latest/ref/sdb/all/salt.sdb.keyring_db.html) module, but other options are available, such as [Consul](https://docs.saltstack.com/en/latest/ref/sdb/all/salt.sdb.consul.html) and [Vault](https://docs.saltstack.com/en/latest/ref/sdb/all/salt.sdb.vault.html#module-salt.sdb.vault).
108+
109+
These databases are set up using a configuration profile in `/srv/salt/master.d`. To access data, you supply an `sdb://` url, such as `password: sdb://mysecrets/mypassword`. For more information on SDB, reference the [Salt SDB documentation](https://docs.saltstack.com/en/latest/topics/sdb/).
58110

59111
{{< note >}}
60-
Salt also provides a module that allows [pillar data to be stored in Vault](https://docs.saltstack.com/en/latest/ref/pillar/all/salt.pillar.vault.html) and a module that includes [functions to interact with Vault](https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.vault.html#vault-setup).
112+
Salt also provides a module that allows [pillar data to be stored in Vault](https://docs.saltstack.com/en/latest/ref/pillar/all/salt.pillar.vault.html), as well as an execution module that includes [functions to interact with Vault](https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.vault.html#vault-setup).
61113
{{</ note >}}
62-

0 commit comments

Comments
 (0)