From 5d7b6d1a74ee143cf1b62f0e9d8cf9b4584b2d0c Mon Sep 17 00:00:00 2001 From: sivasathyaseeelan Date: Tue, 2 Jul 2024 12:33:47 +0530 Subject: [PATCH 01/59] added documentation for PR #9960 Signed-off-by: sivasathyaseeelan --- .../verify-images/notary/_index.md | 209 ++++++++++++++++-- 1 file changed, 191 insertions(+), 18 deletions(-) diff --git a/content/en/docs/writing-policies/verify-images/notary/_index.md b/content/en/docs/writing-policies/verify-images/notary/_index.md index ce1db8b8a..2c641b1c0 100644 --- a/content/en/docs/writing-policies/verify-images/notary/_index.md +++ b/content/en/docs/writing-policies/verify-images/notary/_index.md @@ -40,18 +40,32 @@ ghcr.io/kyverno/test-verify-image@sha256:b31bfb4d0213f254d361e0079deaaebefa4f82b You can also use an OCI registry client to discover signatures and attestations for an image. ```sh -oras discover ghcr.io/kyverno/test-verify-image:signed -o tree -ghcr.io/kyverno/test-verify-image:signed +oras discover -o tree ghcr.io/kyverno/test-verify-image:signed +ghcr.io/kyverno/test-verify-image@sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105 ├── application/vnd.cncf.notary.signature -│   └── sha256:7f870420d92765b42cec0f71ee8e25bf39b692f64d95d6f6607e9e6e54300265 +│ ├── sha256:7f870420d92765b42cec0f71ee8e25bf39b692f64d95d6f6607e9e6e54300265 +│ └── sha256:f7d941ed9e93a1ff1d5dee3b091144a87dae1d73481d5be93aa65258a110c689 ├── vulnerability-scan -│   └── sha256:f89cb7a0748c63a674d157ca84d725ff3ac09cc2d4aee9d0ec4315e0fe92a5fd -│   └── application/vnd.cncf.notary.signature -│   └── sha256:ec45844601244aa08ac750f44def3fd48ddacb736d26b83dde9f5d8ac646c2f3 -└── sbom/cyclone-dx - └── sha256:8cad9bd6de426683424a204697dd48b55abcd6bb6b4930ad9d8ade99ae165414 +│ └── sha256:f89cb7a0748c63a674d157ca84d725ff3ac09cc2d4aee9d0ec4315e0fe92a5fd +│ └── application/vnd.cncf.notary.signature +│ └── sha256:ec45844601244aa08ac750f44def3fd48ddacb736d26b83dde9f5d8ac646c2f3 +├── sbom/cyclone-dx +│ └── sha256:8cad9bd6de426683424a204697dd48b55abcd6bb6b4930ad9d8ade99ae165414 +│ └── application/vnd.cncf.notary.signature +│ └── sha256:61f3e42f017b72f4277c78a7a42ff2ad8f872811324cd984830dfaeb4030c322 +├── application/vnd.cyclonedx+json +│ └── sha256:aa886b475b431a37baa0e803765a9212f0accece0b82a131ebafd43ea78fa1f8 +│ └── application/vnd.cncf.notary.signature +│ ├── sha256:00c5f96577878d79b545d424884886c37e270fac5996f17330d77a01a96801eb +│ └── sha256:f3dc4687f5654ea8c2bc8da4e831d22a067298e8651fb59d55565dee58e94e2d +├── cyclonedx/vex +│ └── sha256:c058f08c9103bb676fcd0b98e41face2436e0a16f3d1c8255797b916ab5daa8a +│ └── application/vnd.cncf.notary.signature +│ └── sha256:79edc8936a4fb8758b9cb2b8603a1c7903f53261c425efb0cd85b09715eb6dfa +└── trivy/scan + └── sha256:a75ac963617462fdfe6a3847d17e5519465dfb069f92870050cce5269e7cbd7b └── application/vnd.cncf.notary.signature - └── sha256:61f3e42f017b72f4277c78a7a42ff2ad8f872811324cd984830dfaeb4030c322 + └── sha256:d1e2b2ba837c164c282cf389594791a190df872cf7712b4d91aa10a3520a8460 ``` ## Verifying Image Signatures @@ -145,15 +159,29 @@ Consider the following image: `ghcr.io/kyverno/test-verify-image:signed` ``` ghcr.io/kyverno/test-verify-image:signed ├── application/vnd.cncf.notary.signature -│ └── sha256:7f870420d92765b42cec0f71ee8e25bf39b692f64d95d6f6607e9e6e54300265 +│ ├── sha256:7f870420d92765b42cec0f71ee8e25bf39b692f64d95d6f6607e9e6e54300265 +│ └── sha256:f7d941ed9e93a1ff1d5dee3b091144a87dae1d73481d5be93aa65258a110c689 ├── vulnerability-scan -│ └── sha256:f89cb7a0748c63a674d157ca84d725ff3ac09cc2d4aee9d0ec4315e0fe92a5fd -│ └── application/vnd.cncf.notary.signature -│ └── sha256:ec45844601244aa08ac750f44def3fd48ddacb736d26b83dde9f5d8ac646c2f3 -└── sbom/cyclone-dx - └── sha256:8cad9bd6de426683424a204697dd48b55abcd6bb6b4930ad9d8ade99ae165414 - └── application/vnd.cncf.notary.signature - └── sha256:61f3e42f017b72f4277c78a7a42ff2ad8f872811324cd984830dfaeb4030c322 +│ └── sha256:f89cb7a0748c63a674d157ca84d725ff3ac09cc2d4aee9d0ec4315e0fe92a5fd +│ └── application/vnd.cncf.notary.signature +│ └── sha256:ec45844601244aa08ac750f44def3fd48ddacb736d26b83dde9f5d8ac646c2f3 +├── sbom/cyclone-dx +│ └── sha256:8cad9bd6de426683424a204697dd48b55abcd6bb6b4930ad9d8ade99ae165414 +│ └── application/vnd.cncf.notary.signature +│ └── sha256:61f3e42f017b72f4277c78a7a42ff2ad8f872811324cd984830dfaeb4030c322 +├── application/vnd.cyclonedx+json +│ └── sha256:aa886b475b431a37baa0e803765a9212f0accece0b82a131ebafd43ea78fa1f8 +│ └── application/vnd.cncf.notary.signature +│ ├── sha256:00c5f96577878d79b545d424884886c37e270fac5996f17330d77a01a96801eb +│ └── sha256:f3dc4687f5654ea8c2bc8da4e831d22a067298e8651fb59d55565dee58e94e2d +├── cyclonedx/vex +│ └── sha256:c058f08c9103bb676fcd0b98e41face2436e0a16f3d1c8255797b916ab5daa8a +│ └── application/vnd.cncf.notary.signature +│ └── sha256:79edc8936a4fb8758b9cb2b8603a1c7903f53261c425efb0cd85b09715eb6dfa +└── trivy/scan + └── sha256:a75ac963617462fdfe6a3847d17e5519465dfb069f92870050cce5269e7cbd7b + └── application/vnd.cncf.notary.signature + └── sha256:d1e2b2ba837c164c282cf389594791a190df872cf7712b4d91aa10a3520a8460 ``` This image has: @@ -161,6 +189,9 @@ This image has: 1. A notary signature. 2. A vulnerability scan report, signed using notary. 3. A CycloneDX SBOM, signed using notary. +4. A CycloneDX VEX report, signed using notary. +5. A Trivy scan report, signed using notary. + This policy checks the signature in the repo `ghcr.io/kyverno/test-verify-image` and ensures that it has been signed by verifying its signature against the provided certificates: ```yaml @@ -227,4 +258,146 @@ After this policy is applied, Kyverno will verify the signature on the sbom/cycl ```sh kubectl run test --image=ghcr.io/kyverno/test-verify-image:signed --dry-run=server pod/test created (server dry run) -``` \ No newline at end of file +``` + +## Verifying Multiple Image Attestations + +Consider the following image: `ghcr.io/kyverno/test-verify-image:signed` + +``` +ghcr.io/kyverno/test-verify-image:signed +├── application/vnd.cncf.notary.signature +│ ├── sha256:7f870420d92765b42cec0f71ee8e25bf39b692f64d95d6f6607e9e6e54300265 +│ └── sha256:f7d941ed9e93a1ff1d5dee3b091144a87dae1d73481d5be93aa65258a110c689 +├── vulnerability-scan +│ └── sha256:f89cb7a0748c63a674d157ca84d725ff3ac09cc2d4aee9d0ec4315e0fe92a5fd +│ └── application/vnd.cncf.notary.signature +│ └── sha256:ec45844601244aa08ac750f44def3fd48ddacb736d26b83dde9f5d8ac646c2f3 +├── sbom/cyclone-dx +│ └── sha256:8cad9bd6de426683424a204697dd48b55abcd6bb6b4930ad9d8ade99ae165414 +│ └── application/vnd.cncf.notary.signature +│ └── sha256:61f3e42f017b72f4277c78a7a42ff2ad8f872811324cd984830dfaeb4030c322 +├── application/vnd.cyclonedx+json +│ └── sha256:aa886b475b431a37baa0e803765a9212f0accece0b82a131ebafd43ea78fa1f8 +│ └── application/vnd.cncf.notary.signature +│ ├── sha256:00c5f96577878d79b545d424884886c37e270fac5996f17330d77a01a96801eb +│ └── sha256:f3dc4687f5654ea8c2bc8da4e831d22a067298e8651fb59d55565dee58e94e2d +├── cyclonedx/vex +│ └── sha256:c058f08c9103bb676fcd0b98e41face2436e0a16f3d1c8255797b916ab5daa8a +│ └── application/vnd.cncf.notary.signature +│ └── sha256:79edc8936a4fb8758b9cb2b8603a1c7903f53261c425efb0cd85b09715eb6dfa +└── trivy/scan + └── sha256:a75ac963617462fdfe6a3847d17e5519465dfb069f92870050cce5269e7cbd7b + └── application/vnd.cncf.notary.signature + └── sha256:d1e2b2ba837c164c282cf389594791a190df872cf7712b4d91aa10a3520a8460 +``` + +This image has: + +1. A notary signature. +2. A vulnerability scan report, signed using notary. +3. A CycloneDX SBOM, signed using notary. +4. A CycloneDX VEX report, signed using notary. +5. A Trivy scan report, signed using notary. + +This policy checks the signature in the repo `ghcr.io/kyverno/test-verify-image` and ensures that it has been signed by verifying its signature against the provided certificates: + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: check-image-attestation +spec: + validationFailureAction: Enforce + webhookTimeoutSeconds: 30 + failurePolicy: Fail + rules: + - name: verify-attestation-notary + match: + any: + - resources: + kinds: + - Pod + context: + - name: keys + configMap: + name: keys + namespace: notary-verify-attestation + verifyImages: + - type: Notary + imageReferences: + - "ghcr.io/kyverno/test-verify-image*" + attestations: + - type: trivy/vulnerability + name: trivy + attestors: + - entries: + - certificates: + cert: |- + -----BEGIN CERTIFICATE----- + MIIDmDCCAoCgAwIBAgIUCntgF4FftePAhEa6nZTsu/NMT3cwDQYJKoZIhvcNAQEL + BQAwTDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxl + MQ8wDQYDVQQKDAZOb3RhcnkxDTALBgNVBAMMBHRlc3QwHhcNMjQwNjEwMTYzMTQ2 + WhcNMzQwNjA4MTYzMTQ2WjBMMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAO + BgNVBAcMB1NlYXR0bGUxDzANBgNVBAoMBk5vdGFyeTENMAsGA1UEAwwEdGVzdDCC + ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJkEGqbILiWye6C1Jz+jwwDY + k/rovpXzxS+EQDvfj/YKvx37Kr4cjboJORu3wtzICWhPUtVWZ21ShfjerKgNq0iB + mrlF4cqz2KcOfuUT3XBglH/NwhEAqOrGPQrMsoQEFWgnilr0RTc+j4vDnkdkcTj2 + K/qPhQHRAeb97TdvFCqcZfAGqiOVUqzDGxd2INz/fJd4/nYRX3LJBn9pUGxqRwZV + ElP5B/aCBjJDdh6tAElT5aDnLGAB+3+W2YwG342ELyAl2ILpbSRUpKLNAfKEd7Nj + 1moIl4or5AIlTkgewZ/AK68HPFJEV3SwNbzkgAC+/mLVCD8tqu0o0ziyIUJtoQMC + AwEAAaNyMHAwHQYDVR0OBBYEFFTIzCppwv0vZnAVmETPm1CfMdcYMB8GA1UdIwQY + MBaAFFTIzCppwv0vZnAVmETPm1CfMdcYMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQD + AgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQB8/vfP + /TQ3X80JEZDsttdvd9NLm08bTJ/T+nh0DIiV10aHymQT9/u+iahfm1+7mj+uv8LS + Y63LepQCX5p9SoFzt513pbNYXMBbRrOKpth3DD49IPL2Gce86AFGydfrakd86CL1 + 9MhFeWhtRf0KndyUX8J2s7jbpoN8HrN4/wZygiEqbQWZG8YtIZ9EewmoVMYirQqH + EvW93NcgmjiELuhjndcT/kHjhf8fUAgSuxiPIy6ern02fJjw40KzgiKNvxMoI9su + G2zu6gXmxkw+x0SMe9kX+Rg4hCIjTUM7dc66XL5LcTp4S5YEZNVC40/FgTIZoK0e + r1dC2/Y1SmmrIoA1 + -----END CERTIFICATE----- + - type: vex/cyclone-dx + name: vex + attestors: + - entries: + - certificates: + cert: |- + -----BEGIN CERTIFICATE----- + MIIDmDCCAoCgAwIBAgIUCntgF4FftePAhEa6nZTsu/NMT3cwDQYJKoZIhvcNAQEL + BQAwTDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxl + MQ8wDQYDVQQKDAZOb3RhcnkxDTALBgNVBAMMBHRlc3QwHhcNMjQwNjEwMTYzMTQ2 + WhcNMzQwNjA4MTYzMTQ2WjBMMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExEDAO + BgNVBAcMB1NlYXR0bGUxDzANBgNVBAoMBk5vdGFyeTENMAsGA1UEAwwEdGVzdDCC + ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJkEGqbILiWye6C1Jz+jwwDY + k/rovpXzxS+EQDvfj/YKvx37Kr4cjboJORu3wtzICWhPUtVWZ21ShfjerKgNq0iB + mrlF4cqz2KcOfuUT3XBglH/NwhEAqOrGPQrMsoQEFWgnilr0RTc+j4vDnkdkcTj2 + K/qPhQHRAeb97TdvFCqcZfAGqiOVUqzDGxd2INz/fJd4/nYRX3LJBn9pUGxqRwZV + ElP5B/aCBjJDdh6tAElT5aDnLGAB+3+W2YwG342ELyAl2ILpbSRUpKLNAfKEd7Nj + 1moIl4or5AIlTkgewZ/AK68HPFJEV3SwNbzkgAC+/mLVCD8tqu0o0ziyIUJtoQMC + AwEAAaNyMHAwHQYDVR0OBBYEFFTIzCppwv0vZnAVmETPm1CfMdcYMB8GA1UdIwQY + MBaAFFTIzCppwv0vZnAVmETPm1CfMdcYMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQD + AgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQB8/vfP + /TQ3X80JEZDsttdvd9NLm08bTJ/T+nh0DIiV10aHymQT9/u+iahfm1+7mj+uv8LS + Y63LepQCX5p9SoFzt513pbNYXMBbRrOKpth3DD49IPL2Gce86AFGydfrakd86CL1 + 9MhFeWhtRf0KndyUX8J2s7jbpoN8HrN4/wZygiEqbQWZG8YtIZ9EewmoVMYirQqH + EvW93NcgmjiELuhjndcT/kHjhf8fUAgSuxiPIy6ern02fJjw40KzgiKNvxMoI9su + G2zu6gXmxkw+x0SMe9kX+Rg4hCIjTUM7dc66XL5LcTp4S5YEZNVC40/FgTIZoK0e + r1dC2/Y1SmmrIoA1 + -----END CERTIFICATE----- + validate: + deny: + conditions: + any: + - key: '{{ trivy.Vulnerabilities[*].VulnerabilityID }}' + operator: AnyNotIn + value: '{{ vex.vulnerabilities[*].id }}' + message: test1 + message: All vulnerabilities in trivy and vex should be same +``` + +After this policy is applied, Kyverno will validate deny condition which checks all the vulneribilities in trivy report are there in vex report using trivy/scan and cyclonedx/scan, then verifies the signature on both the attestation. + +```sh +kubectl run test --image=ghcr.io/kyverno/test-verify-image:signed --dry-run=server +pod/test created (server dry run) +``` From 421f979f13a01ee34a2173bfbfd9bc6c2ac054db Mon Sep 17 00:00:00 2001 From: sivasathyaseeelan Date: Wed, 3 Jul 2024 16:05:46 +0530 Subject: [PATCH 02/59] docs for issue 9723 Signed-off-by: sivasathyaseeelan --- .../writing-policies/external-data-sources.md | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/content/en/docs/writing-policies/external-data-sources.md b/content/en/docs/writing-policies/external-data-sources.md index 43a71f72c..db81b4b24 100644 --- a/content/en/docs/writing-policies/external-data-sources.md +++ b/content/en/docs/writing-policies/external-data-sources.md @@ -714,6 +714,55 @@ The data returned by GlobalContextEntries may vary depending on whether it is a GlobalContextEntries must be in a healthy state (i.e., there is a response received from the remote endpoint) in order for the policies which reference them to be considered healthy. A GlobalContextEntry which is in a `not ready` state will cause any/all referenced policies to also be in a similar state and therefore will not be processed. Creation of a policy referencing a GlobalContextEntry which either does not exist or is not ready will print a warning notifying users. {{% /alert %}} +## Default +Default is an optional arbitrary JSON object that the context may take if the apiCall returns an error. Default value can also used in case of a server error. + +For example, the policy below uses `default` values to validate: +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: default +spec: + rules: + - name: default-apicall + match: + any: + - resources: + kinds: + - Pod + operations: + - CREATE + context: + - name: testString + apiCall: + urlPath: "/api/v1/namespaces/{{ request.namespace }}/invalid" + jmesPath: metadata.name + default: default + - name: testJSON + apiCall: + urlPath: "/api/v1/namespaces/{{ request.namespace }}/invalid" + default: '{"metadata": {"name": "default"}}' + - name: testInteger + apiCall: + urlPath: "/api/v1/namespaces/{{ request.namespace }}/invalid" + jmesPath: metadata.resourceVersion + default: 1 + validate: + deny: + conditions: + all: + - key: "{{ testString }}" + operator: Equals + value: "{{ request.namespace }}" + - key: "{{ testJSON.metadata.name }}" + operator: Equals + value: "{{ request.namespace }}" + - key: "{{ testInteger }}" + operator: GreaterThan + value: 2 +``` + ## Variables from Image Registries A context can also be used to store metadata on an OCI image by using the `imageRegistry` context type. By using this external data source, a Kyverno policy can make decisions based on details of the container image that occurs as part of an incoming resource. From 66ed9c09367df0f570fc400f83c41ff70261acac Mon Sep 17 00:00:00 2001 From: shuting Date: Thu, 26 Sep 2024 19:12:43 +0800 Subject: [PATCH 03/59] feat: Add imageIndex field to imageData (#1362) Signed-off-by: ShutingZhao --- content/en/docs/writing-policies/external-data-sources.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/en/docs/writing-policies/external-data-sources.md b/content/en/docs/writing-policies/external-data-sources.md index 43a71f72c..113529d9d 100644 --- a/content/en/docs/writing-policies/external-data-sources.md +++ b/content/en/docs/writing-policies/external-data-sources.md @@ -736,6 +736,7 @@ the output `imageData` variable will have a structure which looks like the follo "registry": "ghcr.io", "repository": "kyverno/kyverno", "identifier": "latest", + "imageIndex": imageIndex, "manifest": manifest, "configData": config, } @@ -755,7 +756,7 @@ The `imageData` variable represents a "normalized" view of an image after any re ``` {{% /alert %}} -The `manifest` and `config` keys contain the output from `crane manifest ` and `crane config ` respectively. +The `imageIndex`, `manifest` and `config` keys contain the output from `crane manifest ` and `crane config ` respectively. For example, one could inspect the labels, entrypoint, volumes, history, layers, etc of a given image. Using the [crane](https://github.com/google/go-containerregistry/tree/main/cmd/crane) tool, show the config of the `ghcr.io/kyverno/kyverno:latest` image: From 25dbcd78f6ce2f51d841f9e34226be70d91b8a26 Mon Sep 17 00:00:00 2001 From: shuting Date: Thu, 26 Sep 2024 19:14:34 +0800 Subject: [PATCH 04/59] feat: update on metrics exposure config (#1363) Signed-off-by: ShutingZhao --- content/en/docs/monitoring/_index.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/content/en/docs/monitoring/_index.md b/content/en/docs/monitoring/_index.md index b37819711..ac341ab5e 100644 --- a/content/en/docs/monitoring/_index.md +++ b/content/en/docs/monitoring/_index.md @@ -138,11 +138,19 @@ metricsConfig: # Per Metric configuration, allows disabling metrics, dropping labels and change the bucket boundaries. metricsExposure: + # Counter disabled + kyverno_policy_rule_info_total: + enabled: false + # Histogram disabled + kyverno_admission_review_duration_seconds: + enabled: false + # Counter with customized dimensions + kyverno_admission_requests: + disabledLabelDimensions: ["resource_namespace", "resource_kind", "resource_request_operation"] + # Histogram with custom boundaries and dimensions kyverno_policy_execution_duration_seconds: disabledLabelDimensions: ["resource_kind", "resource_namespace", "resource_request_operation"] bucketBoundaries: [0.005, 0.01, 0.025] - kyverno_admission_review_duration_seconds: - enabled: false ... ``` From 1bb401a9a3106eeee214569a2eb7de9e73e46461 Mon Sep 17 00:00:00 2001 From: shuting Date: Thu, 26 Sep 2024 21:49:29 +0800 Subject: [PATCH 05/59] feat: add generate foreach (#1357) Signed-off-by: ShutingZhao --- content/en/docs/writing-policies/generate.md | 181 ++++++++++++++++++- content/en/docs/writing-policies/validate.md | 2 +- 2 files changed, 181 insertions(+), 2 deletions(-) diff --git a/content/en/docs/writing-policies/generate.md b/content/en/docs/writing-policies/generate.md index 1b6c6bd73..ee29ade0b 100644 --- a/content/en/docs/writing-policies/generate.md +++ b/content/en/docs/writing-policies/generate.md @@ -223,6 +223,183 @@ spec: matchLabels: allowedToBeCloned: "true" ``` +## foreach + +The `foreach` declaration allows generation of multiple target resources of sub-elements in resource declarations. Each `foreach` entry must contain a `list` attribute, written as a JMESPath expression without braces, that defines the sub-elements it processes. For example, creating networkpolicies for a list of Namespaces which is stored in a label: + +``` +list: request.object.metadata.labels.namespaces | split(@, ',') +``` + +When a `foreach` is processed, the Kyverno engine will evaluate `list` as a JMESPath expression to retrieve zero or more sub-elements for further processing. The value of the `list` field may also resolve to a simple array of strings, for example as defined in a context variable. The value of the `list` field should not be enclosed in braces even though it is a JMESPath expression. + +A variable `element` is added to the processing context on each iteration. This allows referencing data in the element using `element.` where name is the attribute name. For example, using the list `request.object.spec.containers` when the `request.object` is a Pod allows referencing the container image as `element.image` within a `foreach`. An additional variable called `elementIndex` is made available which allows the current index number to be referenced in a loop. + +The following child declarations are permitted in a `foreach`: + +- [Data Source](#data-source) +- [Clone Source](#clone-source) + + +In addition, each `foreach` declaration can contain the following declarations: + +- [Context](external-data-sources.md): to add additional external data only available per loop iteration. +- [Preconditions](preconditions.md): to control when a loop iteration is skipped. + +Here is a complete example of data source type of `foreach` declaration that creates a NetworkPolicy into a list of existing namespaces which is stored as a comma-separated string in a ConfigMap. + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: foreach-generate-data +spec: + rules: + - match: + any: + - resources: + kinds: + - ConfigMap + name: k-kafka-address + generate: + generateExisting: false + synchronize: true + orphanDownstreamOnPolicyDelete: false + foreach: + - list: request.object.data.namespaces | split(@, ',') + context: + - name: ns + variable: + jmesPath: element + preconditions: + any: + - key: '{{ ns }}' + operator: AnyIn + value: + - foreach-ns-1 + apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + name: my-networkpolicy-{{element}}-{{ elementIndex }} + namespace: '{{ element }}' + data: + metadata: + labels: + request.namespace: '{{ request.object.metadata.name }}' + element: '{{ element }}' + elementIndex: '{{ elementIndex }}' + spec: + podSelector: {} + policyTypes: + - Ingress + - Egress +``` + +For a complete example of clone source type of foreach declaration that clones the source Secret into a list of matching existing namespaces which is stored as a comma-separated string in a ConfigMap, see below. + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: foreach-clone +spec: + rules: + - match: + any: + - resources: + kinds: + - ConfigMap + name: k-kafka-address + context: + - name: configmapns + variable: + jmesPath: request.object.metadata.namespace + preconditions: + any: + - key: '{{configmapns}}' + operator: Equals + value: 'default' + generate: + generateExisting: false + synchronize: true + foreach: + - list: request.object.data.namespaces | split(@, ',') + context: + - name: ns + variable: + jmesPath: element + preconditions: + any: + - key: '{{ ns }}' + operator: AnyIn + value: + - foreach-ns-1 + apiVersion: v1 + kind: Secret + name: cloned-secret-{{ elementIndex }}-{{ ns }} + namespace: '{{ ns }}' + clone: + namespace: default + name: source-secret +``` + +See the triggering ConfigMap below, the `data` contains a `namespaces` field defines multiple namespaces. +```yaml +kind: ConfigMap +apiVersion: v1 +metadata: + name: default-deny + namespace: default +data: + namespaces: foreach-ns-1,foreach-ns-2 +``` + +Similarly as above, here is an example of clone list type of `foreach` declaration that clones a list of secrets based on the label selector. +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: foreach-cpol-clone-list-sync-delete-source +spec: + rules: + - match: + any: + - resources: + kinds: + - ConfigMap + name: k-kafka-address + context: + - name: configmapns + variable: + jmesPath: request.object.metadata.namespace + preconditions: + any: + - key: '{{configmapns}}' + operator: Equals + value: '{{request.object.metadata.namespace}}' + generate: + generateExisting: false + synchronize: true + foreach: + - list: request.object.data.namespaces | split(@, ',') + context: + - name: ns + variable: + jmesPath: element + preconditions: + any: + - key: '{{ ns }}' + operator: AnyIn + value: + - foreach-cpol-clone-list-sync-delete-source-target-ns-1 + namespace: '{{ ns }}' + cloneList: + kinds: + - v1/Secret + namespace: foreach-cpol-clone-list-sync-delete-source-existing-ns + selector: + matchLabels: + allowedToBeCloned: "true" +``` ## Generating Bindings @@ -284,7 +461,9 @@ When a new Namespace is created, Kyverno will generate a new RoleBinding called In some cases, a triggering (source) resource and generated (downstream) resource need to share the same life cycle. That is, when the triggering resource is deleted so too should the generated resource. This is valuable because some resources are only needed in the presence of another, for example a Service of type `LoadBalancer` necessitating the need for a specific network policy in some CNI plug-ins. -When a generate rule has synchronization enabled (`synchronize: true`), deletion of the triggering resource will automatically cause deletion of the downstream (generated) resource. In addition to deletion, if the triggering resource is altered in a way such that it no longer matches the definition in the rule, that too will cause removal of the downstream resource. In cases where synchronization needs to be disabled, if the trigger and downstream are both Namespaced resources and in the same Namespace, the ownerReference technique can be used. +When a generate rule has synchronization enabled (`synchronize: true`), deletion of the triggering resource will automatically cause deletion of the downstream (generated) resource. In addition to deletion, if the triggering resource is altered in a way such that it no longer matches the definition in the rule, that too will cause removal of the downstream resource. In cases where synchronization needs to be disabled, if the trigger and downstream are both Namespaced resources and in the same Namespace, the ownerReference technique can be used. + +For a `generate.foreach` type of declaration, Kyverno does not prevent modifications to the rule definition. When the `synchronize` option is enabled for such a rule, Kyverno will not synchronize changes to existing target resources when updates are made to the target resource specification. For instance, if a `generate.foreach` declaration initially creates a NetworkPolicy named `staging/networkpolicy-default`, and is subsequently modified to create a new NetworkPolicy named `staging/networkpolicy-new`, any further changes will not be applied to the existing `staging/networkpolicy-default` NetworkPolicy resource. {{% alert title="Note" color="info" %}} Synchronization involving changes to trigger resources are confined to the `match` block and do not take into consideration preconditions. diff --git a/content/en/docs/writing-policies/validate.md b/content/en/docs/writing-policies/validate.md index fc740d635..2e8a15b82 100644 --- a/content/en/docs/writing-policies/validate.md +++ b/content/en/docs/writing-policies/validate.md @@ -653,7 +653,7 @@ The following child declarations are permitted in a `foreach`: In addition, each `foreach` declaration can contain the following declarations: - [Context](external-data-sources.md): to add additional external data only available per loop iteration. -- [Preconditions](preconditions.md): to control when a loop iteration is skipped +- [Preconditions](preconditions.md): to control when a loop iteration is skipped. - `elementScope`: controls whether to use the current list element as the scope for validation. Defaults to "true" if not specified. Here is a complete example to enforce that all container images are from a trusted registry: From 08d2ef51912ab0cf803249a3d003b2c163fc4eb3 Mon Sep 17 00:00:00 2001 From: Vishal Choudhary Date: Thu, 26 Sep 2024 19:25:31 +0530 Subject: [PATCH 06/59] fix: docs Signed-off-by: Vishal Choudhary --- .../writing-policies/external-data-sources.md | 46 +++---------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/content/en/docs/writing-policies/external-data-sources.md b/content/en/docs/writing-policies/external-data-sources.md index 8ee79fbba..7a7b503ac 100644 --- a/content/en/docs/writing-policies/external-data-sources.md +++ b/content/en/docs/writing-policies/external-data-sources.md @@ -714,53 +714,19 @@ The data returned by GlobalContextEntries may vary depending on whether it is a GlobalContextEntries must be in a healthy state (i.e., there is a response received from the remote endpoint) in order for the policies which reference them to be considered healthy. A GlobalContextEntry which is in a `not ready` state will cause any/all referenced policies to also be in a similar state and therefore will not be processed. Creation of a policy referencing a GlobalContextEntry which either does not exist or is not ready will print a warning notifying users. {{% /alert %}} -## Default -Default is an optional arbitrary JSON object that the context may take if the apiCall returns an error. Default value can also used in case of a server error. +#### Default values for API calls +In the case where the api server returns an error, `default` can be used to provide a fallback value for the api call context entry. The following example shows how to add default value to context entries For example, the policy below uses `default` values to validate: ```yaml -apiVersion: kyverno.io/v1 -kind: ClusterPolicy -metadata: - name: default -spec: - rules: - - name: default-apicall - match: - any: - - resources: - kinds: - - Pod - operations: - - CREATE +... context: - - name: testString + - name: currentnamespace apiCall: - urlPath: "/api/v1/namespaces/{{ request.namespace }}/invalid" + urlPath: "/api/v1/namespaces/{{ request.namespace }}" jmesPath: metadata.name default: default - - name: testJSON - apiCall: - urlPath: "/api/v1/namespaces/{{ request.namespace }}/invalid" - default: '{"metadata": {"name": "default"}}' - - name: testInteger - apiCall: - urlPath: "/api/v1/namespaces/{{ request.namespace }}/invalid" - jmesPath: metadata.resourceVersion - default: 1 - validate: - deny: - conditions: - all: - - key: "{{ testString }}" - operator: Equals - value: "{{ request.namespace }}" - - key: "{{ testJSON.metadata.name }}" - operator: Equals - value: "{{ request.namespace }}" - - key: "{{ testInteger }}" - operator: GreaterThan - value: 2 +... ``` ## Variables from Image Registries From 051966a49dc6405d037cd45b8e79e093390baf7f Mon Sep 17 00:00:00 2001 From: Vishal Choudhary Date: Thu, 26 Sep 2024 19:27:57 +0530 Subject: [PATCH 07/59] fix: cleanup Signed-off-by: Vishal Choudhary --- content/en/docs/writing-policies/external-data-sources.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/en/docs/writing-policies/external-data-sources.md b/content/en/docs/writing-policies/external-data-sources.md index 7a7b503ac..3d64e9153 100644 --- a/content/en/docs/writing-policies/external-data-sources.md +++ b/content/en/docs/writing-policies/external-data-sources.md @@ -715,9 +715,8 @@ GlobalContextEntries must be in a healthy state (i.e., there is a response recei {{% /alert %}} #### Default values for API calls -In the case where the api server returns an error, `default` can be used to provide a fallback value for the api call context entry. The following example shows how to add default value to context entries +In the case where the api server returns an error, `default` can be used to provide a fallback value for the api call context entry. The following example shows how to add default value to context entries: -For example, the policy below uses `default` values to validate: ```yaml ... context: From 6f4982fa933ab2dd8e7273fffe0c2e89e007351f Mon Sep 17 00:00:00 2001 From: Vishal Choudhary Date: Thu, 26 Sep 2024 19:40:49 +0530 Subject: [PATCH 08/59] fix: refactor Signed-off-by: Vishal Choudhary --- .../verify-images/notary/_index.md | 43 +++---------------- 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/content/en/docs/writing-policies/verify-images/notary/_index.md b/content/en/docs/writing-policies/verify-images/notary/_index.md index 2c641b1c0..588bb8741 100644 --- a/content/en/docs/writing-policies/verify-images/notary/_index.md +++ b/content/en/docs/writing-policies/verify-images/notary/_index.md @@ -262,45 +262,16 @@ pod/test created (server dry run) ## Verifying Multiple Image Attestations -Consider the following image: `ghcr.io/kyverno/test-verify-image:signed` - -``` -ghcr.io/kyverno/test-verify-image:signed -├── application/vnd.cncf.notary.signature -│ ├── sha256:7f870420d92765b42cec0f71ee8e25bf39b692f64d95d6f6607e9e6e54300265 -│ └── sha256:f7d941ed9e93a1ff1d5dee3b091144a87dae1d73481d5be93aa65258a110c689 -├── vulnerability-scan -│ └── sha256:f89cb7a0748c63a674d157ca84d725ff3ac09cc2d4aee9d0ec4315e0fe92a5fd -│ └── application/vnd.cncf.notary.signature -│ └── sha256:ec45844601244aa08ac750f44def3fd48ddacb736d26b83dde9f5d8ac646c2f3 -├── sbom/cyclone-dx -│ └── sha256:8cad9bd6de426683424a204697dd48b55abcd6bb6b4930ad9d8ade99ae165414 -│ └── application/vnd.cncf.notary.signature -│ └── sha256:61f3e42f017b72f4277c78a7a42ff2ad8f872811324cd984830dfaeb4030c322 -├── application/vnd.cyclonedx+json -│ └── sha256:aa886b475b431a37baa0e803765a9212f0accece0b82a131ebafd43ea78fa1f8 -│ └── application/vnd.cncf.notary.signature -│ ├── sha256:00c5f96577878d79b545d424884886c37e270fac5996f17330d77a01a96801eb -│ └── sha256:f3dc4687f5654ea8c2bc8da4e831d22a067298e8651fb59d55565dee58e94e2d -├── cyclonedx/vex -│ └── sha256:c058f08c9103bb676fcd0b98e41face2436e0a16f3d1c8255797b916ab5daa8a -│ └── application/vnd.cncf.notary.signature -│ └── sha256:79edc8936a4fb8758b9cb2b8603a1c7903f53261c425efb0cd85b09715eb6dfa -└── trivy/scan - └── sha256:a75ac963617462fdfe6a3847d17e5519465dfb069f92870050cce5269e7cbd7b - └── application/vnd.cncf.notary.signature - └── sha256:d1e2b2ba837c164c282cf389594791a190df872cf7712b4d91aa10a3520a8460 -``` - -This image has: +Consider the image: `ghcr.io/kyverno/test-verify-image:signed` which image has: 1. A notary signature. 2. A vulnerability scan report, signed using notary. -3. A CycloneDX SBOM, signed using notary. -4. A CycloneDX VEX report, signed using notary. -5. A Trivy scan report, signed using notary. +3. A CycloneDX VEX report, signed using notary. -This policy checks the signature in the repo `ghcr.io/kyverno/test-verify-image` and ensures that it has been signed by verifying its signature against the provided certificates: +This policy checks: +1. The signature in the repo `ghcr.io/kyverno/test-verify-image` +2. Ensures that it has a vulnerability scan report of type `trivy/vulnerability`, and a CycloneDX VEX report of type `vex/cyclone-dx`, both are signed using the given certificate. +3. All the vulnerabilities found in the trivy scan report should be allowed in the vex report. ```yaml apiVersion: kyverno.io/v1 @@ -395,7 +366,7 @@ spec: message: All vulnerabilities in trivy and vex should be same ``` -After this policy is applied, Kyverno will validate deny condition which checks all the vulneribilities in trivy report are there in vex report using trivy/scan and cyclonedx/scan, then verifies the signature on both the attestation. +After this policy is applied, Kyverno will verify the signatures in the image and the attestations and then evaluate the validate deny condition which checks all the vulneribilities in trivy report are there in vex report. ```sh kubectl run test --image=ghcr.io/kyverno/test-verify-image:signed --dry-run=server From 40ece26e532b6674df1714e13787a57e7e3c1039 Mon Sep 17 00:00:00 2001 From: Vishal Choudhary Date: Thu, 26 Sep 2024 20:02:54 +0530 Subject: [PATCH 09/59] fix: refactor Signed-off-by: Vishal Choudhary --- .../en/docs/writing-policies/verify-images/notary/_index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/en/docs/writing-policies/verify-images/notary/_index.md b/content/en/docs/writing-policies/verify-images/notary/_index.md index 588bb8741..1d1e816e4 100644 --- a/content/en/docs/writing-policies/verify-images/notary/_index.md +++ b/content/en/docs/writing-policies/verify-images/notary/_index.md @@ -260,7 +260,7 @@ kubectl run test --image=ghcr.io/kyverno/test-verify-image:signed --dry-run=serv pod/test created (server dry run) ``` -## Verifying Multiple Image Attestations +### Validation across multiple image attestations Consider the image: `ghcr.io/kyverno/test-verify-image:signed` which image has: @@ -362,7 +362,6 @@ spec: - key: '{{ trivy.Vulnerabilities[*].VulnerabilityID }}' operator: AnyNotIn value: '{{ vex.vulnerabilities[*].id }}' - message: test1 message: All vulnerabilities in trivy and vex should be same ``` From d5c01d91df68bc670bd9e929867d6dcff37bbb2c Mon Sep 17 00:00:00 2001 From: Vishal Choudhary Date: Thu, 26 Sep 2024 20:14:04 +0530 Subject: [PATCH 10/59] feat (docs): add support for signature algorithm in cosign cert and kms verification (#1337) * feat (docs): add support for signature algorithm in cosign cert and kms verification Signed-off-by: Vishal Choudhary * fix: case Signed-off-by: Vishal Choudhary * fix: add signature algorithms Signed-off-by: Vishal Choudhary --------- Signed-off-by: Vishal Choudhary Co-authored-by: shuting --- .../verify-images/sigstore/_index.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/content/en/docs/writing-policies/verify-images/sigstore/_index.md b/content/en/docs/writing-policies/verify-images/sigstore/_index.md index 5208bf35b..01dfc66d3 100644 --- a/content/en/docs/writing-policies/verify-images/sigstore/_index.md +++ b/content/en/docs/writing-policies/verify-images/sigstore/_index.md @@ -747,6 +747,28 @@ verifyImages: ... ``` +## Using a different signature algorithm + +By default, cosign uses `sha256` has func when computing digests. To use a different signature algorithm, specify the signature algorithm for each attestor as follows: + +```yaml +... +verifyImages: +- imageReferences: + - ghcr.io/kyverno/test-verify-image* + attestors: + - entries: + - signatureAlgorithm: sha256 + keys: + publicKeys: |- + -----BEGIN PUBLIC KEY----- + MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8nXRh950IZbRj8Ra/N9sbqOPZrfM + 5/KAQN0/KjHcorm/J5yctVd7iEcnessRQjU917hmKO6JWVGHpDguIyakZA== + -----END PUBLIC KEY----- +... +``` +Allowed values for signature algorithm are `sha224`, `sha256`, `sha384`, `sha512`. + ## Ignoring Tlogs and SCT Verification Cosign uses Rekor, a transparency log service to store signatures. In Cosign 2.0 verifies Rekor entries for both key-based and identity-based signing. To disable this set `ignoreTlog: true` in Kyverno policies: From 3331b544027c286471685a3fe7f19f812b7cfcdd Mon Sep 17 00:00:00 2001 From: Mariam Fahmy Date: Thu, 26 Sep 2024 23:24:35 +0300 Subject: [PATCH 11/59] add docs for VAPs (#1358) Signed-off-by: Mariam Fahmy --- content/en/docs/kyverno-cli/usage/apply.md | 6 +- content/en/docs/kyverno-cli/usage/test.md | 6 +- .../validatingadmissionpolicy-reports.md | 4 +- content/en/docs/writing-policies/validate.md | 147 +++++++++++++++++- 4 files changed, 147 insertions(+), 16 deletions(-) diff --git a/content/en/docs/kyverno-cli/usage/apply.md b/content/en/docs/kyverno-cli/usage/apply.md index 557d5921f..07e30f0a4 100644 --- a/content/en/docs/kyverno-cli/usage/apply.md +++ b/content/en/docs/kyverno-cli/usage/apply.md @@ -806,7 +806,7 @@ With the `apply` command, Kubernetes ValidatingAdmissionPolicies can be applied Policy manifest (check-deployment-replicas.yaml): ```yaml -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: check-deployments-replicas @@ -863,7 +863,7 @@ The below example applies a `ValidatingAdmissionPolicyBinding` along with the po Policy manifest (check-deployment-replicas.yaml): ```yaml -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: "check-deployment-replicas" @@ -882,7 +882,7 @@ spec: validations: - expression: object.spec.replicas <= 5 --- -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: "check-deployment-replicas-binding" diff --git a/content/en/docs/kyverno-cli/usage/test.md b/content/en/docs/kyverno-cli/usage/test.md index 63f1b0e83..1ebd7d6e6 100644 --- a/content/en/docs/kyverno-cli/usage/test.md +++ b/content/en/docs/kyverno-cli/usage/test.md @@ -701,7 +701,7 @@ Below is an example of testing a ValidatingAdmissionPolicy against two resources Policy manifest (disallow-host-path.yaml): ```yaml -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: disallow-host-path @@ -823,7 +823,7 @@ In the below example, a `ValidatingAdmissionPolicy` and its corresponding `Valid Policy manifest (`check-deployment-replicas.yaml`): ```yaml -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: "check-deployment-replicas" @@ -842,7 +842,7 @@ spec: validations: - expression: object.spec.replicas <= 2 --- -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: "check-deployment-replicas-binding" diff --git a/content/en/docs/policy-reports/validatingadmissionpolicy-reports.md b/content/en/docs/policy-reports/validatingadmissionpolicy-reports.md index 2040e3e28..9baf38b28 100644 --- a/content/en/docs/policy-reports/validatingadmissionpolicy-reports.md +++ b/content/en/docs/policy-reports/validatingadmissionpolicy-reports.md @@ -14,7 +14,7 @@ To configure Kyverno to generate reports for ValidatingAdmissionPolicies, set th Create a ValidatingAdmissionPolicy that checks the Deployment replicas and a ValidatingAdmissionPolicyBinding that binds the policy to a namespace whose labels set to `environment: staging`. ```yaml -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: name: "check-deployment-replicas" @@ -33,7 +33,7 @@ spec: validations: - expression: object.spec.replicas <= 5 --- -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: name: "check-deployment-replicas-binding" diff --git a/content/en/docs/writing-policies/validate.md b/content/en/docs/writing-policies/validate.md index 2e8a15b82..8ec815eb9 100644 --- a/content/en/docs/writing-policies/validate.md +++ b/content/en/docs/writing-policies/validate.md @@ -1697,7 +1697,7 @@ However, setting the deployment image as `staging.example.com/nginx` will allow A ValidatingAdmissionPolicy provides a declarative, in-process option for validating admission webhooks using the [Common Expression Language](https://github.com/google/cel-spec) (CEL) to perform resource validation checks directly in the API server. -Kubernetes [ValidatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/) was first introduced in 1.26, and it's not fully enabled by default as of Kubernetes versions up to and including 1.28. +Kubernetes [ValidatingAdmissionPolicy](https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/) was first introduced in 1.26, and it is enabled by default in 1.30. {{% alert title="Tip" color="info" %}} The Kyverno Command Line Interface (CLI) enables the validation and testing of ValidatingAdmissionPolicies on resources before adding them to a cluster. It can be integrated into CI/CD pipelines to help with the resource authoring process, ensuring that they adhere to the required standards before deployment. @@ -1717,12 +1717,12 @@ To generate ValidatingAdmissionPolicies, make sure to: 1. Enable `ValidatingAdmissionPolicy` [feature gate](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/). -2. For 1.27, enable `admissionregistration.k8s.io/v1alpha1` API, and for 1.28 enable both `admissionregistration.k8s.io/v1alpha1` and `admissionregistration.k8s.io/v1beta1` API. +2. Enable `admissionregistration.k8s.io/v1beta1` API. Here is the minikube command to enable ValidatingAdmissionPolicy: ``` - minikube start --extra-config=apiserver.runtime-config=admissionregistration.k8s.io/v1beta1,apiserver.runtime-config=admissionregistration.k8s.io/v1alpha1 --feature-gates='ValidatingAdmissionPolicy=true' + minikube start --extra-config=apiserver.runtime-config=admissionregistration.k8s.io/v1beta1 --feature-gates='ValidatingAdmissionPolicy=true' ``` 3. Configure Kyverno to manage ValidatingAdmissionPolicies using the `--generateValidatingAdmissionPolicy=true` flag in the admission controller. @@ -1757,8 +1757,6 @@ To generate ValidatingAdmissionPolicies, make sure to: ValidatingAdmissionPolicies can only be generated from the `validate.cel` sub-rules in Kyverno policies. Refer to the [CEL subrule](#common-expression-language-cel) section for more information. -In case there is a PolicyException defined for the Kyverno policy, the ValidatingAdmissionPolicy will not be generated. The PolicyException is used to exclude certain resources from being validated by Kyverno policies. Refer to the [PolicyException](exceptions.md) page for more information. - Below is an example of a Kyverno policy that can be used to generate a ValidatingAdmissionPolicy and its binding: ```yaml @@ -1795,7 +1793,7 @@ status: The generated ValidatingAdmissionPolicy: ```yaml -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicy metadata: labels: @@ -1832,7 +1830,7 @@ spec: The generated ValidatingAdmissionPolicyBinding: ```yaml -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingAdmissionPolicyBinding metadata: labels: @@ -1893,4 +1891,137 @@ Since Kubernetes ValidatingAdmissionPolicies are cluster-scoped resources, Clust When a Kyverno policy matches solely on Pods, the generated ValidatingAdmissionPolicy will match both `pods` and `pods/ephemeralcontainers`. This occurs because Kyverno inherently includes `pods/ephemeralcontainers` by default in the corresponding ValidatingWebhookConfiguration, and we require analogous behavior for the ValidatingAdmissionPolicies. {{% /alert %}} -The generated ValidatingAdmissionPolicy with its binding is totally managed by the Kyverno admission controller which means deleting/modifying these generated resources will be reverted. Any updates to Kyverno policy triggers synchronization in the corresponding ValidatingAdmissionPolicy. +The generated ValidatingAdmissionPolicy with its binding are totally managed by the Kyverno admission controller which means deleting/modifying these generated resources will be reverted. Any updates to Kyverno policy triggers synchronization in the corresponding ValidatingAdmissionPolicy. + +In case there is a [PolicyException](exceptions.md) defined for the Kyverno policy, the corresponding ValidatingAdmissionPolicy will make use of the `matchConstraints.excludeResourceRules` field. + +Below is an example of a Kyverno policy and a PolicyException that matches it. Both the policy and the exception will be used to generate a ValidatingAdmissionPolicy and its corresponding binding. + + +```yaml +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: disallow-host-path +spec: + background: false + rules: + - name: host-path + match: + any: + - resources: + kinds: + - Deployment + - StatefulSet + - ReplicaSet + - DaemonSet + operations: + - CREATE + - UPDATE + namespaceSelector: + matchExpressions: + - key: type + operator: In + values: + - connector + validate: + failureAction: Audit + cel: + expressions: + - expression: "!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, !has(volume.hostPath))" + message: "HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath must be unset." +``` + +```yaml +apiVersion: kyverno.io/v2 +kind: PolicyException +metadata: + name: policy-exception +spec: + exceptions: + - policyName: disallow-host-path + ruleNames: + - host-path + match: + any: + - resources: + kinds: + - Deployment + names: + - important-tool + operations: + - CREATE + - UPDATE +``` + +The generated ValidatingAdmissionPolicy: + +```yaml +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicy +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path + ownerReferences: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: disallow-host-path +spec: + failurePolicy: Fail + matchConstraints: + resourceRules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - deployments + - statefulsets + - replicasets + - daemonsets + namespaceSelector: + matchExpressions: + - key: type + operator: In + values: + - connector + excludeResourceRules: + - apiGroups: + - apps + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resourceNames: + - important-tool + resources: + - deployments + validations: + - expression: '!has(object.spec.template.spec.volumes) || object.spec.template.spec.volumes.all(volume, + !has(volume.hostPath))' + message: HostPath volumes are forbidden. The field spec.template.spec.volumes[*].hostPath + must be unset. +``` + +The generated ValidatingAdmissionPolicyBinding: + +```yaml +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingAdmissionPolicyBinding +metadata: + labels: + app.kubernetes.io/managed-by: kyverno + name: disallow-host-path-binding + ownerReferences: + - apiVersion: kyverno.io/v1 + kind: ClusterPolicy + name: disallow-host-path +spec: + policyName: disallow-host-path + validationActions: [Audit, Warn] +``` From 88196ca2c6fa519f429d0fb6ace8aafe85dc636f Mon Sep 17 00:00:00 2001 From: Vishal Choudhary Date: Fri, 27 Sep 2024 08:54:30 +0530 Subject: [PATCH 12/59] feat: remove beta warning from image verify, exceptions and cleanup policy docs (#1366) feat: remove beta warning from image verify, exceptions and cleanup policy doc Signed-off-by: Vishal Choudhary --- content/en/docs/writing-policies/cleanup.md | 4 ---- content/en/docs/writing-policies/exceptions.md | 4 ---- content/en/docs/writing-policies/verify-images/_index.md | 4 ---- 3 files changed, 12 deletions(-) diff --git a/content/en/docs/writing-policies/cleanup.md b/content/en/docs/writing-policies/cleanup.md index bbf7243b9..8fba6ad83 100644 --- a/content/en/docs/writing-policies/cleanup.md +++ b/content/en/docs/writing-policies/cleanup.md @@ -5,10 +5,6 @@ description: > weight: 70 --- -{{% alert title="Warning" color="warning" %}} -Cleanup policies are a **beta** feature. -{{% /alert %}} - Kyverno has the ability to cleanup (i.e., delete) existing resources in a cluster in two different ways. The first way is via a declarative policy definition in either a `CleanupPolicy` or `ClusterCleanupPolicy`. See the section on [cleanup policies](#cleanup-policy) below for more details. The second way is via a reserved time-to-live (TTL) label added to a resource. See the [cleanup label](#cleanup-label) section for further details. ## Cleanup Policy diff --git a/content/en/docs/writing-policies/exceptions.md b/content/en/docs/writing-policies/exceptions.md index 89b019cdc..8ec57660d 100644 --- a/content/en/docs/writing-policies/exceptions.md +++ b/content/en/docs/writing-policies/exceptions.md @@ -5,10 +5,6 @@ description: > weight: 80 --- -{{% alert title="Warning" color="warning" %}} -Policy exceptions are a **beta** feature. Normal semantic versioning and compatibility rules will not apply. -{{% /alert %}} - Although Kyverno policies contain multiple methods to provide fine-grained control as to which resources they act upon in the form of [`match`/`exclude` blocks](match-exclude.md#match-statements), [preconditions](preconditions.md) at multiple hierarchies, [anchors](validate.md#anchors), and more, all these mechanisms have in common that the resources which they are intended to exclude must occur in the same rule definition. This may be limiting in situations where policies may not be directly editable, or doing so imposes an operational burden. For example, in organizations where multiple teams must interact with the same cluster, a team responsible for policy authoring and administration may not be the same team responsible for submission of resources. In these cases, it can be advantageous to decouple the policy definition from certain exclusions. Additionally, there are often times where an organization or team must allow certain exceptions which would violate otherwise valid rules but on a one-time basis if the risks are known and acceptable. diff --git a/content/en/docs/writing-policies/verify-images/_index.md b/content/en/docs/writing-policies/verify-images/_index.md index de9f15764..920b5ec8e 100644 --- a/content/en/docs/writing-policies/verify-images/_index.md +++ b/content/en/docs/writing-policies/verify-images/_index.md @@ -5,10 +5,6 @@ description: > weight: 60 --- -{{% alert title="Warning" color="warning" %}} -Image verification is a **beta** feature and there may be changes to the API. -{{% /alert %}} - The logical structure of an verifyImages rule is shown below: Image Verification Rule From a78e00342bf923515be522065bd73669867c862e Mon Sep 17 00:00:00 2001 From: "A. Singh" <32884734+A-5ingh@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:09:39 -0400 Subject: [PATCH 13/59] doc: update hugo installation for github codespaces users (#1370) * doc: update hugo installation for github codespaces users Signed-off-by: A. Singh <32884734+A-5ingh@users.noreply.github.com> * Update README.md Signed-off-by: Jim Bugwadia --------- Signed-off-by: A. Singh <32884734+A-5ingh@users.noreply.github.com> Signed-off-by: Jim Bugwadia Co-authored-by: Jim Bugwadia --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 3cadbb4c1..f6e693df5 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,15 @@ hugo server By default, Hugo runs the website at: http://localhost:1313 and will re-build the site on changes. +**Note for Github Codespaces User:** You will be required to install the hugo extended version. To do so download the extended version from [hugo release](https://github.com/gohugoio/hugo/releases) based on your operation system (mostly it is Ubuntu for Codespaces). Use the below commands to install and then move the hugo directory to `usr/local/hugo/bin/hugo` +``` +wget https://github.com/gohugoio/hugo/releases/download/v0.135.0/hugo_extended_0.135.0_linux-amd64.deb +sudo dpkg -i hugo_extended_0.135.0_linux-amd64.deb +rm hugo_extended_0.135.0_linux-amd64.deb +sudo mv /usr/local/bin/hugo /usr/local/hugo/bin/hugo +``` +Finally, Check the hugo version by running: `hugo version` + ## Update Docsy theme The project uses [Hugo Modules](https://gohugo.io/hugo-modules/) to manage the theme: From ca700e95cc6f879f7ce5cbfdf8f43aaee14cecf5 Mon Sep 17 00:00:00 2001 From: "A. Singh" <32884734+A-5ingh@users.noreply.github.com> Date: Mon, 30 Sep 2024 03:07:08 -0400 Subject: [PATCH 14/59] chore: updated JMESPath function (#1371) Signed-off-by: GitHub --- content/en/blog/general/why-chainsaw-is-unique/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/blog/general/why-chainsaw-is-unique/index.md b/content/en/blog/general/why-chainsaw-is-unique/index.md index b38450952..a374c948b 100644 --- a/content/en/blog/general/why-chainsaw-is-unique/index.md +++ b/content/en/blog/general/why-chainsaw-is-unique/index.md @@ -120,14 +120,14 @@ spec: template: spec: (containers[?securityContext == null]): - (len(@)): 0 + (length(@)): 0 ``` In the assertion above, the first three fields `spec`, `template`, and `spec` are basic projections that simply take the content of their respective fields and pass that to descendants. -`(containers[?securityContext == null])` is a JMESPath expression filtering the `containers` array, selecting only the element where `securityContext` is `null`. This projection results in a new array that is passed to the descendant (`(len(@))` in this case). +`(containers[?securityContext == null])` is a JMESPath expression filtering the `containers` array, selecting only the element where `securityContext` is `null`. This projection results in a new array that is passed to the descendant (`(length(@))` in this case). -`(len(@))` is another JMESPath expression that computes the length of the array. There's no more descendant at this point. We're at a leaf of the YAML tree and the array length we just computed is then compared against 0. +`(length(@))` is another JMESPath expression that computes the length of the array. There's no more descendant at this point. We're at a leaf of the YAML tree and the array length we just computed is then compared against 0. If the comparison matches, the assertion will be considered valid; if not, it will be considered failed. From 03c1967d402a48cb8c5c95fb20309e48f7e44faa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 18:21:16 +0800 Subject: [PATCH 15/59] chore(deps): bump actions/checkout from 4.2.0 to 4.2.1 (#1375) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.0 to 4.2.1. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/d632683dd7b4114ad314bca15554477dd762a938...eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-links.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-links.yaml b/.github/workflows/check-links.yaml index 87569e92d..3567d9db6 100644 --- a/.github/workflows/check-links.yaml +++ b/.github/workflows/check-links.yaml @@ -11,7 +11,7 @@ jobs: linkChecker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - name: Check unrendered links id: lychee_unrendered From 95b13ce1da86a0ee9aea3f33a35da2ac27cdf6e2 Mon Sep 17 00:00:00 2001 From: Norbert Szulc Date: Tue, 8 Oct 2024 22:46:18 +0200 Subject: [PATCH 16/59] Enable CORS for RSS feed (#1369) This will allow using the feed in a Grafana dashboard news panel. Signed-off-by: Norbert Szulc Co-authored-by: shuting --- netlify.toml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/netlify.toml b/netlify.toml index 77fa86e0b..ea2573b16 100644 --- a/netlify.toml +++ b/netlify.toml @@ -45,4 +45,9 @@ status = 200 [[headers]] for = "/*" [headers.values] - X-Frame-Options = "SAMEORIGIN" \ No newline at end of file + X-Frame-Options = "SAMEORIGIN" + +[[headers]] + for = "/blog/index.xml" + [headers.values] + access-control-allow-origin = "*" From 7e798764f81d3db3bf94ee1263209269299d6216 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:13:22 +0800 Subject: [PATCH 17/59] chore(deps): bump lycheeverse/lychee-action from 1.10.0 to 2.0.0 (#1378) Bumps [lycheeverse/lychee-action](https://github.com/lycheeverse/lychee-action) from 1.10.0 to 2.0.0. - [Release notes](https://github.com/lycheeverse/lychee-action/releases) - [Commits](https://github.com/lycheeverse/lychee-action/compare/2b973e86fc7b1f6b36a93795fe2c9c6ae1118621...7da8ec1fc4e01b5a12062ac6c589c10a4ce70d67) --- updated-dependencies: - dependency-name: lycheeverse/lychee-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/check-links.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-links.yaml b/.github/workflows/check-links.yaml index 3567d9db6..848d54e59 100644 --- a/.github/workflows/check-links.yaml +++ b/.github/workflows/check-links.yaml @@ -15,7 +15,7 @@ jobs: - name: Check unrendered links id: lychee_unrendered - uses: lycheeverse/lychee-action@2b973e86fc7b1f6b36a93795fe2c9c6ae1118621 # v1.10.0 + uses: lycheeverse/lychee-action@7da8ec1fc4e01b5a12062ac6c589c10a4ce70d67 # v2.0.0 env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} with: @@ -48,7 +48,7 @@ jobs: # - name: Check rendered links # id: lychee_rendered - # uses: lycheeverse/lychee-action@2b973e86fc7b1f6b36a93795fe2c9c6ae1118621 # v1.10.0 + # uses: lycheeverse/lychee-action@7da8ec1fc4e01b5a12062ac6c589c10a4ce70d67 # v2.0.0 # env: # GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} # with: From 846d8236f5e6748c23af8a7207089352d2aa49c8 Mon Sep 17 00:00:00 2001 From: Jim Bugwadia Date: Tue, 8 Oct 2024 20:14:10 -0700 Subject: [PATCH 18/59] fix footer; update banner (#1376) Signed-off-by: Jim Bugwadia Co-authored-by: shuting --- content/en/_index.md | 11 ++++++----- layouts/partials/footer.html | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/content/en/_index.md b/content/en/_index.md index 59867c9b4..8483e4f5c 100644 --- a/content/en/_index.md +++ b/content/en/_index.md @@ -4,7 +4,7 @@ linkTitle = "Kyverno" +++ {{< blocks/cover title="Kyverno" image_anchor="top" height="full" color="dark" >}} -# Policy Management. Simplified. { class="text-center" } +# Policy as Code, Simplified! { class="text-center" }
@@ -28,18 +28,19 @@ linkTitle = "Kyverno"

