# CNAB Security Draft
> Also see current [pull request in the CNAB specification][pr].
> This document assumes familiarity with the CNAB Core specification, TUF, and In-Toto.
### Key terms
- metadata repository - [TUF repository][tuf-repo] that contains metadata about a CNAB bundle, its referenced images, and [In-Toto verification][in-toto-ver].
- bundle registry - storage and distribution system for CNAB bundles (that may or may not adhere to the CNAB Registry specification)
- image registry - storage and distribution system for container images
- bundle signature - signed digest of a CNAB bundle
- image signature - signed digest a of container image (as defined by the [Docker Content Trust model][dct]) referenced by a CNAB bundle
- [attestation metadata][attestation] - metadata [generated by In-Toto][terminology], which is used by clients to validate the provenance of a software product.
- supply chain layout - signed file that dictates the series of steps that need to be carried out in the supply chain to create a final product; it includes ordered steps, requirements for such steps, and the list of actors (or functionaries) in charge of carrying out every step.
- link - metadata information generated while performing a step or inspection from the layout; signed by the functionary that performed the step.
- [verification image][itc] - container image where In-Toto verifications are run (TODO: where is this specified in the bundle?)
### Used metadata
- bundle signature
- signature of referenced images
- bundle attestation data
- attestation data of referenced images
> Implementations of this specification may choose what metadata to use according to the proposed gradual security model.
>
> The proposed gradual security model of the specification should clarify recommendations and possible vulnerabilities associated with each level.
### Workflows for generating trust metadata
> The following section describes possible workflows for building and signing CNAB bundles.
>
> The only environment currently covered by this section is continuous integration.
The process of building a CNAB bundle is comprised of the following main steps (the actual steps involved might widely differ from organization to organization):
1. project lead defines _each of the different steps involved and its requirements_.
> this step generates the In-Toto supply chain layout
2. developers and operations professionals contribute software and configuration; usage of third party / open source components possible.
> this step generates signed links (e.g.: developer A pushed a commit signed with key B to source control)
3. build the components used by the bundle and other artifacts
> this step generates signed links (e.g.: continuous integration step 1 compiled the source code from source control and generated binary with content digest C)
4. build ( and / or push) / get information for referenced container images
> a. this step generates signed links (e.g.: continuous integration step 2 built container image starting from base image with signature D, and generated image with content digest E)
>
> b. this step also generates an image sigurature (in the Docker Content Trust model)
5. build tools used in the invocation image
> this step generates signed links (similar to metadata generated at step 3)
6. build (and / or push) invocation image
> a. this step generates signed links (similar to metadata generated at step 4b)
>
> b. this step also generates an image signature (similar to metadata generated at step 4)
7. write information about images and metadata (maintainers, parameters, credentials, outputs) into the bundle file
> a. this step generates signed links (e.g.: CNAB builder tool (Porter, Docker App, Duffle) with digest F used input from config file from source control, together with images and digests built by steps 4 and 6 and generated bundle with digest G)
>
> b. this step also generates a bundle signature (bundle digest F is signed in the model defined above)
Metadata generated:
- root layout signed by project owner - step 1
- metadata links signed by functionaries (CI / developers) - steps 2, 3, 4a, 5, 6a, 7a
- signatures for container images referenced in the bundle - step 4b
- signature for invocation image - step 6b
- bundle signature - step 7b
Depending on how the project is structured, the In-Toto metadata (and the actual process) can be further split into:
- signed root layout for _each software component that is referenced in the bundle_
- set of signed links by the functionaries of _each root layout defined above_
- signed root layout for invocation image
- set of signed links for invocation image
### Distributing the trust metadata
For container images, we propose:
- trust metadata is stored in a single TUF repository
- image digest (signature) stored in the `hashes` object of a target in the targets metadata file (as instructed by the Docker Content Trust model)
- In-Toto metadata for the image stored in the `custom`.`image-metadata` object of the target in the targets metadata file, with a typed structure (clearly defined names for root layout, keys, and another map with named links)
For CNAB bundles, we propose:
- bundle digest (signature) stored in the `hashes` object of a target in the targets metadata file (similar to the Docker Content Trust model)
- the `custom` object of the target in the targets metadata file contains:
- In-Toto metadata for the bundle stored in a `custom`.`bundle-metadata` object. Potentially, all In-Toto metadata can be stored in this object. However, if needed, attestation files for referenced images can be referenced in the following object.
- an optional map with the name of each image and either:
- the actual in-toto metadata for the image (see structure above)
- the remote URL of the TUF collection that contains In-Toto metadata for the image, in the structure above
- if both are provided, only one is used for verification. (TODO: we should prescribe which of them them).
- if no map is provided, runtimes should check the `custom`.`image-metadata` object in the TUF collection for referenced images.
> TODO: specify how to get the public keys to verify signatures
We think this model for distributing the trust metadata should accommodate most organizations building bundles.
### Performing verifications on bundles
We propose the following workflow for performing verifications:
- bundle receives command to pull a bundle, with the bundle URL (OCI registry or otherwise) and URL for bundle trust metadata (if the OCI registry has a trust server associated, it can be omitted - Azure Container Registries, Docker Hub)
- bundle signature is fetched from trust registry (all [additional steps from the TUF workflow should be followed][tuf-workflow])
- bundle is pulled from the URL
- bundle digest is computed locally and verified against the digest from the trust registry
- if the digest doesn't match, runtimes must stop the execution
- the In-Toto metadata associated with the bundle is fetched from the trust server
- metadata for the bundle provenance is fetched
- all metadata for referenced images is fetched (either directly, or from their URL) (TODO: how to ensure the verification process has access to the URLs if referenced?)
- all In-Toto layouts are structurally validated locally
- if any validation fails, runtimes must stop the execution
- In-Toto metadata is copied into a container based on a _verification image_
- all In-Toto verifications are run inside the container, [according to the In-Toto specification][verification] (TODO: decide how to handle N sets of verification data - one container execution vs. N)
- if the validations fail, runtimes must stop the execution
- runtime continues the operation by pulling the invocation image. See the runtime specification.
### Key management
This specification does not currently cover how the public keys for TUF and in-toto are distributed. This needs to be resolved as part of the specification.
### Appendix - partial workflow for pushing, pulling, and verifying trust metadata
- it uses Docker Hub to store the CNAB bundle, and Docker Notary to store the TUF + In-Toto metadata (note that the implementation is not dependent on a particular registry, and uses the `custom` object of the TUF targets file to store In-Toto metadata)
- it assumes the bundle is built, and is referenced by file
- it assumes the In-Toto metadata is already generated, and expects the root layout, signing key for the layout, and the links directory as parameters to the push operation
- currently, only bundle attestation metadata is pushed to the trust server
```
$ signy intoto-sign bundle.json radumatei/tuf-intoto-metadata:v1
--layout testdata/intoto/demo.layout.template
--layout-key testdata/intoto/alice.pub
--links testdata/intoto
Adding In-Toto layout and links metadata to TUF
Root key found, using: <root key>
Pushed trust data for <bundle-repo>: <SHA> to server https://notary.docker.io
Starting to copy image cnab/helloworld:0.1.1...
adding entry in relocation map: cnab/helloworld:0.1.1: docker.io/radumatei/tuf-intoto-metadata@sha256:a59a4e74d9cc89e4e75dfb2cc7ea5c108e4236ba6231b53081a9e2506d1197b6Completed image cnab/helloworld:0.1.1 copy
Generated relocation map: bundle.ImageRelocationMap{"cnab/helloworld:0.1.1":"docker.io/radumatei/tuf-intoto-metadata@sha256:a59a4e74d9cc89e4e75dfb2cc7ea5c108e4236ba6231b53081a9e2506d1197b6"}
Pushed successfully, with digest "sha256:086ef83113475d4582a7431b4b9bc98634d4f71ad1289cca45e661153fc9a46e"
$ signy intoto-verify radumatei/tuf-intoto-metadata:v1
--image radumatei/in-toto-container:v1
Pulled trust data for radumatei/tuf-intoto-metadata:v1, with role targets - SHA256: 607ddb1d998e2155104067f99065659b202b0b19fa9ae52349ba3e9248635475
Pulling bundle from registry: radumatei/tuf-intoto-metadata:v1
Relocation map map[cnab/helloworld:0.1.1:radumatei/tuf-intoto-metadata@sha256:a59a4e74d9cc89e4e75dfb2cc7ea5c108e4236ba6231b53081a9e2506d1197b6]
Computed SHA: 607ddb1d998e2155104067f99065659b202b0b19fa9ae52349ba3e9248635475
The SHA sums are equal: 607ddb1d998e2155104067f99065659b202b0b19fa9ae52349ba3e9248635475
Writing In-Toto metadata files into /tmp/intoto-verification667685729
copying file /in-toto/layout.template in container for verification...
copying file /in-toto/key.pub in container for verification...
copying file in-toto/package.2f89b927.link in container for verification...
copying file in-toto/write-code.776a00e2.link in container for verification...
copying file in-toto/foo.tar.gz in container for verification...
Loading layout...
Loading layout key(s)...
Verifying layout signatures...
Verifying layout expiration...
Reading link metadata files...
Verifying link metadata signatures...
Verifying sublayouts...
Verifying alignment of reported commands...
Verifying command alignment for 'write-code.776a00e2.link'...
Verifying command alignment for 'package.2f89b927.link'...
Verifying threshold constraints...
Skipping threshold verification for step 'write-code' with threshold '1'...
Skipping threshold verification for step 'package' with threshold '1'...
Verifying Step rules...
Verifying material rules for 'write-code'...
Verifying product rules for 'write-code'...
Verifying 'ALLOW foo.py'...
Verifying material rules for 'package'...
Verifying 'MATCH foo.py WITH PRODUCTS FROM write-code'...
Verifying 'DISALLOW *'...
Verifying product rules for 'package'...
Verifying 'ALLOW foo.tar.gz'...
Verifying 'ALLOW foo.py'...
Executing Inspection commands...
Executing command for inspection 'untar'...
Running 'untar'...
Recording materials '.'...
Running command 'tar xfz foo.tar.gz'...
Recording products '.'...
Creating link metadata...
Verifying Inspection rules...
Verifying material rules for 'untar'...
Verifying 'MATCH foo.tar.gz WITH PRODUCTS FROM package'...
Verifying 'DISALLOW foo.tar.gz'...
Verifying product rules for 'untar'...
Verifying 'MATCH foo.py WITH PRODUCTS FROM write-code'...
Verifying 'DISALLOW foo.py'...
The software product passed all verification.
```
[pr]: https://github.com/deislabs/cnab-spec/pull/253/files
[tuf]: https://github.com/theupdateframework/specification
[in-toto]: https://github.com/in-toto/docs
[tuf-repo]: https://github.com/theupdateframework/specification/blob/master/tuf-spec.md#3-the-repository
[in-toto-ver]: https://github.com/in-toto/docs/blob/master/in-toto-spec.md#16-terminology
[dct]: https://docs.docker.com/engine/security/trust/content_trust/
[attestation]: https://github.com/in-toto/docs/blob/master/in-toto-spec.md#31-contents
[terminology]: https://github.com/in-toto/docs/blob/master/in-toto-spec.md#16-terminology
[tuf-workflow]: https://github.com/theupdateframework/specification/blob/master/tuf-spec.md#5-detailed-workflows
[itc]: https://github.com/engineerd/in-toto-container
[verification]: https://github.com/in-toto/docs/blob/master/in-toto-spec.md#52-verifying-the-final-product