From b2e033b849797f53831e19014f042cfffbbd4a10 Mon Sep 17 00:00:00 2001 From: slimm609 Date: Thu, 18 Aug 2022 11:39:58 -0400 Subject: [PATCH 1/5] Add ability to disable opt-in - add the ability to disable opt-in support for namespace validation and enforce on across the entire cluster Signed-off-by: slimm609 --- charts/policy-controller/Chart.yaml | 2 +- charts/policy-controller/README.md | 5 ++ charts/policy-controller/README.md.gotmpl | 79 +++++++++++++++++++ .../templates/webhook/webhook_mutating.yaml | 2 + .../templates/webhook/webhook_validating.yaml | 2 + charts/policy-controller/values.schema.json | 3 + charts/policy-controller/values.yaml | 2 + 7 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 charts/policy-controller/README.md.gotmpl diff --git a/charts/policy-controller/Chart.yaml b/charts/policy-controller/Chart.yaml index 18bb9e8d..e5777c50 100644 --- a/charts/policy-controller/Chart.yaml +++ b/charts/policy-controller/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -description: The Helm chart for Policy Controller +description: The Helm chart for Policy Controller home: https://github.com/sigstore/policy-controller sources: diff --git a/charts/policy-controller/README.md b/charts/policy-controller/README.md index 81ef6858..8a34627c 100644 --- a/charts/policy-controller/README.md +++ b/charts/policy-controller/README.md @@ -30,7 +30,12 @@ The Helm chart for Policy Controller | policywebhook.extraArgs | object | `{}` | | | policywebhook.image.pullPolicy | string | `"IfNotPresent"` | | | policywebhook.image.repository | string | `"ghcr.io/sigstore/policy-controller/policy-webhook"` | | +<<<<<<< HEAD | policywebhook.image.version | string | `"sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc"` | `"v0.4.0"` | +======= +| policywebhook.image.version | string | `"sha256:2d8ec2534e903a722a89efd6fe04a52a8a420ca3f8be1703aa697bf5faf418eb"` | | +| policywebhook.namespaceOptIn | bool | `true` | | +>>>>>>> c616289 (Add ability to disable opt-in) | policywebhook.podSecurityContext.allowPrivilegeEscalation | bool | `false` | | | policywebhook.podSecurityContext.capabilities.drop[0] | string | `"all"` | | | policywebhook.podSecurityContext.enabled | bool | `true` | | diff --git a/charts/policy-controller/README.md.gotmpl b/charts/policy-controller/README.md.gotmpl new file mode 100644 index 00000000..27b24034 --- /dev/null +++ b/charts/policy-controller/README.md.gotmpl @@ -0,0 +1,79 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +## Requirements +* Kubernetes cluster with rights to install admission webhooks +* Helm + +The following table lists the configurable parameters of the policy-controller chart and their default values. + + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} + +### Deploy `policy-controller` Helm Chart + +```shell +export COSIGN_PASSWORD= +cosign generate-key-pair +``` + +The previous command generates two key files `cosign.key` and `cosign.pub`. Next, create a secret to validate the signatures: + +```shell +kubectl create namespace cosign-system + +kubectl create secret generic mysecret -n \ +cosign-system --from-file=cosign.pub=./cosign.pub +``` + +Install `policy-controller` using Helm and setting the value of the secret key reference to `mysecret` that you created above: + +```shell +helm repo add sigstore https://sigstore.github.io/helm-charts + +helm repo update + +helm install policy-controller -n cosign-system sigstore/policy-controller --devel --set cosign.secretKeyRef.name=mysecret +``` + +### Enabling Admission control + +To enable the `policy admission webhook` to check for signed images, you will need to add the following label in each namespace that you would want the webhook triggered: + +Label: `policy.sigstore.dev/include: "true"` + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + labels: + policy.sigstore.dev/include: "true" + kubernetes.io/metadata.name: my-namespace + name: my-namespace +spec: + finalizers: + - kubernetes +``` + +### Testing the webhook + +1. Using Unsigned Images: +Creating a deployment referencing images that are not signed will yield the following error and no resources will be created: + + ```shell + kubectl apply -f my-deployment.yaml + Error from server (BadRequest): error when creating "my-deployment.yaml": admission webhook "policy.sigstore.dev" denied the request: validation failed: invalid image signature: spec.template.spec.containers[0].image + ``` + +2. Using Signed Images: Assuming a signed `nginx` image with a tag `signed` exists on a registry, the resource will be successfully created. + + ```shell + kubectl run pod1-signed --image=< REGISTRY_USER >/nginx:signed -n testns + pod/pod1-signed created + ``` + +{{ template "helm-docs.versionFooter" . }} \ No newline at end of file diff --git a/charts/policy-controller/templates/webhook/webhook_mutating.yaml b/charts/policy-controller/templates/webhook/webhook_mutating.yaml index 4eea2686..0a50acef 100644 --- a/charts/policy-controller/templates/webhook/webhook_mutating.yaml +++ b/charts/policy-controller/templates/webhook/webhook_mutating.yaml @@ -4,12 +4,14 @@ metadata: name: {{ required "A valid cosign.webhookName is required" .Values.cosign.webhookName }} webhooks: - name: {{ required "A valid cosign.webhookName is required" .Values.cosign.webhookName }} + {{- if .Values.policywebhook.namespaceOptIn }} namespaceSelector: # The webhook should only apply to things that opt-in matchExpressions: - key: policy.sigstore.dev/include operator: In values: ["true"] + {{- end }} admissionReviewVersions: [v1] clientConfig: service: diff --git a/charts/policy-controller/templates/webhook/webhook_validating.yaml b/charts/policy-controller/templates/webhook/webhook_validating.yaml index 17c3a758..a8811229 100644 --- a/charts/policy-controller/templates/webhook/webhook_validating.yaml +++ b/charts/policy-controller/templates/webhook/webhook_validating.yaml @@ -4,12 +4,14 @@ metadata: name: {{ required "A valid cosign.webhookName is required" .Values.cosign.webhookName }} webhooks: - name: {{ required "A valid cosign.webhookName is required" .Values.cosign.webhookName }} + {{- if .Values.policywebhook.namespaceOptIn }} namespaceSelector: # The webhook should only apply to things that opt-in matchExpressions: - key: policy.sigstore.dev/include operator: In values: ["true"] + {{- end }} admissionReviewVersions: [v1] clientConfig: service: diff --git a/charts/policy-controller/values.schema.json b/charts/policy-controller/values.schema.json index 246e63c5..2234f474 100644 --- a/charts/policy-controller/values.schema.json +++ b/charts/policy-controller/values.schema.json @@ -136,6 +136,9 @@ } } }, + "namespaceOptIn": { + "type": "boolean" + }, "webhookNames": { "type": "object", "properties": { diff --git a/charts/policy-controller/values.yaml b/charts/policy-controller/values.yaml index 878782d3..f7edadc1 100644 --- a/charts/policy-controller/values.yaml +++ b/charts/policy-controller/values.yaml @@ -38,6 +38,8 @@ policywebhook: annotations: {} type: ClusterIP port: 443 + # opt-in to validation with namespace annotation + namespaceOptIn: true webhookNames: defaulting: "defaulting.clusterimagepolicy.sigstore.dev" validating: "validating.clusterimagepolicy.sigstore.dev" From 563d5b63bff0bc53d7b954e79ff20051bbff68a6 Mon Sep 17 00:00:00 2001 From: slimm609 Date: Fri, 19 Aug 2022 07:14:45 -0400 Subject: [PATCH 2/5] fix new line Signed-off-by: slimm609 --- charts/policy-controller/README.md.gotmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/policy-controller/README.md.gotmpl b/charts/policy-controller/README.md.gotmpl index 27b24034..fde123d9 100644 --- a/charts/policy-controller/README.md.gotmpl +++ b/charts/policy-controller/README.md.gotmpl @@ -76,4 +76,4 @@ Creating a deployment referencing images that are not signed will yield the foll pod/pod1-signed created ``` -{{ template "helm-docs.versionFooter" . }} \ No newline at end of file +{{ template "helm-docs.versionFooter" . }} From 13d51cfa7caa7201deceddb0b07cc9a660e98861 Mon Sep 17 00:00:00 2001 From: slimm609 Date: Sun, 23 Oct 2022 14:28:07 -0400 Subject: [PATCH 3/5] rebase and update gotemplate for readme Signed-off-by: slimm609 --- charts/policy-controller/README.md | 14 +++-- charts/policy-controller/README.md.gotmpl | 64 ++++++++++++++++++----- 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/charts/policy-controller/README.md b/charts/policy-controller/README.md index 8a34627c..8d8ec070 100644 --- a/charts/policy-controller/README.md +++ b/charts/policy-controller/README.md @@ -2,7 +2,7 @@ ![Version: 0.3.1](https://img.shields.io/badge/Version-0.3.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.4.0](https://img.shields.io/badge/AppVersion-0.4.0-informational?style=flat-square) -The Helm chart for Policy Controller +The Helm chart for Policy Controller **Homepage:** @@ -30,12 +30,8 @@ The Helm chart for Policy Controller | policywebhook.extraArgs | object | `{}` | | | policywebhook.image.pullPolicy | string | `"IfNotPresent"` | | | policywebhook.image.repository | string | `"ghcr.io/sigstore/policy-controller/policy-webhook"` | | -<<<<<<< HEAD -| policywebhook.image.version | string | `"sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc"` | `"v0.4.0"` | -======= -| policywebhook.image.version | string | `"sha256:2d8ec2534e903a722a89efd6fe04a52a8a420ca3f8be1703aa697bf5faf418eb"` | | +| policywebhook.image.version | string | `"sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc"` | | | policywebhook.namespaceOptIn | bool | `true` | | ->>>>>>> c616289 (Add ability to disable opt-in) | policywebhook.podSecurityContext.allowPrivilegeEscalation | bool | `false` | | | policywebhook.podSecurityContext.capabilities.drop[0] | string | `"all"` | | | policywebhook.podSecurityContext.enabled | bool | `true` | | @@ -59,7 +55,7 @@ The Helm chart for Policy Controller | webhook.extraArgs | object | `{}` | | | webhook.image.pullPolicy | string | `"IfNotPresent"` | | | webhook.image.repository | string | `"ghcr.io/sigstore/policy-controller/policy-controller"` | | -| webhook.image.version | string | `"sha256:2b1c017535f6a0f672ec38279f3792ca1181555342a2deae53605e202afb9764"` | `"v0.4.0"` | +| webhook.image.version | string | `"sha256:2b1c017535f6a0f672ec38279f3792ca1181555342a2deae53605e202afb9764"` | | | webhook.name | string | `"webhook"` | | | webhook.podSecurityContext.allowPrivilegeEscalation | bool | `false` | | | webhook.podSecurityContext.capabilities.drop[0] | string | `"all"` | | @@ -164,7 +160,9 @@ Creating a deployment referencing images that are not signed will yield the foll pod/pod1-signed created ``` - ## More info You can find more information about the policy-controller in [here](https://docs.sigstore.dev/policy-controller/overview/). + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) diff --git a/charts/policy-controller/README.md.gotmpl b/charts/policy-controller/README.md.gotmpl index fde123d9..29a21d7f 100644 --- a/charts/policy-controller/README.md.gotmpl +++ b/charts/policy-controller/README.md.gotmpl @@ -1,13 +1,22 @@ {{ template "chart.header" . }} -{{ template "chart.description" . }} {{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} -## Requirements -* Kubernetes cluster with rights to install admission webhooks -* Helm +{{ template "chart.description" . }} + +**Homepage:** + -The following table lists the configurable parameters of the policy-controller chart and their default values. +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| dlorenc | | | +| hectorj2f | | | + +## Source Code + +* {{ template "chart.requirementsSection" . }} @@ -16,28 +25,52 @@ The following table lists the configurable parameters of the policy-controller c ### Deploy `policy-controller` Helm Chart +Install `policy-controller` using Helm: + +```shell +helm repo add sigstore https://sigstore.github.io/helm-charts + +helm repo update + +kubectl create namespace cosign-system + +helm install policy-controller -n cosign-system sigstore/policy-controller --devel +``` + +The `policy-controller` enforce images matching the defined list of `ClusterImagePolicy` for the labeled namespaces. + +Note that, by default, the `policy-controller` offers a configurable behavior defining whether to allow, deny or warn whenever an image does not match a policy in a specific namespace. This behavior can be configured using the `config-policy-controller` ConfigMap created under the release namespace, and by adding an entry with the property `no-match-policy` and its value `warn|allow|deny`. +By default, any image that does not match a policy is rejected whenever `no-match-policy` is not configured in the ConfigMap. + +As supported in previous versions, you could create your own key pair: + ```shell export COSIGN_PASSWORD= cosign generate-key-pair ``` -The previous command generates two key files `cosign.key` and `cosign.pub`. Next, create a secret to validate the signatures: +This command generates two key files `cosign.key` and `cosign.pub`. Next, create a secret to validate the signatures: ```shell -kubectl create namespace cosign-system - kubectl create secret generic mysecret -n \ cosign-system --from-file=cosign.pub=./cosign.pub ``` -Install `policy-controller` using Helm and setting the value of the secret key reference to `mysecret` that you created above: +**IMPORTANT:** The `cosign.secretKeyRef` flag is not supported anymore. Finally, you could reuse your secret `mysecret` by creating a `ClusterImagePolicy` that sets it as listed authorities, as shown below. -```shell -helm repo add sigstore https://sigstore.github.io/helm-charts - -helm repo update +```yaml +apiVersion: policy.sigstore.dev/v1alpha1 +kind: ClusterImagePolicy +metadata: + name: cip-key-secret +spec: + images: + - glob: "**your-desired-value**" + authorities: + - key: + secretRef: + name: mysecret -helm install policy-controller -n cosign-system sigstore/policy-controller --devel --set cosign.secretKeyRef.name=mysecret ``` ### Enabling Admission control @@ -76,4 +109,7 @@ Creating a deployment referencing images that are not signed will yield the foll pod/pod1-signed created ``` +## More info + +You can find more information about the policy-controller in [here](https://docs.sigstore.dev/policy-controller/overview/). {{ template "helm-docs.versionFooter" . }} From 853942fcc758f35f29f7a0b0a3775a9238eee9ae Mon Sep 17 00:00:00 2001 From: slimm609 Date: Sun, 23 Oct 2022 17:51:05 -0400 Subject: [PATCH 4/5] Update values and description Signed-off-by: slimm609 --- charts/policy-controller/README.md | 4 ++-- .../policy-controller/templates/webhook/webhook_mutating.yaml | 2 +- .../templates/webhook/webhook_validating.yaml | 2 +- charts/policy-controller/values.schema.json | 2 +- charts/policy-controller/values.yaml | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/charts/policy-controller/README.md b/charts/policy-controller/README.md index 8d8ec070..9d49c577 100644 --- a/charts/policy-controller/README.md +++ b/charts/policy-controller/README.md @@ -30,8 +30,8 @@ The Helm chart for Policy Controller | policywebhook.extraArgs | object | `{}` | | | policywebhook.image.pullPolicy | string | `"IfNotPresent"` | | | policywebhook.image.repository | string | `"ghcr.io/sigstore/policy-controller/policy-webhook"` | | -| policywebhook.image.version | string | `"sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc"` | | -| policywebhook.namespaceOptIn | bool | `true` | | +| policywebhook.image.version | string | `"sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc"` | "v0.4.0" | +| policywebhook.namespaceSelectorDisabled | bool | `false` | | | policywebhook.podSecurityContext.allowPrivilegeEscalation | bool | `false` | | | policywebhook.podSecurityContext.capabilities.drop[0] | string | `"all"` | | | policywebhook.podSecurityContext.enabled | bool | `true` | | diff --git a/charts/policy-controller/templates/webhook/webhook_mutating.yaml b/charts/policy-controller/templates/webhook/webhook_mutating.yaml index 0a50acef..81e0cd9b 100644 --- a/charts/policy-controller/templates/webhook/webhook_mutating.yaml +++ b/charts/policy-controller/templates/webhook/webhook_mutating.yaml @@ -4,7 +4,7 @@ metadata: name: {{ required "A valid cosign.webhookName is required" .Values.cosign.webhookName }} webhooks: - name: {{ required "A valid cosign.webhookName is required" .Values.cosign.webhookName }} - {{- if .Values.policywebhook.namespaceOptIn }} + {{- if not .Values.policywebhook.namespaceSelectorDisabled }} namespaceSelector: # The webhook should only apply to things that opt-in matchExpressions: diff --git a/charts/policy-controller/templates/webhook/webhook_validating.yaml b/charts/policy-controller/templates/webhook/webhook_validating.yaml index a8811229..6a978314 100644 --- a/charts/policy-controller/templates/webhook/webhook_validating.yaml +++ b/charts/policy-controller/templates/webhook/webhook_validating.yaml @@ -4,7 +4,7 @@ metadata: name: {{ required "A valid cosign.webhookName is required" .Values.cosign.webhookName }} webhooks: - name: {{ required "A valid cosign.webhookName is required" .Values.cosign.webhookName }} - {{- if .Values.policywebhook.namespaceOptIn }} + {{- if not .Values.policywebhook.namespaceSelectorDisabled }} namespaceSelector: # The webhook should only apply to things that opt-in matchExpressions: diff --git a/charts/policy-controller/values.schema.json b/charts/policy-controller/values.schema.json index 2234f474..a83bb611 100644 --- a/charts/policy-controller/values.schema.json +++ b/charts/policy-controller/values.schema.json @@ -136,7 +136,7 @@ } } }, - "namespaceOptIn": { + "namespaceSelectorDisabled": { "type": "boolean" }, "webhookNames": { diff --git a/charts/policy-controller/values.yaml b/charts/policy-controller/values.yaml index f7edadc1..65475733 100644 --- a/charts/policy-controller/values.yaml +++ b/charts/policy-controller/values.yaml @@ -10,6 +10,7 @@ policywebhook: image: repository: ghcr.io/sigstore/policy-controller/policy-webhook # crane digest ghcr.io/sigstore/policy-controller/policy-webhook:v0.4.0 + # -- "v0.4.0" version: sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc pullPolicy: IfNotPresent env: {} @@ -38,8 +39,7 @@ policywebhook: annotations: {} type: ClusterIP port: 443 - # opt-in to validation with namespace annotation - namespaceOptIn: true + namespaceSelectorDisabled: false webhookNames: defaulting: "defaulting.clusterimagepolicy.sigstore.dev" validating: "validating.clusterimagepolicy.sigstore.dev" From 32b1d962547e03e41d89b932224edcf5be505e40 Mon Sep 17 00:00:00 2001 From: slimm609 Date: Sun, 23 Oct 2022 17:53:04 -0400 Subject: [PATCH 5/5] fix versions Signed-off-by: slimm609 --- charts/policy-controller/README.md | 4 ++-- charts/policy-controller/values.yaml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/charts/policy-controller/README.md b/charts/policy-controller/README.md index 9d49c577..4001726c 100644 --- a/charts/policy-controller/README.md +++ b/charts/policy-controller/README.md @@ -30,7 +30,7 @@ The Helm chart for Policy Controller | policywebhook.extraArgs | object | `{}` | | | policywebhook.image.pullPolicy | string | `"IfNotPresent"` | | | policywebhook.image.repository | string | `"ghcr.io/sigstore/policy-controller/policy-webhook"` | | -| policywebhook.image.version | string | `"sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc"` | "v0.4.0" | +| policywebhook.image.version | string | `"sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc"` | `"v0.4.0"` | | policywebhook.namespaceSelectorDisabled | bool | `false` | | | policywebhook.podSecurityContext.allowPrivilegeEscalation | bool | `false` | | | policywebhook.podSecurityContext.capabilities.drop[0] | string | `"all"` | | @@ -55,7 +55,7 @@ The Helm chart for Policy Controller | webhook.extraArgs | object | `{}` | | | webhook.image.pullPolicy | string | `"IfNotPresent"` | | | webhook.image.repository | string | `"ghcr.io/sigstore/policy-controller/policy-controller"` | | -| webhook.image.version | string | `"sha256:2b1c017535f6a0f672ec38279f3792ca1181555342a2deae53605e202afb9764"` | | +| webhook.image.version | string | `"sha256:2b1c017535f6a0f672ec38279f3792ca1181555342a2deae53605e202afb9764"` | `"v0.4.0"` | | webhook.name | string | `"webhook"` | | | webhook.podSecurityContext.allowPrivilegeEscalation | bool | `false` | | | webhook.podSecurityContext.capabilities.drop[0] | string | `"all"` | | diff --git a/charts/policy-controller/values.yaml b/charts/policy-controller/values.yaml index 65475733..f57d93b6 100644 --- a/charts/policy-controller/values.yaml +++ b/charts/policy-controller/values.yaml @@ -10,7 +10,7 @@ policywebhook: image: repository: ghcr.io/sigstore/policy-controller/policy-webhook # crane digest ghcr.io/sigstore/policy-controller/policy-webhook:v0.4.0 - # -- "v0.4.0" + # -- `"v0.4.0"` version: sha256:03f6b9807103c988439741fdc2ec4410a85c13ba62fbad58448a070ac07bb5bc pullPolicy: IfNotPresent env: {} @@ -50,6 +50,7 @@ webhook: image: repository: ghcr.io/sigstore/policy-controller/policy-controller # crane digest ghcr.io/sigstore/policy-controller/policy-controller:v0.4.0 + # -- `"v0.4.0"` version: sha256:2b1c017535f6a0f672ec38279f3792ca1181555342a2deae53605e202afb9764 pullPolicy: IfNotPresent env: {}