Skip to content

Commit

Permalink
fix: enable commit signing (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
soniqua authored Nov 12, 2024
1 parent fe4b2b4 commit 2476d05
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 17 deletions.
6 changes: 5 additions & 1 deletion .gitleaks.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@
useDefault = true

[allowList]
paths = ['''snyk-universal-broker/tests''']
paths = [
'''snyk-universal-broker/tests''',
'''snyk-universal-broker/values.schema.json''',
'''README.md'''
]
90 changes: 74 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,58 @@ image:
- name: containers-company-secret
```

### Commit Signing

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.

This feature requires a GitHub Account that has a GPG key configured for commit signing.

#### Via Helm

Provide the GPG key (exported as an ASCII armored version), the passphrase, and associated email/user:

```yaml
commitSigning:
name: "Account Name"
email: "email@company.tld"
passphrase: "passphrase"
gpgPrivateKey: -----BEGIN PGP PRIVATE KEY BLOCK-----\n....\n-----END PGP PRIVATE KEY BLOCK-----
```

The Universal Broker Helm Chart creates this secret for you.

#### Via External Secret

First create or otherwise ensure the secret exists:

```yaml
kind: Secret
apiVersion: v1
metadata:
name: gpg-signing-key
data:
GPG_PRIVATE_KEY: "-----BEGIN PRIVATE KEY BLOCK-----..."
GPG_PASSPRHASE: "passphrase"
GIT_COMMITTER_EMAIL: "user@comapny.io"
GIT_COMMITTER_NAME: "User Name"
```

The keys **must** match the example above.

Then set values within `.Values.commitSigningSecret` to reference this external Secret:
```yaml
commitSigning:
enabled: true
commitSigningSecret:
name: gpg-signing-key
```

Commit signing is enabled if the following entry appears in Universal Broker logs at startup:

```
loading commit signing rules (enabled=true, rulesCount=5)
```

## Parameters

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

| Name | Description | Value |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| `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. | `""` |
| `region` | Optionally specify a Snyk Region - e.g. "eu" for "SNYK-EU-01". Defaults to "SNYK-US-01", app.snyk.io | `""` |
| `preflightChecks.enabled` | broker client preflight checks | `true` |
| `deploymentId` | Obtained by installing the Broker App | `""` |
| `clientId` | Obtained by installing the Broker App | `""` |
| `clientSecret` | Obtained by installing the Broker App | `""` |
| `platformAuthSecret.name` | Optionally provide an external secret containing three keys: `DEPLOYMENT_ID`, `CLIENT_ID` and `CLIENT_SECRET` | `""` |
| `credentialReferences` | Credential References to pass to Broker | `{}` |
| `credentialReferencesSecret.name` | Optionally provide a pre-existing secret with SCM credential reference data | `""` |
| `acceptCode` | Set to false to block Broker rules relating to Snyk Code analysis | `true` |
| `acceptAppRisk` | Set to false to block Broker rules relating to AppRisk | `true` |
| `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 | `""` |
| `acceptCustomPrTemplates` | Set to false to block Broker rules relating to Snyk Custom PR Templates | `true` |
| `acceptLargeManifests` | Set to false to block Broker rules relating to fetching of large files from GitHub/GitHub Enterprise | `true` |
| Name | Description | Value |
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `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. | `""` |
| `region` | Optionally specify a Snyk Region - e.g. "eu" for "SNYK-EU-01". Defaults to "SNYK-US-01", app.snyk.io | `""` |
| `preflightChecks.enabled` | broker client preflight checks | `true` |
| `deploymentId` | Obtained by installing the Broker App | `""` |
| `clientId` | Obtained by installing the Broker App | `""` |
| `clientSecret` | Obtained by installing the Broker App | `""` |
| `platformAuthSecret.name` | Optionally provide an external secret containing three keys: `DEPLOYMENT_ID`, `CLIENT_ID` and `CLIENT_SECRET` | `""` |
| `credentialReferences` | Credential References to pass to Broker | `{}` |
| `credentialReferencesSecret.name` | Optionally provide a pre-existing secret with SCM credential reference data | `""` |
| `acceptCode` | Set to false to block Broker rules relating to Snyk Code analysis | `true` |
| `acceptAppRisk` | Set to false to block Broker rules relating to AppRisk | `true` |
| `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 | `""` |
| `acceptCustomPrTemplates` | Set to false to block Broker rules relating to Snyk Custom PR Templates | `true` |
| `acceptLargeManifests` | Set to false to block Broker rules relating to fetching of large files from GitHub/GitHub Enterprise | `true` |
| `commitSigning.enabled` | Set to true to sign any commits made to GitHub or GitHub Enterprise. Requires `name`, `email`, `passphrase`, `privateKey` _or_ `commitSigningSecret` | `false` |
| `commitSigning.name` | The name to associate with any signed commits | `""` |
| `commitSigning.email` | The email to associate with any signed commits | `""` |
| `commitSigning.gpgPrivateKey` | The GPG private key to sign commits with (ASCII armored version) | `""` |
| `commitSigning.passphrase` | The passpharse for the GPG key | `""` |
| `commitSigningSecret` | An external secret containing `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL`, `GPG_PASSPHRASE` and `GPG_PRIVATE_KEY` | `""` |

### Networking Parameters

Expand Down
7 changes: 7 additions & 0 deletions snyk-universal-broker/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ Each credential must be a valid env var, with associated string value
{{- end }}

{{/*
Create a name for the Commit Signing secret, using a provided override if present
*/}}
{{- define "snyk-broker.commitSigningSecretName" -}}
{{- .Values.commitSigningSecret.name | default ( include "snyk-broker.genericSecretName" (dict "Context" . "secretName" "commit-signing-secret" ) ) -}}
{{- end }}

{{/*}}
Snyk Broker ACCEPT_ vars
*/}}
{{- define "snyk-broker.accepts" -}}
Expand Down
22 changes: 22 additions & 0 deletions snyk-universal-broker/templates/commit-signing-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{- if and .Values.commitSigning.enabled ( not .Values.commitSigningSecret.name ) }}
{{- $unsetKeys:= list -}}
{{- range ( unset .Values.commitSigning "enabled" | keys ) -}}
{{- if not (get $.Values.commitSigning . ) }}
{{- $unsetKeys = append $unsetKeys . -}}
{{- end }}
{{- end }}
{{- if gt (len $unsetKeys) 0 -}}
{{- fail (printf "Missing value(s) under .Values.commitSigning for: %s" (join "," $unsetKeys) ) }}
{{- end }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "snyk-broker.commitSigningSecretName" . }}
namespace: {{ .Release.Namespace }}
labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
data:
GPG_PRIVATE_KEY: {{ .Values.commitSigning.gpgPrivateKey | b64enc }}
GPG_PASSPHRASE: {{ .Values.commitSigning.passphrase | b64enc }}
GIT_COMMITER_NAME: {{ .Values.commitSigning.name | b64enc }}
GIT_COMMITER_EMAIL: {{ .Values.commitSigning.email | b64enc }}
{{- end }}
4 changes: 4 additions & 0 deletions snyk-universal-broker/templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ spec:
- secretRef:
name: {{ include "snyk-broker.credentialReferencesSecretName" . }}
{{- end }}
{{- if .Values.commitSigning.enabled }}
- secretRef:
name: {{ include "snyk-broker.commitSigningSecretName" . }}
{{- end }}
volumeMounts:
{{- if or .Values.caCert .Values.caCertSecret.name }}
- name: {{ .Release.Name }}-cacert-volume
Expand Down
119 changes: 119 additions & 0 deletions snyk-universal-broker/tests/commit_signing_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/helm-unittest/helm-unittest/main/schema/helm-testsuite.json
suite: Commit Signing
templates:
- statefulset.yaml
- commit-signing-secret.yaml
values:
- ../values.yaml
- fixtures/default_values.yaml

tests:
- it: enables commit signing with inline private key
set:
commitSigning:
enabled: true
name: "Bot"
email: "bot@corp.io"
passphrase: "fake"
gpgPrivateKey: "-----BEGIN GPG PRIVATE KEY BLOCK-----\nFAKE\n-----END GPG PRIVATE KEY BLOCK-----"
asserts:
- contains:
path: spec.template.spec.containers[0].envFrom
content:
secretRef:
name: RELEASE-NAME-commit-signing-secret
template: statefulset.yaml
- equal:
path: data.GPG_PRIVATE_KEY
value: LS0tLS1CRUdJTiBHUEcgUFJJVkFURSBLRVkgQkxPQ0stLS0tLQpGQUtFCi0tLS0tRU5EIEdQRyBQUklWQVRFIEtFWSBCTE9DSy0tLS0t
template: commit-signing-secret.yaml
- equal:
path: data.GPG_PASSPHRASE
value: ZmFrZQ==
template: commit-signing-secret.yaml
- equal:
path: data.GIT_COMMITER_NAME
value: Qm90
template: commit-signing-secret.yaml
- equal:
path: data.GIT_COMMITER_EMAIL
value: Ym90QGNvcnAuaW8=
template: commit-signing-secret.yaml

- it: enables commit signing with multiline private key
set:
commitSigning:
enabled: true
name: "Bot"
email: "bot@corp.io"
passphrase: "fake"
gpgPrivateKey: |-
-----BEGIN GPG PRIVATE KEY BLOCK-----
FAKE
-----END GPG PRIVATE KEY BLOCK-----
asserts:
- contains:
path: spec.template.spec.containers[0].envFrom
content:
secretRef:
name: RELEASE-NAME-commit-signing-secret
template: statefulset.yaml
- equal:
path: data.GPG_PRIVATE_KEY
value: LS0tLS1CRUdJTiBHUEcgUFJJVkFURSBLRVkgQkxPQ0stLS0tLQpGQUtFCi0tLS0tRU5EIEdQRyBQUklWQVRFIEtFWSBCTE9DSy0tLS0t
template: commit-signing-secret.yaml
- equal:
path: data.GPG_PASSPHRASE
value: ZmFrZQ==
template: commit-signing-secret.yaml
- equal:
path: data.GIT_COMMITER_NAME
value: Qm90
template: commit-signing-secret.yaml
- equal:
path: data.GIT_COMMITER_EMAIL
value: Ym90QGNvcnAuaW8=
template: commit-signing-secret.yaml

- it: fails if one of the commit signing values is missing and no external secret is specified
set:
commitSigning:
enabled: true
name: "Bot"
email: "bot@corp.io"
gpgPrivateKey: "-----BEGIN GPG PRIVATE KEY BLOCK-----\nFAKE\n-----END GPG PRIVATE KEY BLOCK-----"
asserts:
- failedTemplate:
errorMessage: "Missing value(s) under .Values.commitSigning for: passphrase"
template: commit-signing-secret.yaml

- it: uses an external secret if specified
set:
commitSigning:
enabled: true
commitSigningSecret:
name: "my-commit-signing-secret"
asserts:
- contains:
path: spec.template.spec.containers[0].envFrom
content:
secretRef:
name: my-commit-signing-secret
template: statefulset.yaml

- it: uses an external secret if specified, ignoring any values set under commitSigning
set:
commitSigning:
enabled: true
name: "Bot"
email: "bot@corp.io"
commitSigningSecret:
name: "my-commit-signing-secret"
asserts:
- contains:
path: spec.template.spec.containers[0].envFrom
content:
secretRef:
name: my-commit-signing-secret
template: statefulset.yaml
37 changes: 37 additions & 0 deletions snyk-universal-broker/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,43 @@
}
}
},
"commitSigning": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"name": {
"type": "string"
},
"email": {
"type": "string",
"oneOf": [
{
"maxLength": 0
},
{
"format": "email"
}
]
},
"gpgPrivateKey": {
"type": "string",
"regex": "^$|^\\s*-----BEGIN PGP PRIVATE KEY BLOCK-----(?:.|\\s)*-----END PGP PRIVATE KEY BLOCK-----\\s*$"
},
"passphrase": {
"type": "string"
}
}
},
"commitSigningSecret": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
},
"global": {
"type": "object",
"additionalProperties": true
Expand Down
16 changes: 16 additions & 0 deletions snyk-universal-broker/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ acceptIaC: "tf,yaml,yml,json,tpl"
acceptCustomPrTemplates: true
acceptLargeManifests: true

## @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`
## @param commitSigning.name [string] The name to associate with any signed commits
## @param commitSigning.email [string] The email to associate with any signed commits
## @param commitSigning.gpgPrivateKey [string] The GPG private key to sign commits with (ASCII armored version)
## @param commitSigning.passphrase [string] The passpharse for the GPG key
## @param commitSigningSecret [string] An external secret containing `GIT_COMMITTER_NAME`, `GIT_COMMITTER_EMAIL`, `GPG_PASSPHRASE` and `GPG_PRIVATE_KEY`
commitSigning:
enabled: false
name: ""
email: ""
gpgPrivateKey: ""
passphrase: ""

commitSigningSecret:
name: ""

## @section Networking Parameters

## @param containerPort Port to open for HTTP in Broker
Expand Down

0 comments on commit 2476d05

Please sign in to comment.