Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: update cosign tutorial and commands, update kyverno policy #5929

Merged
merged 4 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/docs/supply-chain/attestation/vuln.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,14 @@ You can use Cosign to sign without keys by authenticating with an OpenID Connect

```
$ trivy image --format cosign-vuln -o vuln.json <IMAGE>
$ COSIGN_EXPERIMENTAL=1 cosign attest --type vuln --predicate vuln.json <IMAGE>
$ cosign attest --type vuln --predicate vuln.json <IMAGE>
```
This will provide a certificate in the output section.

You can verify attestations.
You can verify attestations:

```
$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type vuln <IMAGE>
$ cosign verify-attestation --certificate=path-to-the-certificate --type vuln --certificate-identity Email-used-to-sign --certificate-oidc-issuer='the-issuer-used' <IMAGE>
```

[vuln-attest-spec]: https://github.com/sigstore/cosign/blob/95b74db89941e8ec85e768f639efd4d948db06cd/specs/COSIGN_VULN_ATTESTATION_SPEC.md
63 changes: 24 additions & 39 deletions docs/tutorials/kubernetes/kyverno.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ This tutorial details
- Verify the container image has an attestation with Kyverno

### Prerequisites
1. [Attestation of the vulnerability scan uploaded][vuln-attestation]
2. A running Kubernetes cluster that kubectl is connected to
1. A running Kubernetes cluster that kubectl is connected to
2. A Container image signed with Cosign and an attestation generated for a Trivy Vulnerability scan.
[Follow this tutorial for more information.][vuln-attestation]

### Kyverno Policy to check attestation

Expand All @@ -24,26 +25,36 @@ kind: ClusterPolicy
metadata:
name: check-vulnerabilities
spec:
validationFailureAction: enforce
webhookTimeoutSeconds: 10
validationFailureAction: Enforce
background: false
webhookTimeoutSeconds: 30
failurePolicy: Fail
rules:
- name: not-older-than-one-week
- name: checking-vulnerability-scan-not-older-than-one-hour
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "CONTAINER-REGISTRY/*:*"
- "*"
attestations:
- predicateType: cosign.sigstore.dev/attestation/vuln/v1
- type: https://cosign.sigstore.dev/attestation/vuln/v1
conditions:
- all:
- key: "{{ time_since('','{{metadata.scanFinishedOn}}','') }}"
- key: "{{ time_since('','{{ metadata.scanFinishedOn }}', '') }}"
operator: LessThanOrEquals
value: "168h"
value: "1h"
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
abc
xyz
-----END PUBLIC KEY-----
```

{% endraw %}
Expand All @@ -57,38 +68,12 @@ Next, apply the above policy:
kubectl apply -f vuln-attestation.yaml
```

To ensure that the policy worked, we can deploye an example deployment file with our container image:
To ensure that the policy worked, we can deploy an example Kubernetes Pod with our container image:

deployment.yaml
```
apiVersion: apps/v1
kind: Deployment
metadata:
name: cns-website
namespace: app
spec:
replicas: 2
selector:
matchLabels:
run: cns-website
template:
metadata:
labels:
run: cns-website
spec:
containers:
- name: cns-website
image: docker.io/anaisurlichs/cns-website:0.0.6
ports:
- containerPort: 80
imagePullPolicy: Always
resources:
limits:
memory: 512Mi
cpu: 200m
securityContext:
allowPrivilegeEscalation: false
kubectl run app-signed --image= docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd 
```
Note that the image is based on the [signing tutorial.][vuln-attestation]

Once we apply the deployment, it should pass since our attestation is available:
```
Expand All @@ -98,7 +83,7 @@ deployment.apps/cns-website created

However, if we try to deploy any other container image, our deployment will fail. We can verify this by replacing the image referenced in the deployment with `docker.io/anaisurlichs/cns-website:0.0.5` and applying the deployment:
```
kubectl apply -f deployment-two.yaml
kubectl run app-unsigned --image=docker.io/anaisurlichs/cns-website:0.1.1 

Resource: "apps/v1, Resource=deployments", GroupVersionKind: "apps/v1, Kind=Deployment"
Name: "cns-website", Namespace: "app"
Expand Down
135 changes: 122 additions & 13 deletions docs/tutorials/signing/vuln-attestation.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,145 @@
# Vulnerability Scan Record Attestation

This tutorial details
This tutorial details how to

- Scan your container image for vulnerabilities
- Generate an attestation with Cosign
- Scan container images for vulnerabilities
- Generate an attestation, using Cosign, with and without generating a separate key pair

#### Prerequisites

