Skip to content

Commit

Permalink
Reorganize README
Browse files Browse the repository at this point in the history
Adds in:
* including the logo!
* moves the tutorial, config, and signing into separate docs
* updates the install instructions to represent the latest release
* adds an x509 exampele to the tutorial
  • Loading branch information
Priya Wadhwa authored and tekton-robot committed Jun 1, 2021
1 parent 77c7981 commit 55e8e48
Show file tree
Hide file tree
Showing 8 changed files with 436 additions and 188 deletions.
219 changes: 33 additions & 186 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,212 +1,59 @@
# Tekton Chains
Supply Chain Security in Tekton Pipelines

## Getting Started

Tekton Chains is currently experimental, and does not have any published releases.
To use Tekton Chains, you'll have to build and deploy your own release from git.

### Installation

See [DEVELOPMENT.md](DEVELOPMENT.md) for a guide on how to build and deploy your own version.

### Configuration

Chains uses a `ConfigMap` called `chains-config` in the `tekton-chains` namespace for configuration.
Supported keys include (scroll right for defaults):

| Key | Description | Supported Values | Default |
| --- | --- | --- | --- |
| `artifacts.taskrun.format` | The format to store `TaskRun` payloads in. | `tekton` | `tekton` |
| `artifacts.taskrun.storage` | The storage backend to store `TaskRun` signatures in. | `tekton`, `oci`, `gcs`, `docdb` | `tekton` |
| `artifacts.taskrun.signer` | The signature backend to sign `Taskrun` payloads with. | `pgp`, `x509`, `kms` | `x509` |
| `artifacts.oci.format` | The format to store `OCI` payloads in. | `tekton`, `simplesigning` | `simplesigning` |
| `artifacts.oci.storage` | The storage backend to store `OCI` signatures in. | `tekton`, `oci`, `gcs`, `docdb` | `oci` |
| `artifacts.oci.signer` | The signature backend to sign `OCI` payloads with. | `pgp`, `x509`, `kms` | `x509` |
| `signers.kms.kmsref` | The URI reference to a KMS service to use in `KMS` signers. | `gcpkms://projects/<project>/locations/<location>/keyRings/<keyring>/cryptoKeys/<key>`| |
| `storage.docdb.url` | The go-cloud URI reference to a docstore collection | `firestore://projects/<project>/databases/(default)/documents/<collection>?name_field=name`| |

### Overview

`Chains` works by observing `TaskRun` executions, capturing relevant information, and storing it in a cryptographically-signed format.

`TaskRuns` can indicate inputs and outputs which are then captured and surfaced in the `Chains` payload formats, where relevant.
`Chains` uses the standard mechanisms (`Results` and `PipelineResouces`) where possible, and provides a few other mechanisms to *hint* at the correct inputs and outputs. These are outlined below:

#### Chains Type Hinting

When outputing an OCI image without using a `PipelineResource`, `Chains` will look for the following Results:

* `IMAGE_URL` - The URL to the built OCI image
* `IMAGE_DIGEST` - The Digest of the built OCI image

For in-toto attestations, see [INTOTO.md](INTOTO.md) for description
of in-toto specific type hinting.

Note that these are provided automatically when using `PipelineResources`.

### Signing Secrets

To get started signing things with Chains, you first have to instruct Chains on how to sign things.
Chains supports a few different signature schemes, including PGP/GPG, x509 and KMS systems.
The private key material (or access to it) is required by Chains in order to create signatures.

This section explains how to configure this for each type.


#### GPG/PGP

Chains expects the private key and passphrase to be in a secret called `signing-secrets` with the following structure:

* pgp.private-key (the private key)
* pgp.passphrase (the optional passphrase)

You can set all of these as fields in the Kubernetes secret `signing-secrets`:

```shell
kubectl create secret generic signing-secrets -n tekton-chains --from-file=pgp.passphrase --from-file=pgp.private-key --from-file=pgp.public-key
```

##### Setup
You'll need to create or upload an existing private key as Kubernetes secret.
If you don't have one already, but you can usually use something like this:

```shell
gpg --gen-key
```

Enter a passprase (make sure you remember it!) and a name for the key.

Next, you'll need to upload the private key as a Kubernetes `Secret` so Tekton can use it
to sign payloads.
To do that, export the public and private keys as files:

```shell
gpg --export-secret-key --armor $keyname > pgp.private-key
gpg --export --armor $keyname > pgp.public-key
```

And save the passphrase (if you set one) in it's own file:

```shell
echo -n $passphrase > pgp.passphrase
```