-Policy Management for Kubernetes and cloud native environments. +The Kyverno project provides a comprehensive set of tools to manage the complete Policy-as-Code (PaC) lifecycle for Kubernetes and other cloud native environments


-Kyverno policies are declarative YAML resources and no new language is required to write policies. This allows using familiar tools such as kubectl, git, and kustomize to manage policies. For efficient handling of complex logic, Kyverno supports both JMESPath and the Common Expressions Language (CEL) languages. + +Kyverno policies are declarative YAML resources and no new language is required. Kyverno enables use of familiar tools such as kubectl, git, and kustomize to manage policies. Kyverno supports JMESPath and the Common Expressions Language (CEL) for efficient handling of complex logic. In Kubernetes environments, Kyverno policies can validate, mutate, generate, and cleanup any Kubernetes resource, including custom resources. To help secure the software supply chain Kyverno policies can verify OCI container image signatures and artifacts. Kyverno policy reports and policy exceptions are also Kubernetes API resources. -The **Kyverno CLI** can be used to apply and test policies off-cluster e.g., as part of a CI/CD pipeline. +The **Kyverno CLI** can be used to apply and test policies off-cluster e.g., as part of an IaC and CI/CD pipelines. -**Kyverno Policy Reporter** provides in-cluster report management with a graphical web-based user interface. +**Kyverno Policy Reporter** provides report management with a graphical web-based user interface. **Kyverno JSON** allows applying Kyverno policies in non-Kubernetes environments and on any JSON payload. diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index d76e35c31..174610ca7 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -22,8 +22,8 @@ {{ with .Site.Params.copyright }}© {{ now.Year}} {{ .}} {{ T "footer_all_rights_reserved" }}{{ end }}

+ - {{ define "footer-links-block" }}