1. Trivy CLI installed
2. Cosign installed
1. [Trivy CLI](../../getting-started/installation.md) installed
2. [Cosign CLI](https://docs.sigstore.dev/system_config/installation/) installed
3. Ensure that you have access to a container image in a remote container registry that you own/within your account. In this tutorial, we will use DockerHub.

#### Scan Container Image for vulnerabilities
## Scan Container Image for vulnerabilities

Scan your container image for vulnerabilities and save the scan result to a scan.json file:
```
trivy image --ignore-unfixed --format json --output scan.json anaisurlichs/cns-website:0.0.6
trivy image --ignore-unfixed --format cosign-vuln --output scan.json DockerHubID/imagename:imagetag
```

* --ignore-unfixed: Ensures that only the vulnerabilities are displayed that have a already a fix available
* --output scan.json: The scan output is saved to a scan.json file instead of being displayed in the terminal.
For example:
```
trivy image --ignore-unfixed --format cosign-vuln --output scan.json anaisurlichs/signed-example:0.1
```

Note: Replace the container image with the container image that you would like to scan.
* `--ignore-unfixed`: Ensures only the vulnerabilities, which have a already a fix available, are displayed
* `--output scan.json`: The scan output is saved to a scan.json file instead of being displayed in the terminal.

Note: Replace the container image with the container image that you want to scan.

## Option 1: Signing and Generating an attestation without new key pair

#### Signing

Sign the container image:
```
cosign sign DockerHubID/imagename@imageSHA
```

The `imageSHA` can be obtained through the following docker command:
```
docker image ls --digests
```
The SHA will be displayed next to the image name and tag.

Note that it is better practice to sign the image SHA rather than the tag as the SHA will remain the same for the particular image that we have signed.

For example:
```
cosign sign docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd
```

#### Attestation of the vulnerability scan with Cosign
#### Attestation

The following command generates an attestation for the vulnerability scan and uploads it to our container image:
The following command generates an attestation for the vulnerability scan and uploads it to the container image used:
```
cosign attest --replace --predicate scan.json --type vuln anaisurlichs/cns-website:0.0.6
cosign attest --predicate scan.json --type vuln docker.io/DockerHubID/imagename:imageSHA
```

For example:
```
cosign attest --predicate scan.json --type vuln docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd
```

Note: Replace the container image with the container image that you would like to scan.

Next, Sigstore will ask you to verify with an account -- Microsoft, GitHub, or Google.

Once done, the user will be provided with a certificate in the terminal where they ran the command. Example certificate:
```
-----BEGIN CERTIFICATE-----
MIIC1TCCAlygAwIBAgIUfSXI7xTWSLq4nuygd8YPuhPZlEswCgYIKoZIzj0EAwMw
NzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRl
cm1lZGlhdGUwHhcNMjQwMTExMTMzODUzWhcNMjQwMTExMTM0ODUzWjAAMFkwEwYH
KoZIzj0CAQYIKoZIzj0DAQcDQgAETcUNnK76mfo9G3j1c7NN6Vcn6yQPDX5rd3QB
unkHs1Uk59CWv3qm6sUyRNYaATs9zdHAZqLck8G4P/Pj7+GzCKOCAXswggF3MA4G
........
-----END CERTIFICATE-----
```


## Option 2: Signing and Generating an attestation with a new Cosign key pair

To generate an attestation for the container image with a separate key pair, we can use Cosign to generate a new key pair:
```
cosign generate-key-pair 
```

This will generate a `cosign.key` and a `cosign.pub` file. The `cosign.key` file is your private key that should be kept confidential as it is used to sign artefacts. However, the `cosign.pub` file contains the information of the corresponding public key. This key can be used by third parties to verify the attestation -- basically that this person who claims to have signed the attestation actually is the one who signed it.

#### Signing

Sign the container image:
```
cosign sign --key cosign.key docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd
```

#### Attestation

To generate the attestation with the specific key pairs, run the following command:
```
cosign attest --key cosign.key --type vuln --predicate scan.json docker.io/anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd 
```

## Verify the attestation

### Option 1 -- No separate key pair

If you have not generated a key pair but received a certificate after the container image was signed, use the following command to verify the attestation:

```
cosign verify-attestation --type vuln --certificate-identity Email-used-to-sign --certificate-oidc-issuer='the-issuer-used' docker.io/DockerHubID/imagename:imageSHA
```

For example, the command could be like this:
```
cosign verify-attestation --type vuln --certificate-identity urlichsanais@gmail.com --certificate-oidc-issuer='https://github.com/login/oauth' anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd
```

### Option 2 -- Separate key pair

If you have used a new cosign key pair, the attestation can be verified through the following command:
```
cosign verify-attestation --key cosign.pub --type vuln anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd 
```

<details>
<summary>Output</summary>

The output should look similar to the following:
```
Verification for anaisurlichs/signed-example@sha256:c5911ac313e0be82a740bd726dc290e655800a9588424ba4e0558c705d1287fd --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- The signatures were verified against the specified public key
{"payloadType":"application/vnd.in-toto+json","payload":
```
</details>

## More information

See [here][vuln-attestation] for more details.

[vuln-attestation]: ../../docs/supply-chain/attestation/vuln.md