File: secretGeneratorPlugin.md

package info (click to toggle)
kustomize 5.6.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,572 kB
  • sloc: makefile: 162; sh: 123
file content (221 lines) | stat: -rw-r--r-- 5,131 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
[ConfigMaps]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#configmap-v1-core
[ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
[Go plugin]: https://golang.org/pkg/plugin
[Secrets]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#secret-v1-core
[base64]: https://tools.ietf.org/html/rfc4648#section-4
[configuration directory]: https://wiki.archlinux.org/index.php/XDG_Base_Directory#Specification
[grpc]: https://grpc.io
[tag]: /../../releases
[v2.0.3]: /../../releases/tag/v2.0.3
[`exec.Command`]: https://golang.org/pkg/os/exec/#Command

# Generating Secrets

## What's a Secret?

Kubernetes [ConfigMaps] and [Secrets] are both
key:value maps, but the latter is intended to
signal that its values have a sensitive nature -
e.g. pass phrases or ssh keys.

Kubernetes developers work in various ways to hide
the information in a Secret more carefully than
the information held by ConfigMaps, Deployments,
etc.

## Make a place to work

<!-- @establishBase @testAgainstLatestRelease -->
```
DEMO_HOME=$(mktemp -d)
```

## Secret values from local files

kustomize has three different (builtin) ways to
generate a secret from local files:

 * get them from so-called _env_ files (`NAME=VALUE`, one per line),
 * consume the entire contents of a file to make one secret value,
 * get literal values from the kustomization file itself.

Here's an example combining all three methods:

Make an env file with some short secrets:

<!-- @makeEnvFile @testAgainstLatestRelease -->
```
cat <<'EOF' >$DEMO_HOME/foo.env
ROUTER_PASSWORD=admin
DB_PASSWORD=iloveyou
EOF
```

Make a text file with a long secret:

<!-- @makeLongSecretFile @testAgainstLatestRelease -->
```
cat <<'EOF' >$DEMO_HOME/longsecret.txt
Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.
EOF
```

And make a kustomization file referring to the
above and _additionally_ defining some literal KV
pairs in line:

<!-- @makeKustomization1 @testAgainstLatestRelease -->
```
cat <<'EOF' >$DEMO_HOME/kustomization.yaml
secretGenerator:
- name: mysecrets
  envs:
  - foo.env
  files:
  - longsecret.txt
  literals:
  - FRUIT=apple
  - VEGETABLE=carrot
EOF
```

Now generate the Secret:

<!-- @build1 @testAgainstLatestRelease -->
```
result=$(kustomize build $DEMO_HOME)
echo "$result"
# Spot check the result:
test 1 == $(echo "$result" | grep -c "FRUIT: YXBwbGU=")
```

This emits something like

> ```
> apiVersion: v1
> kind: Secret
> metadata:
>   name: mysecrets-hfb5df789h
> type: Opaque
> data:
>   FRUIT: YXBwbGU=
>   VEGETABLE: Y2Fycm90
>   ROUTER_PASSWORD: YWRtaW4=
>   DB_PASSWORD: aWxvdmV5b3U=
>   longsecret.txt: TG9yZW0gaXBzdW0gZG9sb3Igc2l0I... (elided)
> ```

The name of the resource is the prefix `mysecrets`
(as specfied in the kustomization file), followed
by a hash of its contents.

Use your favorite base64 decoder to confirm the raw
versions of any of these values.

The problem that these three approaches share is
that the purported secrets must live on disk.

This adds additional security questions - who can
see the files, who installs them, who deletes
them, etc.


## Secret values from anywhere

A general alternative is to enshrine secret
value generation in a [plugin](../docs/plugins).

The values can then come in via, say, an
authenticated and authorized RPC to a password
vault service.

[sgp]: ../plugin/someteam.example.com/v1/secretsfromdatabase

Here's a [secret generator plugin][sgp]
that pretends to pull the values of a map
from a database.


Download it

<!-- @copyPlugin @testAgainstLatestRelease -->
```
repo=https://raw.githubusercontent.com/kubernetes-sigs/kustomize
pPath=plugin/someteam.example.com/v1/secretsfromdatabase
dir=$DEMO_HOME/kustomize/$pPath

mkdir -p $dir

curl -s -o $dir/SecretsFromDatabase.go \
  ${repo}/master/$pPath/SecretsFromDatabase.go
```

Compile it

<!-- @compilePlugin @xtest -->
```
go build -buildmode plugin \
  -o $dir/SecretsFromDatabase.so \
  $dir/SecretsFromDatabase.go
```


Create a configuration file for it:

<!-- @makeConfiguration @testAgainstLatestRelease -->
```
cat <<'EOF' >$DEMO_HOME/secretFromDb.yaml
apiVersion: someteam.example.com/v1
kind: SecretsFromDatabase
metadata:
  name: mySecretGenerator
name: forbiddenValues
namespace: production
keys:
- ROCKET
- VEGETABLE
EOF
```

Create a new kustomization file
referencing this plugin:

<!-- @makeKustomization2 @testAgainstLatestRelease -->
```
cat <<'EOF' >$DEMO_HOME/kustomization.yaml
generators:
- secretFromDb.yaml
EOF
```

Finally, generate the secret, setting
`XDG_CONFIG_HOME` so that the plugin
can be found under `$DEMO_HOME`:

<!-- @build2 @xtest -->
```
result=$( \
  XDG_CONFIG_HOME=$DEMO_HOME \
  kustomize build --enable_alpha_plugins $DEMO_HOME )
echo "$result"
# Spot check the result:
test 1 == $(echo "$result" | grep -c "FRUIT: YXBwbGU=")
```

This should emit something like:

> ```
> apiVersion: v1
> kind: Secret
> metadata:
>   name: mysecrets-bdt27dbkd6
> type: Opaque
> data:
>  FRUIT: YXBwbGU=
>  VEGETABLE: Y2Fycm90
> ```

i.e. a subset of the same values as above.