Skip to content

Commit 2476d05

Browse files
authored
fix: enable commit signing (#21)
1 parent fe4b2b4 commit 2476d05

File tree

8 files changed

+284
-17
lines changed

8 files changed

+284
-17
lines changed

.gitleaks.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@
22
useDefault = true
33

44
[allowList]
5-
paths = ['''snyk-universal-broker/tests''']
5+
paths = [
6+
'''snyk-universal-broker/tests''',
7+
'''snyk-universal-broker/values.schema.json''',
8+
'''README.md'''
9+
]

README.md

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,58 @@ image:
179179
- name: containers-company-secret
180180
```
181181

182+
### Commit Signing
183+
184+
Snyk Broker commit signing is in [Early Access](https://docs.snyk.io/getting-started/snyk-release-process#open-beta). If you would like to use this feature, contact your Snyk representative or team.
185+
186+
This feature requires a GitHub Account that has a GPG key configured for commit signing.
187+
188+
#### Via Helm
189+
190+
Provide the GPG key (exported as an ASCII armored version), the passphrase, and associated email/user:
191+
192+
```yaml
193+
commitSigning:
194+
name: "Account Name"
195+
196+
passphrase: "passphrase"
197+
gpgPrivateKey: -----BEGIN PGP PRIVATE KEY BLOCK-----\n....\n-----END PGP PRIVATE KEY BLOCK-----
198+
```
199+
200+
The Universal Broker Helm Chart creates this secret for you.
201+
202+
#### Via External Secret
203+
204+
First create or otherwise ensure the secret exists:
205+
206+
```yaml
207+
kind: Secret
208+
apiVersion: v1
209+
metadata:
210+
name: gpg-signing-key
211+
data:
212+
GPG_PRIVATE_KEY: "-----BEGIN PRIVATE KEY BLOCK-----..."
213+
GPG_PASSPRHASE: "passphrase"
214+
GIT_COMMITTER_EMAIL: "[email protected]"
215+
GIT_COMMITTER_NAME: "User Name"
216+
```
217+
218+
The keys **must** match the example above.
219+
220+
Then set values within `.Values.commitSigningSecret` to reference this external Secret:
221+
```yaml
222+
commitSigning:
223+
enabled: true
224+
commitSigningSecret:
225+
name: gpg-signing-key
226+
```
227+
228+
Commit signing is enabled if the following entry appears in Universal Broker logs at startup:
229+
230+
```
231+
loading commit signing rules (enabled=true, rulesCount=5)
232+
```
233+
182234
## Parameters
183235

184236
### Snyk Broker parameters
@@ -190,22 +242,28 @@ Credential References should contain one or more key/value pairs where each key
190242
helm install ... --set credentialReferences.MY_GITHUB_TOKEN=<gh-pat>
191243
```
192244

193-
| Name | Description | Value |
194-
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
195-
| `brokerClientUrl` | is the address of the broker. This needs to be the address of itself. In the case of Kubernetes, you need to ensure that you are pointing to the cluster ingress you have setup. | `""` |
196-
| `region` | Optionally specify a Snyk Region - e.g. "eu" for "SNYK-EU-01". Defaults to "SNYK-US-01", app.snyk.io | `""` |
197-
| `preflightChecks.enabled` | broker client preflight checks | `true` |
198-
| `deploymentId` | Obtained by installing the Broker App | `""` |
199-
| `clientId` | Obtained by installing the Broker App | `""` |
200-
| `clientSecret` | Obtained by installing the Broker App | `""` |
201-
| `platformAuthSecret.name` | Optionally provide an external secret containing three keys: `DEPLOYMENT_ID`, `CLIENT_ID` and `CLIENT_SECRET` | `""` |
202-
| `credentialReferences` | Credential References to pass to Broker | `{}` |
203-
| `credentialReferencesSecret.name` | Optionally provide a pre-existing secret with SCM credential reference data | `""` |
204-
| `acceptCode` | Set to false to block Broker rules relating to Snyk Code analysis | `true` |
205-
| `acceptAppRisk` | Set to false to block Broker rules relating to AppRisk | `true` |
206-
| `acceptIaC` | Defaults to "tf,yaml,yml,json,tpl". Optionally remove any extensions not required. Must be comma separated. Set to "" to block Broker rules relating to Snyk IaC analysis | `""` |
207-
| `acceptCustomPrTemplates` | Set to false to block Broker rules relating to Snyk Custom PR Templates | `true` |
208-
| `acceptLargeManifests` | Set to false to block Broker rules relating to fetching of large files from GitHub/GitHub Enterprise | `true` |
245+
| Name | Description | Value |
246+
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
247+
| `brokerClientUrl` | is the address of the broker. This needs to be the address of itself. In the case of Kubernetes, you need to ensure that you are pointing to the cluster ingress you have setup. | `""` |
248+
| `region` | Optionally specify a Snyk Region - e.g. "eu" for "SNYK-EU-01". Defaults to "SNYK-US-01", app.snyk.io | `""` |
249+
| `preflightChecks.enabled` | broker client preflight checks | `true` |
250+
| `deploymentId` | Obtained by installing the Broker App | `""` |
251+
| `clientId` | Obtained by installing the Broker App | `""` |
252+
| `clientSecret` | Obtained by installing the Broker App | `""` |
253+
| `platformAuthSecret.name` | Optionally provide an external secret containing three keys: `DEPLOYMENT_ID`, `CLIENT_ID` and `CLIENT_SECRET` | `""` |
254+
| `credentialReferences` | Credential References to pass to Broker | `{}` |
255+
| `credentialReferencesSecret.name` | Optionally provide a pre-existing secret with SCM credential reference data | `""` |
256+
| `acceptCode` | Set to false to block Broker rules relating to Snyk Code analysis | `true` |
257+
| `acceptAppRisk` | Set to false to block Broker rules relating to AppRisk | `true` |
258+
| `acceptIaC` | Defaults to "tf,yaml,yml,json,tpl". Optionally remove any extensions not required. Must be comma separated. Set to "" to block Broker rules relating to Snyk IaC analysis | `""` |
259+
| `acceptCustomPrTemplates` | Set to false to block Broker rules relating to Snyk Custom PR Templates | `true` |
260+
| `acceptLargeManifests` | Set to false to block Broker rules relating to fetching of large files from GitHub/GitHub Enterprise | `true` |
261+
| `commitSigning.enabled` | Set to true to sign any commits made to GitHub or GitHub Enterprise. Requires `name`, `email`, `passphrase`, `privateKey` _or_ `commitSigningSecret` | `false` |
262+
| `commitSigning.name` | The name to associate with any signed commits | `""` |
263+
| `commitSigning.email` | The email to associate with any signed commits | `""` |
264+
| `commitSigning.gpgPrivateKey` | The GPG private key to sign commits with (ASCII armored version) | `""` |
265+
| `commitSigning.passphrase` | The passpharse for the GPG key | `""` |
266+
| `commitSigningSecret` | An external secret containing `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL`, `GPG_PASSPHRASE` and `GPG_PRIVATE_KEY` | `""` |
209267

210268
### Networking Parameters
211269

snyk-universal-broker/templates/_helpers.tpl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,13 @@ Each credential must be a valid env var, with associated string value
104104
{{- end }}
105105

106106
{{/*
107+
Create a name for the Commit Signing secret, using a provided override if present
108+
*/}}
109+
{{- define "snyk-broker.commitSigningSecretName" -}}
110+
{{- .Values.commitSigningSecret.name | default ( include "snyk-broker.genericSecretName" (dict "Context" . "secretName" "commit-signing-secret" ) ) -}}
111+
{{- end }}
112+
113+
{{/*}}
107114
Snyk Broker ACCEPT_ vars
108115
*/}}
109116
{{- define "snyk-broker.accepts" -}}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{{- if and .Values.commitSigning.enabled ( not .Values.commitSigningSecret.name ) }}
2+
{{- $unsetKeys:= list -}}
3+
{{- range ( unset .Values.commitSigning "enabled" | keys ) -}}
4+
{{- if not (get $.Values.commitSigning . ) }}
5+
{{- $unsetKeys = append $unsetKeys . -}}
6+
{{- end }}
7+
{{- end }}
8+
{{- if gt (len $unsetKeys) 0 -}}
9+
{{- fail (printf "Missing value(s) under .Values.commitSigning for: %s" (join "," $unsetKeys) ) }}
10+
{{- end }}
11+
apiVersion: v1
12+
kind: Secret
13+
metadata:
14+
name: {{ include "snyk-broker.commitSigningSecretName" . }}
15+
namespace: {{ .Release.Namespace }}
16+
labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
17+
data:
18+
GPG_PRIVATE_KEY: {{ .Values.commitSigning.gpgPrivateKey | b64enc }}
19+
GPG_PASSPHRASE: {{ .Values.commitSigning.passphrase | b64enc }}
20+
GIT_COMMITER_NAME: {{ .Values.commitSigning.name | b64enc }}
21+
GIT_COMMITER_EMAIL: {{ .Values.commitSigning.email | b64enc }}
22+
{{- end }}

snyk-universal-broker/templates/statefulset.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ spec:
9494
- secretRef:
9595
name: {{ include "snyk-broker.credentialReferencesSecretName" . }}
9696
{{- end }}
97+
{{- if .Values.commitSigning.enabled }}
98+
- secretRef:
99+
name: {{ include "snyk-broker.commitSigningSecretName" . }}
100+
{{- end }}
97101
volumeMounts:
98102
{{- if or .Values.caCert .Values.caCertSecret.name }}
99103
- name: {{ .Release.Name }}-cacert-volume
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/helm-unittest/helm-unittest/main/schema/helm-testsuite.json
2+
suite: Commit Signing
3+
templates:
4+
- statefulset.yaml
5+
- commit-signing-secret.yaml
6+
values:
7+
- ../values.yaml
8+
- fixtures/default_values.yaml
9+
10+
tests:
11+
- it: enables commit signing with inline private key
12+
set:
13+
commitSigning:
14+
enabled: true
15+
name: "Bot"
16+
17+
passphrase: "fake"
18+
gpgPrivateKey: "-----BEGIN GPG PRIVATE KEY BLOCK-----\nFAKE\n-----END GPG PRIVATE KEY BLOCK-----"
19+
asserts:
20+
- contains:
21+
path: spec.template.spec.containers[0].envFrom
22+
content:
23+
secretRef:
24+
name: RELEASE-NAME-commit-signing-secret
25+
template: statefulset.yaml
26+
- equal:
27+
path: data.GPG_PRIVATE_KEY
28+
value: LS0tLS1CRUdJTiBHUEcgUFJJVkFURSBLRVkgQkxPQ0stLS0tLQpGQUtFCi0tLS0tRU5EIEdQRyBQUklWQVRFIEtFWSBCTE9DSy0tLS0t
29+
template: commit-signing-secret.yaml
30+
- equal:
31+
path: data.GPG_PASSPHRASE
32+
value: ZmFrZQ==
33+
template: commit-signing-secret.yaml
34+
- equal:
35+
path: data.GIT_COMMITER_NAME
36+
value: Qm90
37+
template: commit-signing-secret.yaml
38+
- equal:
39+
path: data.GIT_COMMITER_EMAIL
40+
value: Ym90QGNvcnAuaW8=
41+
template: commit-signing-secret.yaml
42+
43+
- it: enables commit signing with multiline private key
44+
set:
45+
commitSigning:
46+
enabled: true
47+
name: "Bot"
48+
49+
passphrase: "fake"
50+
gpgPrivateKey: |-
51+
-----BEGIN GPG PRIVATE KEY BLOCK-----
52+
FAKE
53+
-----END GPG PRIVATE KEY BLOCK-----
54+
55+
asserts:
56+
- contains:
57+
path: spec.template.spec.containers[0].envFrom
58+
content:
59+
secretRef:
60+
name: RELEASE-NAME-commit-signing-secret
61+
template: statefulset.yaml
62+
- equal:
63+
path: data.GPG_PRIVATE_KEY
64+
value: LS0tLS1CRUdJTiBHUEcgUFJJVkFURSBLRVkgQkxPQ0stLS0tLQpGQUtFCi0tLS0tRU5EIEdQRyBQUklWQVRFIEtFWSBCTE9DSy0tLS0t
65+
template: commit-signing-secret.yaml
66+
- equal:
67+
path: data.GPG_PASSPHRASE
68+
value: ZmFrZQ==
69+
template: commit-signing-secret.yaml
70+
- equal:
71+
path: data.GIT_COMMITER_NAME
72+
value: Qm90
73+
template: commit-signing-secret.yaml
74+
- equal:
75+
path: data.GIT_COMMITER_EMAIL
76+
value: Ym90QGNvcnAuaW8=
77+
template: commit-signing-secret.yaml
78+
79+
- it: fails if one of the commit signing values is missing and no external secret is specified
80+
set:
81+
commitSigning:
82+
enabled: true
83+
name: "Bot"
84+
85+
gpgPrivateKey: "-----BEGIN GPG PRIVATE KEY BLOCK-----\nFAKE\n-----END GPG PRIVATE KEY BLOCK-----"
86+
asserts:
87+
- failedTemplate:
88+
errorMessage: "Missing value(s) under .Values.commitSigning for: passphrase"
89+
template: commit-signing-secret.yaml
90+
91+
- it: uses an external secret if specified
92+
set:
93+
commitSigning:
94+
enabled: true
95+
commitSigningSecret:
96+
name: "my-commit-signing-secret"
97+
asserts:
98+
- contains:
99+
path: spec.template.spec.containers[0].envFrom
100+
content:
101+
secretRef:
102+
name: my-commit-signing-secret
103+
template: statefulset.yaml
104+
105+
- it: uses an external secret if specified, ignoring any values set under commitSigning
106+
set:
107+
commitSigning:
108+
enabled: true
109+
name: "Bot"
110+
111+
commitSigningSecret:
112+
name: "my-commit-signing-secret"
113+
asserts:
114+
- contains:
115+
path: spec.template.spec.containers[0].envFrom
116+
content:
117+
secretRef:
118+
name: my-commit-signing-secret
119+
template: statefulset.yaml

snyk-universal-broker/values.schema.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,43 @@
294294
}
295295
}
296296
},
297+
"commitSigning": {
298+
"type": "object",
299+
"properties": {
300+
"enabled": {
301+
"type": "boolean"
302+
},
303+
"name": {
304+
"type": "string"
305+
},
306+
"email": {
307+
"type": "string",
308+
"oneOf": [
309+
{
310+
"maxLength": 0
311+
},
312+
{
313+
"format": "email"
314+
}
315+
]
316+
},
317+
"gpgPrivateKey": {
318+
"type": "string",
319+
"regex": "^$|^\\s*-----BEGIN PGP PRIVATE KEY BLOCK-----(?:.|\\s)*-----END PGP PRIVATE KEY BLOCK-----\\s*$"
320+
},
321+
"passphrase": {
322+
"type": "string"
323+
}
324+
}
325+
},
326+
"commitSigningSecret": {
327+
"type": "object",
328+
"properties": {
329+
"name": {
330+
"type": "string"
331+
}
332+
}
333+
},
297334
"global": {
298335
"type": "object",
299336
"additionalProperties": true

snyk-universal-broker/values.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ acceptIaC: "tf,yaml,yml,json,tpl"
6060
acceptCustomPrTemplates: true
6161
acceptLargeManifests: true
6262

63+
## @param commitSigning.enabled [default: false] Set to true to sign any commits made to GitHub or GitHub Enterprise. Requires `name`, `email`, `passphrase`, `privateKey` _or_ `commitSigningSecret`
64+
## @param commitSigning.name [string] The name to associate with any signed commits
65+
## @param commitSigning.email [string] The email to associate with any signed commits
66+
## @param commitSigning.gpgPrivateKey [string] The GPG private key to sign commits with (ASCII armored version)
67+
## @param commitSigning.passphrase [string] The passpharse for the GPG key
68+
## @param commitSigningSecret [string] An external secret containing `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL`, `GPG_PASSPHRASE` and `GPG_PRIVATE_KEY`
69+
commitSigning:
70+
enabled: false
71+
name: ""
72+
email: ""
73+
gpgPrivateKey: ""
74+
passphrase: ""
75+
76+
commitSigningSecret:
77+
name: ""
78+
6379
## @section Networking Parameters
6480

6581
## @param containerPort Port to open for HTTP in Broker

0 commit comments

Comments
 (0)