-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
1 parent
77c7981
commit 55e8e48
Showing
8 changed files
with
436 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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`| | | ||
|
Oops, something went wrong.