Skip to content

Commit 9bd7fb8

Browse files
Priya Wadhwatekton-robot
authored andcommitted
Add tutorial for generating signed provenance
This should help people set up signing OCI images and generating signed provenance for them.
1 parent 6c067d5 commit 9bd7fb8

4 files changed

Lines changed: 148 additions & 12 deletions

File tree

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ To finish setting up Chains, please complete the following steps:
4747
* [Set up any additional configuration](docs/config.md)
4848

4949

50-
## Tutorial
51-
To get started with Chains, try out our getting started [tutorial](docs/tutorial.md)!
50+
## Tutorials
51+
To get started with Chains, try out our [getting started tutorial](docs/tutorials/getting-started-tutorial.md).
52+
53+
To start signing OCI images and generating signed provenance for them, try our [signed provenance tutorial](docs/tutorials/signed-provenance-tutorial.md).
5254

5355
## Experimental Features
5456
To learn more about experimental features, check out [experimental.md](docs/experimental.md)

docs/authentication.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,32 @@ The Chains controller will use the same service account your Task runs under as
1111
First, you will need access to credentials for your registry (they are in a file called `credentials.json` in this example).
1212
Next, create a [Docker config type Kubernetes secret](https://kubernetes.io/docs/concepts/configuration/secret/#docker-config-secrets), which will contain the credentials required to push signatures:
1313

14+
15+
Set the namespace and name of the Kubernetes service account:
16+
17+
```
18+
export NAMESPACE=<your namespace>
19+
export SERVICE_ACCOUNT_NAME=<service account name>
20+
```
21+
22+
Then, create a `.dockerconfig` type secret:
23+
1424
```
1525
kubectl create secret docker-registry registry-credentials \
1626
--docker-server=gcr.io \
1727
--docker-username=_json_key \
1828
--docker-email=someemail@something.com \
1929
--docker-password="$(cat credentials.json)" \
20-
-n tekton-chains
30+
-n $NAMESPACE
2131
```
2232
More details around creating this secret can be found [here](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials).
2333

24-
Set the namespace and name of the service account:
25-
26-
```
27-
export NAMESPACE=<your namespace>
28-
export SERVICE_ACCOUNT_NAME=<service account name>
29-
```
3034

31-
and give the service account access to the secret above:
35+
Finally, give the service account access to the secret above:
3236

3337
```
3438
kubectl patch serviceaccount $SERVICE_ACCOUNT_NAME \
3539
-p "{\"imagePullSecrets\": [{\"name\": \"registry-credentials\"}]}" -n $NAMESPACE
3640
```
3741

38-
Now, anything running under `$SERVICE_ACCOUNT_NAME` should be able to push to your OCI registry.
42+
Now, Chains has push permissions for any TaskRuns running under the service account `$SERVICE_ACCOUNT_NAME`.

docs/tutorial.md renamed to docs/tutorials/getting-started-tutorial.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Chains Tutorial
1+
# Chains Getting Started Tutorial
22
This tutorial will guide you through:
33
* Generating your own keypair and storing it as a Kubernetes Secret
44
* Creating a sample TaskRun
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Chains Signed Provenance Tutorial
2+
3+
This tutorial will cover how to set up Chains to sign OCI images built in Tekton, and how to automatically generate and sign in-toto attestations for each image.
4+
This tutorial will also cover how to store these attestations in a transparency log and query the log for the attestation.
5+
6+
This tutorial will guide you through:
7+
* Generating your own keypair and storing it as a Kubernetes Secret
8+
* Setting up authentication for your OCI registry to store images, image signatures and signed image attestations
9+
* Configuring Tekton Chains to generate and sign provenance
10+
* Building an image with kaniko in a Tekton TaskRun
11+
* Verifying the signed image and the signed provenance
12+
13+
## Prerequisites
14+
A Kubernetes cluster with the following installed:
15+
* Tekton Chains
16+
* Tekton Pipelines
17+
18+
19+
## Generate a Key Pair
20+
First, we'll generate an encrypted x509 keypair and save it as a Kubernetes secret.
21+
Install [cosign](https://github.com/sigstore/cosign) and run the following:
22+
23+
```shell
24+
cosign generate-key-pair k8s://tekton-chains/signing-secrets
25+
```
26+
27+
cosign will prompt you for a password, which will be stored in a Kubernetes secret named `signing-secrets` in the `tekton-chains` namespace.
28+
29+
The public key will be written to a local file called `cosign.pub`.
30+
31+
32+
## Set up Authentication
33+
There are two forms of authentication that need to be set up:
34+
1. The default service account in the default namespace needs permission to push to your registry, since this is what Chains will be using for pushing signatures. See our [authentication doc](../authentication.md)
35+
1. The Kaniko Task that will build and push the image needs push permissions for your registry
36+
37+
To set up auth for the Kaniko Task, you'll need a Kubernetes secret of a docker `config.json` file which contains the required auth.
38+
You can create the secret by running:
39+
40+
```
41+
kubectl create secret generic [DOCKERCONFIG_SECRET_NAME] --from-file [PATH TO CONFIG.JSON]
42+
```
43+
44+
## Configuring Tekton Chains
45+
You'll need to make these changes to the Tekton Chains Config:
46+
* `artifacts.taskrun.format=tekton-provenance`
47+
* `artifacts.taskrun.storage=oci`
48+
* `transparency.enabled=true`
49+
50+
You can set these fields by running
51+
52+
```
53+
kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"artifacts.taskrun.format": "tekton-provenance"}}'
54+
kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"artifacts.taskrun.storage": "oci"}}'
55+
kubectl patch configmap chains-config -n tekton-chains -p='{"data":{"transparency.enabled": "true"}}'
56+
```
57+
58+
This tells Chains to generate an in-toto attestation and store it in the specified OCI registry.
59+
Attestations will also be stored in [rekor](https://github.com/sigstore/rekor) since transparency is enabled.
60+
61+
## Start the Kaniko Task
62+
Great, now that the setup is done we're finally ready to build an image with kaniko!
63+
64+
First, apply the [Kaniko Task](../../examples/kaniko/kaniko.yaml) to your cluster:
65+
66+
```
67+
kubectl apply -f examples/kaniko/kaniko.yaml
68+
```
69+
70+
and set the following environment variables:
71+
72+
```
73+
REGISTRY=[The registry you'll be pushing to]
74+
DOCKERCONFIG_SECRET_NAME=[The name of the secret with the docker config.json]
75+
```
76+
77+
Then, you can start the Kaniko Task with the Tekton CLI tool, [tkn](https://github.com/tektoncd/cli):
78+
79+
```
80+
tkn task start --param IMAGE=$REGISTRY/kaniko-chains --use-param-defaults --workspace name=source,emptyDir="" --workspace name=dockerconfig,secret=$DOCKERCONFIG_SECRET_NAME kaniko-chains
81+
```
82+
83+
You can watch the logs of this Task until they complete; if authentication is set up correctly than the final image should be pushed to `$REGISTRY/kaniko-chains`.
84+
85+
86+
## Verifying the Image and Attestation
87+
Once the TaskRun has successfully completed, you'll need to wait a few seconds for Chains to generate provenance and sign it.
88+
89+
Once you see the `chains.tekton.dev/signed=true` annotation on your TaskRun you know that Chains has completed the signing process and you're ready to move on to verification:
90+
91+
```
92+
kubectl get tr [TASKRUN_NAME] -o json | jq -r .metadata.annotations
93+
94+
{
95+
"chains.tekton.dev/signed": "true",
96+
...
97+
}
98+
```
99+
100+
To verify the image and the attestation, we'll use `cosign` again:
101+
102+
```
103+
cosign verify -key cosign.pub $REGISTRY/kaniko-chains
104+
cosign verify-attestation -key cosign.pub $REGISTRY/kaniko-chains
105+
```
106+
107+
You should see verification output for both!
108+
109+
## Finding Provenance in Rekor
110+
To find provenance for the image in Rekor, first get the digest of the `$REGISTRY/kaniko-chains` image you just built.
111+
You can look this up in the TaskRun, or pull the image to get the digest.
112+
113+
You can then search rekor to find all entries that match the sha256 digest of the image you just built with the [rekor-cli](https://github.com/sigstore/rekor/releases/) tool:
114+
115+
```
116+
rekor-cli search --sha [IMAGE_DIGEST]
117+
118+
[UUID1]
119+
[UUID2]
120+
```
121+
122+
The search will print out the UUIDs of matching entries.
123+
It may take a little guessing, but one of those UUIDs holds the attestation.
124+
You can see the attestation by using [jq](https://github.com/stedolan/jq):
125+
126+
```
127+
rekor-cli get --uuid [UUID] --format json | jq -r .Attestation | base64 --decode | jq
128+
```
129+
130+
Congratulations! You have officially built an image, signed it, and generated signed provenance for it with Tekton Chains 🎉

0 commit comments

Comments
 (0)