#### x509

Chains expects the private key to be stored as an unencrpyted PKCS8 PEM file (`BEGIN PRIVATE KEY`).
Chains only supports `ed25519` and `ecdsa` keys today.

The private key is expected to be stored in a secret named `signing-secrets` under the key `x509.pem`.

Chains also supports keys generated by [cosign](https://github.com/sigstore/cosign), stored as an encrypted PEM file (`ENCRYPTED COSIGN PRIVATE KEY`).
To use a cosign generated key, chains will expect the following to be stored in a secret named `signing-secrets`:
1. `cosign.key`: the cosign-generated private key
1. `cosign.password` the password to decrypt the private key

##### Setup

To create an ecdsa keypair, you can run [gen-keys.sh](gen-keys.sh).
This script will take care of creating the keypair (`x509.pem` and `x509.pub`), and storing the private key as a Kubernetes secret.

_Note: requires `openssl` is installed_

##### Cosign
To create a cosign keypair, `cosign.key` and `cosign.pub`, install [cosign](https://github.com/sigstore/cosign) and run the following:
```shell
cosign generate-key-pair
```
Cosign will prompt you for a password; store this password in a file called `cosign.password`.

You can create a secret with:
```
kubectl create secret generic signing-secrets -n tekton-chains --from-file=cosign.key --from-file cosign.password
```

#### KMS

Chains uses a "go-cloud" URI like scheme to refer to KMS references.
Chains supports GCP KMS and Hashicorp Vault today, but we would love to add support for more.

You can configure Chains to use a specific KMS key using the `signers.kms.kmsref` config key in `chains-config`.

For GCP, this should have the structure of `gcpkms://projects/<project>/locations/<location>/keyRings/<keyring>/cryptoKeys/<key>`
where <location>, <keyring>, and <key> are filled in appropriately.
<p align="center">
<img src="tekton_chains-color.png" alt="Tekton Chains logo"></img>
</p>

For Vault, this should have the structure of `hashivault://<keyname>`, where the `keyname` is filled out appropriately.

The `chains-controller` deployment must have access to this somehow.
For GCP/GKE, we suggest using Workload Identity.
Other Service Account techniques would work as well.

---
**NOTE**

If your signing secrets is already populated, you may get the following error:

```shell
Error from server (AlreadyExists): secrets "signing-secrets" already exists
```

Simply prepend a delete:

```shell
kubectl delete secret signing-secrets -n tekton-chains && kubectl create secret generic signing-secrets -n tekton-chains --from-file=pgp.passphrase --from-file=pgp.private-key --from-file=pgp.public-key
```
---
## Getting Started

## Usage
Tekton Chains is a Kubernetes Custom Resource Definition (CRD) controller that allows you to manage your supply chain security in Tekton.

In its default mode of operation, Chains works by observing all `TaskRuns` in your cluster.
In its default mode of operation, Chains works by observing all `TaskRuns` executions in your cluster.
When `TaskRuns` complete, Chains takes a snapshot of them.
Chains then converts this snapshot to one or more standard payload formats, signs them and stores them somewhere.

To try it out, create a `TaskRun` of your choice.
For a sample one, try this:
Current features include:
* Signing `TaskRun` results with user provided cryptographic keys, including `TaskRun`s themselves and OCI Images
* Attestation formats like [intoto](docs/intoto.md)
* Signing with a variety of cryptograhic key types and services (PGP, x509, KMS)
* Support for multiple storage backends for signatures

```shell
$ kubectl create -f examples/task-output-image.yaml
taskrun.tekton.dev/build-push-run-output-image-abcd created
### Installation
To install the latest version of Chains to your Kubernetes cluster, run:
```

Then, take the name of the `TaskRun` you just created, and wait for it to finish (SUCCEEEDED should be True).

```shell
$ kubectl get taskrun.tekton.dev/taskrun home-is-set-rwhzs
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
home-is-set-rwhzs True Succeeded 105s 100s
kubectl apply --filename https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml
```

Next, retrieve the signature and payload from the object (they are stored as base64-encoded annotations):
To install a specific version of Chains, run:
```
kubectl apply -f https://storage.googleapis.com/tekton-releases/chains/previous/${VERSION}/release.yaml
```

To verify that installation was successful, wait until all Pods have Status `Running`:
```shell
$ kubectl get taskrun home-is-set-rwhzs -o=json | jq -r '.metadata.annotations["chains.tekton.dev/payload-taskrun"]' | base64 --decode > payload
$ kubectl get taskrun home-is-set-rwhzs -o=json | jq -r '.metadata.annotations["chains.tekton.dev/signature-taskrun"]' | base64 --decode > signature
$ kubectl get po -n tekton-chains --watch
NAME READY STATUS RESTARTS AGE
tekton-chains-controller-c4f7c57c4-nrjb2 1/1 Running 0 160m
```

Finally, we can check the signature:
### Setup
To finish setting up Chains, please complete the following steps:
* [Add authentication to the Chains controller](docs/authentication.md)
* [Generate a cryptographic key and configure Chains to use it for signing](docs/signing.md)
* [Set up any additional configuration](docs/config.md)

```shell
gpg --verify signature payload
gpg: Signature made Mon Jul 27 14:42:01 2020 CDT
gpg: using RSA key 4FCFD41D993B806C
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 4 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 4u
gpg: next trustdb check due at 2022-03-16
gpg: Good signature from "Tekton Unit Tests <[email protected]>" [ultimate]
```

Now we have a verifiable record of the `TaskRuns`!
## Tutorial
To get started with Chains, try out our getting started [tutorial](docs/tutorial.md)!

## Authentication
For more information about setting up authentication for Chains, check out [authentication.md](./docs/authentication.md).

## Want to contribute

We are so excited to have you!

See [CONTRIBUTING.md](CONTRIBUTING.md) for an overview of our processes
See [DEVELOPMENT.md](DEVELOPMENT.md) for how to get started
See [ROADMAP.md](ROADMAP.md) for the current roadmap
Look at our good first issues and our help wanted issues
* See [CONTRIBUTING.md](CONTRIBUTING.md) for an overview of our processes
* See [DEVELOPMENT.md](DEVELOPMENT.md) for how to get started
* See [ROADMAP.md](ROADMAP.md) for the current roadmap
Check out our good first issues and our help wanted issues to get started!
2 changes: 1 addition & 1 deletion docs/authentication.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Authentication for Chains

Authentication can be required for the following features in Chains:
Authentication must be set up to take advantage of the following features in Chains:
* Pushing signatures to an OCI registry after signing an image

This doc will cover how to set this up!
Expand Down
36 changes: 36 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Chains Configuration

`Chains` works by observing `TaskRun` executions, capturing relevant information, and storing it in a cryptographically-signed format.

`TaskRuns` can indicate inputs and outputs which are then captured and surfaced in the `Chains` payload formats, where relevant.
`Chains` uses the standard mechanisms (`Results` and `PipelineResouces`) where possible, and provides a few other mechanisms to *hint* at the correct inputs and outputs. These are outlined below:

## Chains Type Hinting

When outputing an OCI image without using a `PipelineResource`, `Chains` will look for the following Results:

* `IMAGE_URL` - The URL to the built OCI image
* `IMAGE_DIGEST` - The Digest of the built OCI image

For in-toto attestations, see [INTOTO.md](INTOTO.md) for description
of in-toto specific type hinting.

Note that these are provided automatically when using `PipelineResources`.


## Chains Configuration

Chains uses a `ConfigMap` called `chains-config` in the `tekton-chains` namespace for configuration.
Supported keys include (scroll right for defaults):

| Key | Description | Supported Values | Default |
| --- | --- | --- | --- |
| `artifacts.taskrun.format` | The format to store `TaskRun` payloads in. | `tekton` | `tekton` |
| `artifacts.taskrun.storage` | The storage backend to store `TaskRun` signatures in. | `tekton`, `oci`, `gcs`, `docdb` | `tekton` |
| `artifacts.taskrun.signer` | The signature backend to sign `Taskrun` payloads with. | `pgp`, `x509`, `kms` | `x509` |
| `artifacts.oci.format` | The format to store `OCI` payloads in. | `tekton`, `simplesigning` | `simplesigning` |
| `artifacts.oci.storage` | The storage backend to store `OCI` signatures in. | `tekton`, `oci`, `gcs`, `docdb` | `oci` |
| `artifacts.oci.signer` | The signature backend to sign `OCI` payloads with. | `pgp`, `x509`, `kms` | `x509` |
| `signers.kms.kmsref` | The URI reference to a KMS service to use in `KMS` signers. | `gcpkms://projects/<project>/locations/<location>/keyRings/<keyring>/cryptoKeys/<key>`| |
| `storage.docdb.url` | The go-cloud URI reference to a docstore collection | `firestore://projects/<project>/databases/(default)/documents/<collection>?name_field=name`| |

Loading

0 comments on commit 55e8e48

Please sign in to comment.