From e83eedb016b20f89c3b6fd12994680c32f1306cb Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Thu, 14 Jan 2021 15:53:54 -0800 Subject: [PATCH 01/10] Staged content for artifact-manifest Signed-off-by: Steve Lasker --- .../artifact-manifest-bicep.json | 41 ++++ ...tifact-manifest-mysql-image-signature.json | 24 +++ ...act-manifest-wordpress-cnab-signature.json | 0 .../artifact-manifest-wordpress-cnab..json | 0 ...act-manifest-wordpress-helm-signature.json | 34 +++ .../artifact-manifest-wordpress-helm.json | 58 +++++ ...ct-manifest-wordpress-image-signature.json | 33 +++ artifact-manifest/artifact-manifest.json | 43 ++++ artifact-manifest/artifact-manifest.md | 198 ++++++++++++++++++ 9 files changed, 431 insertions(+) create mode 100644 artifact-manifest/artifact-manifest-bicep.json create mode 100644 artifact-manifest/artifact-manifest-mysql-image-signature.json create mode 100644 artifact-manifest/artifact-manifest-wordpress-cnab-signature.json create mode 100644 artifact-manifest/artifact-manifest-wordpress-cnab..json create mode 100644 artifact-manifest/artifact-manifest-wordpress-helm-signature.json create mode 100644 artifact-manifest/artifact-manifest-wordpress-helm.json create mode 100644 artifact-manifest/artifact-manifest-wordpress-image-signature.json create mode 100644 artifact-manifest/artifact-manifest.json create mode 100644 artifact-manifest/artifact-manifest.md diff --git a/artifact-manifest/artifact-manifest-bicep.json b/artifact-manifest/artifact-manifest-bicep.json new file mode 100644 index 0000000..e00ff14 --- /dev/null +++ b/artifact-manifest/artifact-manifest-bicep.json @@ -0,0 +1,41 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.collection.v1+json", + "config": { + "mediaType": "application/vnd.azure.arm.bicep.config.v1+json", + "size": 7023, + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + }, + "references": [ + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 32654, + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0" + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 16724, + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 73109, + "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" + }, + { + "mediaType": "image|index|signature|helm|CNAB|...", + "digest": "---", + "refType": "hard|soft" + }, + { + "mediaType": "image|index|signature|helm|CNAB|...", + "digest": "---", + "refType": "hard|soft" + }, + { + "mediaType": "image|index|signature|helm|CNAB|...", + "digest": "---", + "refType": "hard|soft" + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-mysql-image-signature.json b/artifact-manifest/artifact-manifest-mysql-image-signature.json new file mode 100644 index 0000000..eb2c154 --- /dev/null +++ b/artifact-manifest/artifact-manifest-mysql-image-signature.json @@ -0,0 +1,24 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.collection.v1+json", + "artifactType": "application/vnd.cncf.notary.v2", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 0 + }, + "dependencies": [ + { + "mediaType": "application/vnd.cncf.notary.v2.json", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654, + "reference": "registry.wabbitnetworks.io" + }, + { + "mediaType": "application/vnd.oci.image.manifest.v1", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724, + "reference": "/mysql:3.1" + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-wordpress-cnab-signature.json b/artifact-manifest/artifact-manifest-wordpress-cnab-signature.json new file mode 100644 index 0000000..e69de29 diff --git a/artifact-manifest/artifact-manifest-wordpress-cnab..json b/artifact-manifest/artifact-manifest-wordpress-cnab..json new file mode 100644 index 0000000..e69de29 diff --git a/artifact-manifest/artifact-manifest-wordpress-helm-signature.json b/artifact-manifest/artifact-manifest-wordpress-helm-signature.json new file mode 100644 index 0000000..18d959c --- /dev/null +++ b/artifact-manifest/artifact-manifest-wordpress-helm-signature.json @@ -0,0 +1,34 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2", + "size": 0, + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + }, + "parent": { + "mediaType": "application/vnd.oci.image.index.v1.config.json", + "reference": "/wordpress:5.7" + }, + "blobs": [ + { + "mediaType": "application/vnd.cncf.notary.v2.json", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654, + "reference": "registry.wabbitnetworks.io" + } + ], + "dependencies": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config.json", + "reference": "/wordpress:5.7", + "depType": "hard" + }, + { + "mediaType": "application/vnd.oci.image.index.v1.config.json", + "reference": "/mysql:3.1", + "depType": "hard" + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-wordpress-helm.json b/artifact-manifest/artifact-manifest-wordpress-helm.json new file mode 100644 index 0000000..f0cbed8 --- /dev/null +++ b/artifact-manifest/artifact-manifest-wordpress-helm.json @@ -0,0 +1,58 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.helm.v3", + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "size": 0, + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + }, + "blobs": [ + { + "mediaType": "application/vnd.cncf.helm.chart.v1.tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + }, + { + "mediaType": "application/vnd.cncf.helm.values.v1.yaml", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "dependencies": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config.json", + "reference": "/wordpress:5.7", + "depType": "soft" + }, + { + "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "reference": "/mysql:v3.1", + "depType": "soft" + }, + { + "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "refType": "manifest", + "reference": "/wordpress@sha256:swo32498791238740124809sd098s7q40129874" + }, + { + "comment": "this is a referenced helm chart", + "mediaType": "application/vnd.oci.artifact.manifest.v1.json", + "artifactType": "application/vnd.cncf.helm.v3", + "reference": "/wordpress:5.7" + } + ], + "annotations": { + "org.opencontainers.artifact.created": "", + "org.opencontainers.artifact.authors": "", + "org.opencontainers.artifact.url": "opencontainers.org", + "org.opencontainers.artifact.documentation": "opencontainers.org", + "org.opencontainers.artifact.source": "https://github.com/opencontainers/artifacts", + "org.opencontainers.artifact.version": "v1.0", + "org.opencontainers.artifact.revision": "v1.1.0", + "org.opencontainers.artifact.vendor": "Open Containers Initiative", + "org.opencontainers.artifact.licenses": "MIT", + "org.opencontainers.artifact.title": "Open Containers Artifact Manifest", + "org.opencontainers.artifact.description": "A schema for defining artifacts" + } +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-wordpress-image-signature.json b/artifact-manifest/artifact-manifest-wordpress-image-signature.json new file mode 100644 index 0000000..094ddab --- /dev/null +++ b/artifact-manifest/artifact-manifest-wordpress-image-signature.json @@ -0,0 +1,33 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.collection.v1+json", + "artifactType": "application/vnd.cncf.notary.v2", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 0 + }, + "dependencies": [ + { + "mediaType": "application/vnd.cncf.notary.v2.json", + "refType": "blob", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654, + "reference": "registry.wabbitnetworks.io" + }, + { + "mediaType": "application/vnd.oci.image.manifest.v1", + "digest": "wordpress@sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724, + "linkType": "hard|soft", + "linkType": "parent|child", + "reference": "/wordpress:5.7" + }, + "links": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config.json", + "refType": "manifest", + "reference": "/wordpress:5.7" + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest.json b/artifact-manifest/artifact-manifest.json new file mode 100644 index 0000000..f0ba833 --- /dev/null +++ b/artifact-manifest/artifact-manifest.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.collection.v1+json", + "config": { + "mediaType": "application/vnd.oci.artifact.collection.config.v1+json", + "size": 7023, + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + }, + "blobs": [ + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 32654, + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0" + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 16724, + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 73109, + "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" + } + ], + "references": [ + { + "mediaType": "image|index|signature|helm|CNAB|...", + "digest": "---", + "refType": "hard|soft" + }, + { + "mediaType": "image|index|signature|helm|CNAB|...", + "digest": "---", + "refType": "hard|soft" + }, + { + "mediaType": "image|index|signature|helm|CNAB|...", + "digest": "---", + "refType": "hard|soft" + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md new file mode 100644 index 0000000..65dfef1 --- /dev/null +++ b/artifact-manifest/artifact-manifest.md @@ -0,0 +1,198 @@ +# OCI Artifact Manifest + +The OCI artifact manifest provides a means to define a wide range of artifacts, including a chain of dependencies of related artifacts. It provides a means to define a collection of items, including blobs and linked artifacts with the information needed for reference counting, garbage collection and indexing. + +## Goals of Artifact Manifest + +### Bi-directional Hierarchal Support + +The OCI Distribution-spec 1.0 supports tops down hierarchies for tracking a manifest, a config object, and a collection of layers. This works well for immutable artifacts that are individually pushed to a registry. As an artifact is pushed, a manifest and digest of the manifest and it's referenced layers are computed. + +The artifact-manifest will support additional references to existing content within a registry. Rather than update the original manifest with the additional objects, the additional object will provide the digest by which it's enhancing. + +- `hello-world:v1` with a digest of `sha256:8b895ffec9fe33301cee47b0edc1600ea67604c3d138fa8ecb43ae62ad3b6fd4` is pushed to the registry +- A **S**oftware **B**ill **o**f **M**aterials (SBoM) for `hello-world:v1` is pushed to the registry. +- A `hello-world:v1` SBoM is pushed, using digest of the `hello-world:v1` image. + +In the above case, the original `hello-world:v1` image digest remains the same. Deployments of the `hello-world:v1` image can be made using the `hello-world:v1` tag, or the `sha256:8b89...` digest. With additional distribution-spec artifact APIs, requests may be made to list objects that reference the `hello-world:v1` artifact. In this case, returning the SBoM references. + +### Artifact Copying Within and Across OCI Compliant Registries + +Distribution-spec APIs will provide a means to discover, pull and push content within and across registries. No knowledge of the specific artifact type will be necessary. + +### Delete Operations + +Distribution-spec APIs will provide standard delete operations, including options for deleting referenced artifacts, or blocking a delete as the artifact is referenced by other artifacts. + +- Which references should be deleted (ref counted) +- Which references should just reduce ref counting? +- Which artifacts should be blocked from deletion as another artifact depends upon it? +- Examples: + - deleting the wordpress helm chart deletes the config, chart and values blobs + - deleting the mysql image should warn if referenced by helm charts + - deleting the wordpress chart removes a ref count to the mysql image, for mysql deletion + +## *Image Manifest* Property Descriptions + +- **`schemaVersion`** *int* + + This REQUIRED property specifies the artifact manifest schema version. + For this version of the specification, this MUST be `1`. The value of this MAY change if the schema is enhanced. + +- **`mediaType`** *string* + + This property identifies the OCI Artifact Manifest schema. This field MUST be `"application/vnd.oci.artifact.manifest.v1+json"` + +- **`config`** *[descriptor](descriptor.md)* + + This REQUIRED property references a configuration object for a container, by digest. + Beyond the [descriptor requirements](descriptor.md#properties), the value has the following additional restrictions: + + - **`mediaType`** *string* + + This [descriptor property](descriptor.md#properties) has additional restrictions for `config`. + Implementations MUST support at least the following media types: + + - [`application/vnd.oci.image.config.v1+json`](config.md) + + Manifests concerned with portability SHOULD use one of the above media types. + +- **`layers`** *array of objects* + + Each item in the array MUST be a [descriptor](descriptor.md). + The array MUST have the base layer at index 0. + Subsequent layers MUST then follow in stack order (i.e. from `layers[0]` to `layers[len(layers)-1]`). + The final filesystem layout MUST match the result of [applying](layer.md#applying-changesets) the layers to an empty directory. + The [ownership, mode, and other attributes](layer.md#file-attributes) of the initial empty directory are unspecified. + + Beyond the [descriptor requirements](descriptor.md#properties), the value has the following additional restrictions: + + - **`mediaType`** *string* + + This [descriptor property](descriptor.md#properties) has additional restrictions for `layers[]`. + Implementations MUST support at least the following media types: + + - [`application/vnd.oci.image.layer.v1.tar`](layer.md) + - [`application/vnd.oci.image.layer.v1.tar+gzip`](layer.md#gzip-media-types) + - [`application/vnd.oci.image.layer.nondistributable.v1.tar`](layer.md#non-distributable-layers) + - [`application/vnd.oci.image.layer.nondistributable.v1.tar+gzip`](layer.md#gzip-media-types) + + Manifests concerned with portability SHOULD use one of the above media types. + An encountered `mediaType` that is unknown to the implementation MUST be ignored. + + + Entries in this field will frequently use the `+gzip` types. + +- **`annotations`** *string-string map* + + This OPTIONAL property contains arbitrary metadata for the image manifest. + This OPTIONAL property MUST use the [annotation rules](annotations.md#rules). + + See [Pre-Defined Annotation Keys](annotations.md#pre-defined-annotation-keys). + +## Example Image Manifest + +*Example showing an image manifest:* +```json,title=Manifest&mediatype=application/vnd.oci.image.manifest.v1%2Bjson +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 7023, + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + }, + "layers": [ + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 32654, + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0" + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 16724, + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" + }, + { + "mediaType": "application/vnd.oci.artifact.layer.v1.tar+gzip", + "size": 73109, + "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" + } + ], + "annotations": { + "com.example.key1": "value1", + "com.example.key2": "value2" + } +} +``` + +## Pre-Defined Annotation Keys + +This specification defines the following annotation keys, intended for but not limited to Artifact Manifest authors: +* **org.opencontainers.artifact.created** date and time on which the artifact was built (string, date-time as defined by [RFC 3339](https://tools.ietf.org/html/rfc3339#section-5.6)). +* **org.opencontainers.artifact.authors** contact details of the people or organization responsible for the artifact (freeform string) +* **org.opencontainers.artifact.url** URL to find more information on the artifact (string) +* **org.opencontainers.artifact.documentation** URL to get documentation on the artifact (string) +* **org.opencontainers.artifact.source** URL to get source code for building the artifact (string) +* **org.opencontainers.artifact.version** version of the packaged software + * The version MAY match a label or tag in the source code repository + * version MAY be [Semantic versioning-compatible](http://semver.org/) +* **org.opencontainers.artifact.revision** Source control revision identifier for the packaged software. +* **org.opencontainers.artifact.vendor** Name of the distributing entity, organization or individual. +* **org.opencontainers.artifact.licenses** License(s) under which contained software is distributed as an [SPDX License Expression][spdx-license-expression]. +* **org.opencontainers.artifact.title** Human-readable title of the artifact (string) +* **org.opencontainers.artifact.description** Human-readable description of the software packaged in the artifact (string) + +## Setting meta-data + +Should be as simple as setting a name/value pair for a specific tag and/or digest +Setting a name/value pair for a tag will assign the meta-data to the digest currently associated with the tag. We do not currently see the need to set meta-data specific to a tag. + +Setting the git digest to a tagged artifact: + +```shell +/charts/wordpress:5.7 +{ + "name": "git.digest", + "value": "1124125" +} +``` + +Setting the contact info to a tagged artifact: + +```shell +/charts/wordpress:5.7 +{ + "name": "oci.meta-data.contact", + "value": '{ + "first": "Steve", + "last": "Lasker", + "email" "stevenlasker@hotmail.com" + }' +} +``` + +## Collections + +## Parent + +Parent elements MUST NOT have tags as they are attributions to the parent element + +Optional elements are optional as they represent metadata that has persistance. + +### Blobs + +All blobs are considered to be hard dependencies. These support ref counting, but would be deleted when the manifest is deleted. + +### Dependencies + +All dependencies are considered soft dependencies. + + +## Pushing Artifact Manifests + +Manifest validation +Each mediaType is evaluated. If the manifestType is + +## Open Questions + +Should the references collection support additional types, like loose urls \ No newline at end of file From 7d44093be4f057c00e7fe2efac45034022407398 Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Tue, 19 Jan 2021 18:38:39 -0800 Subject: [PATCH 02/10] Staged content for artifact.manifest Signed-off-by: Steve Lasker --- ...tifact-manifest-mysql-image-signature.json | 14 +- ...act-manifest-wordpress-helm-signature.json | 19 +- .../artifact-manifest-wordpress-helm.json | 38 +-- artifact-manifest/artifact-manifest.json | 24 +- artifact-manifest/artifact-manifest.md | 231 +++++++++++++++++- artifact-manifest/media/helm-chart-copy.svg | 1 + artifact-manifest/media/mysql-copy.svg | 1 + .../media/mysql-with-sigs-copy.svg | 1 + .../media/wordpress-cnab-copy.svg | 1 + artifact-manifest/mysql-image.json | 25 ++ 10 files changed, 301 insertions(+), 54 deletions(-) create mode 100644 artifact-manifest/media/helm-chart-copy.svg create mode 100644 artifact-manifest/media/mysql-copy.svg create mode 100644 artifact-manifest/media/mysql-with-sigs-copy.svg create mode 100644 artifact-manifest/media/wordpress-cnab-copy.svg create mode 100644 artifact-manifest/mysql-image.json diff --git a/artifact-manifest/artifact-manifest-mysql-image-signature.json b/artifact-manifest/artifact-manifest-mysql-image-signature.json index eb2c154..bd182e6 100644 --- a/artifact-manifest/artifact-manifest-mysql-image-signature.json +++ b/artifact-manifest/artifact-manifest-mysql-image-signature.json @@ -1,24 +1,26 @@ { "schemaVersion": 2, - "mediaType": "application/vnd.oci.artifact.collection.v1+json", + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "artifactType": "application/vnd.cncf.notary.v2", "config": { "mediaType": "application/vnd.cncf.notary.config.v2", "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", - "size": 0 + "size": 102 }, - "dependencies": [ + "blobs": [ { "mediaType": "application/vnd.cncf.notary.v2.json", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654, "reference": "registry.wabbitnetworks.io" - }, + } + ], + "dependencies": [ { "mediaType": "application/vnd.oci.image.manifest.v1", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", "size": 16724, - "reference": "/mysql:3.1" + "artifact": "mysql:3.1" } ] -} \ No newline at end of file +} diff --git a/artifact-manifest/artifact-manifest-wordpress-helm-signature.json b/artifact-manifest/artifact-manifest-wordpress-helm-signature.json index 18d959c..ee49d80 100644 --- a/artifact-manifest/artifact-manifest-wordpress-helm-signature.json +++ b/artifact-manifest/artifact-manifest-wordpress-helm-signature.json @@ -7,10 +7,6 @@ "size": 0, "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" }, - "parent": { - "mediaType": "application/vnd.oci.image.index.v1.config.json", - "reference": "/wordpress:5.7" - }, "blobs": [ { "mediaType": "application/vnd.cncf.notary.v2.json", @@ -19,16 +15,13 @@ "reference": "registry.wabbitnetworks.io" } ], - "dependencies": [ - { - "mediaType": "application/vnd.oci.image.index.v1.config.json", - "reference": "/wordpress:5.7", - "depType": "hard" - }, + "references": [ { "mediaType": "application/vnd.oci.image.index.v1.config.json", - "reference": "/mysql:3.1", - "depType": "hard" + "reference": "/wordpress:5.7" + # digest not necessary as the signature has the digest embedded in it } ] -} \ No newline at end of file +} + + diff --git a/artifact-manifest/artifact-manifest-wordpress-helm.json b/artifact-manifest/artifact-manifest-wordpress-helm.json index f0cbed8..a93db68 100644 --- a/artifact-manifest/artifact-manifest-wordpress-helm.json +++ b/artifact-manifest/artifact-manifest-wordpress-helm.json @@ -19,40 +19,18 @@ "size": 16724 } ], - "dependencies": [ - { - "mediaType": "application/vnd.oci.image.index.v1.config.json", - "reference": "/wordpress:5.7", - "depType": "soft" - }, + "references": [ { + "reference": "wordpress:5.7", "mediaType": "application/vnd.oci.image.manifest.v1.config.json", - "reference": "/mysql:v3.1", - "depType": "soft" + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510 }, { + "reference": "mysql:8", "mediaType": "application/vnd.oci.image.manifest.v1.config.json", - "refType": "manifest", - "reference": "/wordpress@sha256:swo32498791238740124809sd098s7q40129874" - }, - { - "comment": "this is a referenced helm chart", - "mediaType": "application/vnd.oci.artifact.manifest.v1.json", - "artifactType": "application/vnd.cncf.helm.v3", - "reference": "/wordpress:5.7" + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578 } - ], - "annotations": { - "org.opencontainers.artifact.created": "", - "org.opencontainers.artifact.authors": "", - "org.opencontainers.artifact.url": "opencontainers.org", - "org.opencontainers.artifact.documentation": "opencontainers.org", - "org.opencontainers.artifact.source": "https://github.com/opencontainers/artifacts", - "org.opencontainers.artifact.version": "v1.0", - "org.opencontainers.artifact.revision": "v1.1.0", - "org.opencontainers.artifact.vendor": "Open Containers Initiative", - "org.opencontainers.artifact.licenses": "MIT", - "org.opencontainers.artifact.title": "Open Containers Artifact Manifest", - "org.opencontainers.artifact.description": "A schema for defining artifacts" - } + ] } \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest.json b/artifact-manifest/artifact-manifest.json index f0ba833..a197d91 100644 --- a/artifact-manifest/artifact-manifest.json +++ b/artifact-manifest/artifact-manifest.json @@ -1,8 +1,8 @@ { "schemaVersion": 2, - "mediaType": "application/vnd.oci.artifact.collection.v1+json", + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "config": { - "mediaType": "application/vnd.oci.artifact.collection.config.v1+json", + "mediaType": "application/vnd.oci.artifact.manifest.config.v1+json", "size": 7023, "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" }, @@ -23,6 +23,11 @@ "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" } ], + "dependencies":[ + { + + } + ], "references": [ { "mediaType": "image|index|signature|helm|CNAB|...", @@ -39,5 +44,18 @@ "digest": "---", "refType": "hard|soft" } - ] + ], + "annotations": { + "org.opencontainers.artifact.created": "", + "org.opencontainers.artifact.authors": "", + "org.opencontainers.artifact.url": "opencontainers.org", + "org.opencontainers.artifact.documentation": "opencontainers.org", + "org.opencontainers.artifact.source": "https://github.com/opencontainers/artifacts", + "org.opencontainers.artifact.version": "v1.0", + "org.opencontainers.artifact.revision": "v1.1.0", + "org.opencontainers.artifact.vendor": "Open Containers Initiative", + "org.opencontainers.artifact.licenses": "MIT", + "org.opencontainers.artifact.title": "Open Containers Artifact Manifest", + "org.opencontainers.artifact.description": "A schema for defining artifacts" + } } \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index 65dfef1..f27847f 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -1,10 +1,215 @@ # OCI Artifact Manifest -The OCI artifact manifest provides a means to define a wide range of artifacts, including a chain of dependencies of related artifacts. It provides a means to define a collection of items, including blobs and linked artifacts with the information needed for reference counting, garbage collection and indexing. +The OCI artifact manifest provides a means to define a wide range of artifacts, including a chain of dependencies of related artifacts. It provides a means to define multiple collections of types, including blobs, dependent artifacts and referenced artifacts. These collections provide the information required for validating an artifact and registry management including reference counting, garbage collection and indexing. + +- The content that directly represents the artifact are persisted as blobs +- References to other artifacts, used to complete the scenario, but may not be stored within the same registry are represented as dependencies. +- References made by enhancements to the artifact, such as a Notary v2 signature or an SBoM. These references are unknown by the target artifact, but may be deleted (ref counted) when the target artifact is deleted. + +## Scenarios + +### Copy Container Images + +![mysql image copy](./media/mysql-copy.svg) + +Copying a container from a public registry to a private registry would involve `docker pull`, `docker tag` and `docker push` + +```bash +docker pull mysql:8 +docker tag mysql:8 registry.acmerockets.io/base-artifacts/mysql:8 +docker push registry.acmerockets.io/base-artifacts/mysql:8 +``` + +The above commands account for the image manifest and the associated layers. Note the directionality of the manifest to layers references. A manifest declares the layers that must be accounted for before a manifest may be considered valid within a registry. In addition, most registries implement layer de-duping and reference counting to avoid maintaining multiple copies of the same layers. + +```json +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 7097, + "digest": "sha256:c8562eaf9d81c779cbfc318d6e01b8e6f86907f1d41233268a2ed83b2f34e748" + }, + "layers": [ + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 27108069, + "digest": "sha256:a076a628af6f7dcabc536bee373c0d9b48d9f0516788e64080c4e841746e6ce6" + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 1741, + "digest": "sha256:f6c208f3f991dcbc417fed8efde391f887c0551d77ed0c1a125fd28f4841e1cc" + } + ] +} +``` + +### Container Image, with Signatures + +![mysql image copy](./media/mysql-with-sigs-copy.svg) + +In the above example, the layers have been removed for clarity. In this scenario, Notary v2 signatures have been added. Note the directionality of the Notary v2 signatures references. The `mysql:8` image has no reference to the signatures. The signatures may be added to existing artifacts. + +From a user experience perspective, copying a container from a public registry to a private registry would likely be expected to copy the signatures alongside the artifact they've signed. + +The `oci.artifact.manifest` supports the Notary v2 requirements, including: + +- support for additive signatures, assuring the target manifest digest and tag do not change +- support for multiple signatures. In the above scenario, `mysql` signed the original image. As `mysql` was copied to Docker Hub, an additional `docker signature` was added, providing a certified content attestation. Once the image copy to ACME Rockets is completed, an additional `acmerockets signature` is added providing assurance the `mysql:8` image was security scanned and verified applicable to the ACME Rockets environment. + +From a user experience, the signature artifacts have no unique value beyond the artifact they represent, therefore they would be persisted to a registry in a form by which they are known to copy with the artifact, and be deleted when the artifact they are associated with is deleted. + +To support hard references, an additional dependencies collection is added to a new `application/vnd.oci.artifact.manifest.v1+json` schema. The `dependencies` collection declares the artifact the signature is dependent upon. Similar to pypi packages, the validation of dependencies are deferred. If the dependent artifacts are found, they are valid. Depending on the validation options, a signature may exist without its dependent artifact. + +```json +{ + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 102 + }, + "blobs": [ + { + "mediaType": "application/vnd.cncf.notary.v2.json", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654, + "reference": "registry.wabbitnetworks.io" + } + ], + "dependencies": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724, + "artifact": "mysql:3.1" + } + ] +} +``` + +#### OCI-Registry CLI + +To copy the above image and the associated signatures, a new `oci-reg` cli is proposed. + +The following command would copy the `mysql:8` image from docker hub to the acmerockets registry. The CLI could be run within the source or target cloud. + +```bash +oci-reg copy \ + --source hub.docker.io/mysql:8 \ + --target registry.acme-rockets.io/base-artifacts/mysql:8 +``` + +The `oci-reg copy` command would: + +- assure the manifest and layer/blob digests remain the same +- copy any artifacts that are dependent on the source artifact-manifest, persisting them in the target registry. + +### Reference Artifacts + +There are a set of artifact types that declare references to other artifacts that may, or may not be stored in the same registry. The reference is important to note, indicating copying to be capable between environments, as well as generalized validation scenarios. + +#### Helm Reference + +![mysql image copy](./media/helm-chart-copy.svg) + +In the above scenario, a helm chart is copied from a public registry to the ACME Rockets registry. The `wordpress-chart:v5` is represented as an `application/vnd.oci.artifact.manifest.v1+json`. In addition to the Notary v2 signatures declaring a dependency on the `wordpress:v5` image, the `mysql:8` image, the `wordpress-chart:v5` helm chart can also represent signed content. The new references collection within the `oci.artifact.manifest` schema provides a means to identify the images the helm chart references. + +```json +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.helm.v3", + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "size": 0, + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + }, + "blobs": [ + { + "mediaType": "application/vnd.cncf.helm.chart.v1.tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + }, + { + "mediaType": "application/vnd.cncf.helm.values.v1.yaml", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [ + { + "reference": "wordpress:5.7", + "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510 + }, + { + "reference": "mysql:8", + "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578 + } + ] +} +``` + +#### CNAB Reference + +A CNAB is yet another reference artifact. While the current CNAB spec incorporates the helm-cli ahd helm chart within an invocation image, the `artifact.manifest` provides more natural package management experiences where the references can be resolved based on the users intent. + +![mysql image copy](./media/wordpress-cnab-copy.svg) + +Similar to the Helm example, a CNAB is copied from a public registry to the ACME Rockets registry. The `wordpress-cnab:v5` CNAB declares references to an invocation image that includes the `helm-cli`. This provides an environment to run `helm install`. The CNAB includes an additional refernece to `wordpress-chart:v5`. The chart includes references to the `wordpress:v5` and `mysql:8` images. As the `oci-reg copy` command is executed, the graph of references may be expanded. As the copy proceeds, only those artifacts that don't already exist in the target registry are required to be copied. The CNAB and Helm `artifact.manifest` may declare how strict they wish to couple their references to **stable tags** or **unique digests** + +```json +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.cnab.v1", + "config": { + "mediaType": "application/vnd.cncf.cnab.config.v1+json", + "size": 0, + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + }, + "blobs": [ + { + "mediaType": "application/vnd.cncf.cnab.v1.tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + }, + { + "mediaType": "application/vnd.cncf.cnab.params.v1.json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [ + { + "reference": "wordpress-chart:v5", + "mediaType": "application/vnd.cncf.helm.v1.config.json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510 + }, + { + "reference": "helm-cli:3", + "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578 + } + ] +} +``` + +---- +# ADDITIONAL EDITING REQUIRED BEYOND THIS POINT +---- ## Goals of Artifact Manifest -### Bi-directional Hierarchal Support +### Bi-directional Hierarchies The OCI Distribution-spec 1.0 supports tops down hierarchies for tracking a manifest, a config object, and a collection of layers. This works well for immutable artifacts that are individually pushed to a registry. As an artifact is pushed, a manifest and digest of the manifest and it's referenced layers are computed. @@ -32,6 +237,28 @@ Distribution-spec APIs will provide standard delete operations, including option - deleting the mysql image should warn if referenced by helm charts - deleting the wordpress chart removes a ref count to the mysql image, for mysql deletion +## Link Types + +Artifact manifest will support bi-directional references enabling additional artifacts to be added to a registry after an artifact was persisted. + +As artifacts reference others, hard and soft references will be supported, enabling artifacts to be individually deleted, or an extent of the dependency graph to be removed. + +### Notes +Artifact-manifest has 3 collections +```json +{ + blobs:{}, physical content that is always associated with the object - just like oci image + dependencies:{} - can be loosely defined (cnab, helm) + references:{} - always copied (signature) +} +``` + +# copy the helm chart, the images (if found) and all signatures found +registry copy wordpress-helm:v1 + +# copy with limited references (signatures but not source) +registry copy wordpress-helm:v1 --with-dependencies --filter-references "+notary.v2" "-gpl-source.v2" + ## *Image Manifest* Property Descriptions - **`schemaVersion`** *int* diff --git a/artifact-manifest/media/helm-chart-copy.svg b/artifact-manifest/media/helm-chart-copy.svg new file mode 100644 index 0000000..beb0d32 --- /dev/null +++ b/artifact-manifest/media/helm-chart-copy.svg @@ -0,0 +1 @@ +Artifact Copymysql:8MySQL signatureDockerCommunity signatureAcme Rocketssignaturewordpress:v5DockerCommunity signaturewordpress-chart:v5HelmCommunity signaturemysql:8MySQL signatureDockerCommunity signaturewordpress:v5DockerCommunity signaturewordpress-chart:v5HelmCommunity signatureACME RocketsPublic Registry \ No newline at end of file diff --git a/artifact-manifest/media/mysql-copy.svg b/artifact-manifest/media/mysql-copy.svg new file mode 100644 index 0000000..26454a2 --- /dev/null +++ b/artifact-manifest/media/mysql-copy.svg @@ -0,0 +1 @@ +Artifact CopyACME Rocketsmysql:8mysql:8layer1layer2layer1layer2 \ No newline at end of file diff --git a/artifact-manifest/media/mysql-with-sigs-copy.svg b/artifact-manifest/media/mysql-with-sigs-copy.svg new file mode 100644 index 0000000..0865959 --- /dev/null +++ b/artifact-manifest/media/mysql-with-sigs-copy.svg @@ -0,0 +1 @@ +Artifact CopyACME Rocketsmysql:8MySQL signatureDockerCommunity signatureAcme Rockets signaturemysql:8MySQL signatureDockerCommunity signature \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-cnab-copy.svg b/artifact-manifest/media/wordpress-cnab-copy.svg new file mode 100644 index 0000000..32fd61d --- /dev/null +++ b/artifact-manifest/media/wordpress-cnab-copy.svg @@ -0,0 +1 @@ +Public RegistryArtifact Copymysql:8MySQL signatureDockerCommunity signatureAcme Rocketssignaturewordpress:v5DockerCommunity signaturewordpress-chart:v5HelmCommunity signaturewordpress-cnab:v5HelmCommunity signaturehelm-cli:v3HelmCommunity signaturemysql:8MySQL signatureDockerCommunity signaturewordpress:v5DockerCommunity signaturewordpress-chart:v5HelmCommunity signaturewordpress-cnab:v5HelmCommunity signaturehelm-cli:v3HelmCommunity signatureACME Rockets \ No newline at end of file diff --git a/artifact-manifest/mysql-image.json b/artifact-manifest/mysql-image.json new file mode 100644 index 0000000..6a008a6 --- /dev/null +++ b/artifact-manifest/mysql-image.json @@ -0,0 +1,25 @@ +{ + "schemaVersion": 2, + "config": { + "mediaType": "application/vnd.oci.image.config.v1+json", + "size": 7097, + "digest": "sha256:c8562eaf9d81c779cbfc318d6e01b8e6f86907f1d41233268a2ed83b2f34e748" + }, + "layers": [ + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 27108069, + "digest": "sha256:a076a628af6f7dcabc536bee373c0d9b48d9f0516788e64080c4e841746e6ce6" + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 1741, + "digest": "sha256:f6c208f3f991dcbc417fed8efde391f887c0551d77ed0c1a125fd28f4841e1cc" + }, + { + "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", + "size": 4178395, + "digest": "sha256:88a9455a9165654c855c2614bc1dc1f574e7d9265ecb39a3211e0bfc55926729" + } + ] +} \ No newline at end of file From 0e2c60746d438633b7cac20f325ffe4b44b6111b Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Wed, 20 Jan 2021 19:01:42 -0800 Subject: [PATCH 03/10] Add artifact types Signed-off-by: Steve Lasker --- .../artifact-manifest-wordpress-cnab..json | 36 +++++++++++++++ artifact-manifest/artifact-manifest.md | 46 ++++++++++++++++--- artifact-manifest/media/mysql-copy.svg | 2 +- .../media/mysql-with-sigs-copy.svg | 2 +- .../media/notaryv2-signature.svg | 1 + .../media/wordpress-cnab-copy.svg | 2 +- artifact-manifest/media/wordpress-cnab.svg | 1 + .../media/wordpress-helm-chart-copy.svg | 1 + .../media/wordpress-helm-chart.svg | 1 + .../media/wordpress-image-layers-sig.svg | 1 + .../media/wordpress-image-layers.svg | 1 + artifact-manifest/media/wordpress-image.svg | 1 + 12 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 artifact-manifest/media/notaryv2-signature.svg create mode 100644 artifact-manifest/media/wordpress-cnab.svg create mode 100644 artifact-manifest/media/wordpress-helm-chart-copy.svg create mode 100644 artifact-manifest/media/wordpress-helm-chart.svg create mode 100644 artifact-manifest/media/wordpress-image-layers-sig.svg create mode 100644 artifact-manifest/media/wordpress-image-layers.svg create mode 100644 artifact-manifest/media/wordpress-image.svg diff --git a/artifact-manifest/artifact-manifest-wordpress-cnab..json b/artifact-manifest/artifact-manifest-wordpress-cnab..json index e69de29..4b618d4 100644 --- a/artifact-manifest/artifact-manifest-wordpress-cnab..json +++ b/artifact-manifest/artifact-manifest-wordpress-cnab..json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.cnab.v1", + "config": { + "mediaType": "application/vnd.cncf.cnab.config.v1+json", + "size": 0, + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + }, + "blobs": [ + { + "mediaType": "application/vnd.cncf.cnab.v1.tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + }, + { + "mediaType": "application/vnd.cncf.cnab.params.v1.json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [ + { + "reference": "wordpress-chart:v5", + "mediaType": "application/vnd.cncf.helm.v1.config.json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510 + }, + { + "reference": "helm-cli:3", + "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578 + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index f27847f..900e31c 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -2,15 +2,47 @@ The OCI artifact manifest provides a means to define a wide range of artifacts, including a chain of dependencies of related artifacts. It provides a means to define multiple collections of types, including blobs, dependent artifacts and referenced artifacts. These collections provide the information required for validating an artifact and registry management including reference counting, garbage collection and indexing. -- The content that directly represents the artifact are persisted as blobs -- References to other artifacts, used to complete the scenario, but may not be stored within the same registry are represented as dependencies. -- References made by enhancements to the artifact, such as a Notary v2 signature or an SBoM. These references are unknown by the target artifact, but may be deleted (ref counted) when the target artifact is deleted. +OCI Artifact Manifests provide the following types of references: -## Scenarios +1. Content that represents the artifact, persisted as blobs. These are analogues to layers from the OCI Image manifest and Config objects. Layers are renamed blobs as they represent a generic collection of content, as opposed to an ordered layered collection as defined by OCI Image Manifest. An artifact may treat them as ordered, but it is not required. +1. Loose references to other artifacts, used to complete a scenario, but may not be stored within the same repository or registry. These references are defined by the source artifact and known at the time of upload to a registry, such as a Helm chart that references other images. These references are included in the manifest and computed in the digest of the manifest. +1. References made by enhancements to the artifact, such as a Notary v2 signature or an SBoM. These references are unknown by the original artifact as they are added at a later time. A registry would need to index these references as registry apis would request all content related to the source artifact. + +## Supported Artifact Types + +Artifact Manifest is intended to support the following scenarios: + +### OCI Image + +An OCI Image is based on the oci-image-manifest. It's shown as a comparison to the examples below. + +![OCI Image](media/wordpress-image-layers.svg) + +### Notary v2 Signature Persistance + +A Notary v2 signature would persist as a manifest with a config object and a signature, persisted as a blobs. + +![notary v2 signature](media/notaryv2-signature.svg) + +The Notary v2 signature would reference an artifact, such as the `wordpress:v5` image above. Notice the directionality of the references. One or more signatures may be added to a registry after the image was persisted. While an image knows of it's layers, and a Notary v2 signature knows of its config and blob, the Notary v2 signature has a reference to the artifact its signing. + +![wordpress image with layers](media/wordpress-image-layers-sig.svg) + +### Helm Charts & CNAB + +A Helm chart can represent the images it references within the chart. These references are loose references as they may be persisted in different registries, or may change as a values file is updated. However, the chart may also be persisted together as a collection of artifacts in a registry. + +![Wordpress Helm Chart](media/wordpress-helm-chart.svg) + +A CNAB may also be persisted as a CNAB document that contains the configuration information, along with its invocation image. Notice the reference to the `helm-cli:v3` is a hard reference. This allows the helm-cli to be deleted *(ref-count -1)* when the parent cnab is deleted. As the CNAB references a Helm chart, the `wordpress-chart:v5` is also represented as a loose reference, which then references the images required to instance wordpress. + +![Wordpress CNAB](media/wordpress-cnab.svg) + +## Supported Scenarios ### Copy Container Images -![mysql image copy](./media/mysql-copy.svg) +![mysql image copy](media/mysql-copy.svg) Copying a container from a public registry to a private registry would involve `docker pull`, `docker tag` and `docker push` @@ -84,7 +116,7 @@ To support hard references, an additional dependencies collection is added to a "mediaType": "application/vnd.oci.image.manifest.v1", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", "size": 16724, - "artifact": "mysql:3.1" + "artifact": "mysql:8" } ] } @@ -113,7 +145,7 @@ There are a set of artifact types that declare references to other artifacts tha #### Helm Reference -![mysql image copy](./media/helm-chart-copy.svg) +![mysql image copy](./media/wordpress-helm-chart-copy.svg) In the above scenario, a helm chart is copied from a public registry to the ACME Rockets registry. The `wordpress-chart:v5` is represented as an `application/vnd.oci.artifact.manifest.v1+json`. In addition to the Notary v2 signatures declaring a dependency on the `wordpress:v5` image, the `mysql:8` image, the `wordpress-chart:v5` helm chart can also represent signed content. The new references collection within the `oci.artifact.manifest` schema provides a means to identify the images the helm chart references. diff --git a/artifact-manifest/media/mysql-copy.svg b/artifact-manifest/media/mysql-copy.svg index 26454a2..2b32435 100644 --- a/artifact-manifest/media/mysql-copy.svg +++ b/artifact-manifest/media/mysql-copy.svg @@ -1 +1 @@ -Artifact CopyACME Rocketsmysql:8mysql:8layer1layer2layer1layer2 \ No newline at end of file +ACME RocketsArtifact Importmysql:8Layer1Layer2mysql:8Artifact ImportLayer1Layer2 \ No newline at end of file diff --git a/artifact-manifest/media/mysql-with-sigs-copy.svg b/artifact-manifest/media/mysql-with-sigs-copy.svg index 0865959..295ba78 100644 --- a/artifact-manifest/media/mysql-with-sigs-copy.svg +++ b/artifact-manifest/media/mysql-with-sigs-copy.svg @@ -1 +1 @@ -Artifact CopyACME Rocketsmysql:8MySQL signatureDockerCommunity signatureAcme Rockets signaturemysql:8MySQL signatureDockerCommunity signature \ No newline at end of file +mysql:8MySQL signatureDocker community signatureACME Rockets signatureLayer1Layer2ACME Rocketsmysql:8MySQL signatureDocker community signatureACME Rockets signatureArtifact ImportLayer1Layer2 \ No newline at end of file diff --git a/artifact-manifest/media/notaryv2-signature.svg b/artifact-manifest/media/notaryv2-signature.svg new file mode 100644 index 0000000..7fd5cb8 --- /dev/null +++ b/artifact-manifest/media/notaryv2-signature.svg @@ -0,0 +1 @@ +notary v2 signatureconfig-blobsignature-blob \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-cnab-copy.svg b/artifact-manifest/media/wordpress-cnab-copy.svg index 32fd61d..631a2b9 100644 --- a/artifact-manifest/media/wordpress-cnab-copy.svg +++ b/artifact-manifest/media/wordpress-cnab-copy.svg @@ -1 +1 @@ -Public RegistryArtifact Copymysql:8MySQL signatureDockerCommunity signatureAcme Rocketssignaturewordpress:v5DockerCommunity signaturewordpress-chart:v5HelmCommunity signaturewordpress-cnab:v5HelmCommunity signaturehelm-cli:v3HelmCommunity signaturemysql:8MySQL signatureDockerCommunity signaturewordpress:v5DockerCommunity signaturewordpress-chart:v5HelmCommunity signaturewordpress-cnab:v5HelmCommunity signaturehelm-cli:v3HelmCommunity signatureACME Rockets \ No newline at end of file +ACME Rocketswordpress:v5Docker community signaturehelm-cli:v3Helm community signaturewordpress-chart:v5Helm community signaturewordpress-cnab:v5Helm community signaturePublic Registrymysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturehelm-cli:v3Helm community signaturewordpress-chart:v5Helm community signaturewordpress-cnab:v5Helm community signatureArtifact Importmysql:8MySQL signatureDocker community signatureACME Rockets signature \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-cnab.svg b/artifact-manifest/media/wordpress-cnab.svg new file mode 100644 index 0000000..7330757 --- /dev/null +++ b/artifact-manifest/media/wordpress-cnab.svg @@ -0,0 +1 @@ +mysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturehelm-cli:v3Helm community signaturewordpress-chart:v5Helm community signaturewordpress-cnab:v5Helm community signature \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-helm-chart-copy.svg b/artifact-manifest/media/wordpress-helm-chart-copy.svg new file mode 100644 index 0000000..965739e --- /dev/null +++ b/artifact-manifest/media/wordpress-helm-chart-copy.svg @@ -0,0 +1 @@ +ACME Rocketsmysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturewordpress-chart:v5Helm community signaturePublic Registrymysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturewordpress-chart:v5Helm community signatureArtifact Import \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-helm-chart.svg b/artifact-manifest/media/wordpress-helm-chart.svg new file mode 100644 index 0000000..591ca72 --- /dev/null +++ b/artifact-manifest/media/wordpress-helm-chart.svg @@ -0,0 +1 @@ +mysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturewordpress-chart:v5Helm community signature \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-image-layers-sig.svg b/artifact-manifest/media/wordpress-image-layers-sig.svg new file mode 100644 index 0000000..8ff4365 --- /dev/null +++ b/artifact-manifest/media/wordpress-image-layers-sig.svg @@ -0,0 +1 @@ +wordpress:v5Docker community signatureLayer1Layer2 \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-image-layers.svg b/artifact-manifest/media/wordpress-image-layers.svg new file mode 100644 index 0000000..000e076 --- /dev/null +++ b/artifact-manifest/media/wordpress-image-layers.svg @@ -0,0 +1 @@ +wordpress:v5Layer1Layer2 \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-image.svg b/artifact-manifest/media/wordpress-image.svg new file mode 100644 index 0000000..cf79d4e --- /dev/null +++ b/artifact-manifest/media/wordpress-image.svg @@ -0,0 +1 @@ +wordpress:v5Docker community signature \ No newline at end of file From d73291fca9a3256b683bbd78cf94e96f112aabf9 Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Thu, 21 Jan 2021 16:43:50 -0800 Subject: [PATCH 04/10] Repo listing examples --- artifact-manifest/artifact-manifest.md | 50 +++++++++++++++---- .../repo-listing-attributed-expanded.svg | 1 + .../media/repo-listing-attributed.svg | 1 + artifact-manifest/media/repo-listing-flat.svg | 1 + .../media/wordpress-image-layers-sig.svg | 2 +- 5 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 artifact-manifest/media/repo-listing-attributed-expanded.svg create mode 100644 artifact-manifest/media/repo-listing-attributed.svg create mode 100644 artifact-manifest/media/repo-listing-flat.svg diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index 900e31c..8e2adba 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -1,16 +1,24 @@ # OCI Artifact Manifest -The OCI artifact manifest provides a means to define a wide range of artifacts, including a chain of dependencies of related artifacts. It provides a means to define multiple collections of types, including blobs, dependent artifacts and referenced artifacts. These collections provide the information required for validating an artifact and registry management including reference counting, garbage collection and indexing. +The OCI artifact manifest provides a means to define a wide range of artifacts, including a chain of dependencies of related artifacts. It provides a means to define multiple collections of types, including blobs, dependent artifacts and referenced artifacts. + +These collections provide the information required for: + +- validating an artifact, +- registry management and visualizations +- deletion management, including reference counting, garbage collection & +- indexing for artifact discover, along with it's related content +- copying within & across registries OCI Artifact Manifests provide the following types of references: -1. Content that represents the artifact, persisted as blobs. These are analogues to layers from the OCI Image manifest and Config objects. Layers are renamed blobs as they represent a generic collection of content, as opposed to an ordered layered collection as defined by OCI Image Manifest. An artifact may treat them as ordered, but it is not required. -1. Loose references to other artifacts, used to complete a scenario, but may not be stored within the same repository or registry. These references are defined by the source artifact and known at the time of upload to a registry, such as a Helm chart that references other images. These references are included in the manifest and computed in the digest of the manifest. -1. References made by enhancements to the artifact, such as a Notary v2 signature or an SBoM. These references are unknown by the original artifact as they are added at a later time. A registry would need to index these references as registry apis would request all content related to the source artifact. +1. **Blobs:** Content that represents the artifact. These are analogues to layers from the OCI Image manifest and Config objects. Layers are renamed blobs as they represent a generic collection of content, as opposed to an ordered layered collection as defined by OCI Image Manifest. An artifact may treat them as ordered, but it is not required. +1. **References** to other artifacts, used to complete a scenario, but may not be stored within the same repository or registry. These references are defined by the source artifact and known at the time of upload to a registry, such as a Helm chart that references other images. These references are included in the manifest and computed in the digest of the manifest. +1. **Dependencies** on other artifacts that enhance the content, such as a Notary v2 signature or an SBoM. These dependencies are *unknown* by the original artifact as they are added at a later time. A registry would need to index these references as registry apis would request all content related to the source artifact. ## Supported Artifact Types -Artifact Manifest is intended to support the following scenarios: +Artifact manifest is intended to support the following artifact types: ### OCI Image @@ -20,26 +28,50 @@ An OCI Image is based on the oci-image-manifest. It's shown as a comparison to t ### Notary v2 Signature Persistance -A Notary v2 signature would persist as a manifest with a config object and a signature, persisted as a blobs. +A Notary v2 signature would persist as a manifest with a config object and a signature, persisted as a blob. However, the signature has no value unto itself. A signature is applied to a given artifact. It's said to be dependent upon another artifact to be complete. ![notary v2 signature](media/notaryv2-signature.svg) -The Notary v2 signature would reference an artifact, such as the `wordpress:v5` image above. Notice the directionality of the references. One or more signatures may be added to a registry after the image was persisted. While an image knows of it's layers, and a Notary v2 signature knows of its config and blob, the Notary v2 signature has a reference to the artifact its signing. +The Notary v2 signature would reference an artifact, such as the `wordpress:v5` image above. Notice the directionality of the references. One or more signatures may be added to a registry after the image was persisted. While an image knows of it's layers, and a Notary v2 signature knows of its config and blob, the Notary v2 signature declares a dependency to the artifact it's signing. The visualization indicates the references through solid lines as these reference types are said to be hard references. Just as the layers of an OCI Image are deleted (*ref-counted -1*), the blobs of a signature are deleted (*ref-counted -1*) when the signature is deleted. Likewise, when an artifact is deleted, the signature would be deleted (*ref-counted -1*) as the signatures have no value without the artifact they are signing. ![wordpress image with layers](media/wordpress-image-layers-sig.svg) ### Helm Charts & CNAB -A Helm chart can represent the images it references within the chart. These references are loose references as they may be persisted in different registries, or may change as a values file is updated. However, the chart may also be persisted together as a collection of artifacts in a registry. +A Helm chart can represent the images it references within the chart. These references are loose references as they may be persisted in different registries, or may change as a values file is updated. However, the chart may also be persisted together as a collection of artifacts in a registry. The lines are dotted to represent the loose reference. Deleting the `wordpress-chart:v5` may, or may not delete the images as the images have value unto themselves. ![Wordpress Helm Chart](media/wordpress-helm-chart.svg) -A CNAB may also be persisted as a CNAB document that contains the configuration information, along with its invocation image. Notice the reference to the `helm-cli:v3` is a hard reference. This allows the helm-cli to be deleted *(ref-count -1)* when the parent cnab is deleted. As the CNAB references a Helm chart, the `wordpress-chart:v5` is also represented as a loose reference, which then references the images required to instance wordpress. +A CNAB may also be persisted with configuration information, along with a reference to its invocation image. The reference to the `helm-cli:v3` is solid line/hard reference. This allows the helm-cli to be deleted *(ref-count -1)* when the parent cnab is deleted. As the CNAB references a Helm chart, the `wordpress-chart:v5` is also represented as a loose reference as the helm chart and referenced images have value unto themselves. ![Wordpress CNAB](media/wordpress-cnab.svg) ## Supported Scenarios +The main scenarios include: + +1. Discovery of content within a registry for content listing through CLI and visualizations. +1. Copying within and across registries. +1. Deletion management, providing information to de-dupe content with reference counting. +1. Support enhancing information related to existing content. Such as adding a Notary v2 signature or SBoM. +1. Validation, with required and optional references. + +### Content Discovery + +Registries today support a flat list of content within designated repositories. A container image, multi-arch container image, Helm Chart, CNAB, Singularity, WASM and other OCI Artifact types can be listed based on their `manifest.config.mediaType` + +![flat listing of OCI artifacts](media/repo-listing-flat.svg) + +In the above example, all the artifacts are displayed without relation to each other. The layers of the `:v5` are also displayed as an example of data that is already hidden. + +![flat listing of OCI artifacts](media/repo-listing-attributed.svg) + +In the above example, the Notary v2 signature, an SBoM and collection of attributes are displayed as directly associated with their primary artifact. + +![flat listing of OCI artifacts](media/repo-listing-attributed-expanded.svg) + +In the above case, the graph of references can be expanded showing the references across repositories. This visualization demonstrates the hierarchy known by the registry, based on the artifact-manifest. While an artifact icon is displayed, based on the `manifest.config.mediaType`, the registry need not know any of the artifact specific details to track this data. Registries would not need to parse the Helm Chart, the CNAB. Each artifact author will lift data elements for the objects they wish to reference in a registry. + ### Copy Container Images ![mysql image copy](media/mysql-copy.svg) diff --git a/artifact-manifest/media/repo-listing-attributed-expanded.svg b/artifact-manifest/media/repo-listing-attributed-expanded.svg new file mode 100644 index 0000000..3e4589a --- /dev/null +++ b/artifact-manifest/media/repo-listing-attributed-expanded.svg @@ -0,0 +1 @@ +v5………………cnab-v5wordpress-chart:v5SBoMSBoMSBoMhelm-cli:v3SBoMwordpress:v5mysql:8 \ No newline at end of file diff --git a/artifact-manifest/media/repo-listing-attributed.svg b/artifact-manifest/media/repo-listing-attributed.svg new file mode 100644 index 0000000..7df6b37 --- /dev/null +++ b/artifact-manifest/media/repo-listing-attributed.svg @@ -0,0 +1 @@ +v5………cnab-v5chart-v5SBoMSBoMSBoM \ No newline at end of file diff --git a/artifact-manifest/media/repo-listing-flat.svg b/artifact-manifest/media/repo-listing-flat.svg new file mode 100644 index 0000000..3841557 --- /dev/null +++ b/artifact-manifest/media/repo-listing-flat.svg @@ -0,0 +1 @@ +v59834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0SBoM…………………Layer1Layer2b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a5373c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a6b5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a82cnab-v5chart-v5 \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-image-layers-sig.svg b/artifact-manifest/media/wordpress-image-layers-sig.svg index 8ff4365..51d6f6e 100644 --- a/artifact-manifest/media/wordpress-image-layers-sig.svg +++ b/artifact-manifest/media/wordpress-image-layers-sig.svg @@ -1 +1 @@ -wordpress:v5Docker community signatureLayer1Layer2 \ No newline at end of file +wordpress:v5Docker community signatureLayer1Layer2ACME Rockets signature \ No newline at end of file From 25b008c6304bead2a4195c3ee2348f05d6d9ca5c Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Mon, 25 Jan 2021 08:33:25 -0800 Subject: [PATCH 05/10] Cleanup OCI Artifacts descriptions Signed-off-by: Steve Lasker --- artifact-manifest/artifact-manifest.md | 362 ++++++++++++------------- 1 file changed, 169 insertions(+), 193 deletions(-) diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index 8e2adba..859635f 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -1,20 +1,80 @@ # OCI Artifact Manifest -The OCI artifact manifest provides a means to define a wide range of artifacts, including a chain of dependencies of related artifacts. It provides a means to define multiple collections of types, including blobs, dependent artifacts and referenced artifacts. +The OCI artifact manifest provides a means to define a wide range of artifacts, including a chain of dependencies of related artifacts. It provides a means to define multiple collections of types, including blobs, dependent artifacts and referenced artifacts. These collections provide the information required for: -- validating an artifact, +- validating an artifact - registry management and visualizations -- deletion management, including reference counting, garbage collection & +- deletion management, including reference counting and garbage collection - indexing for artifact discover, along with it's related content - copying within & across registries -OCI Artifact Manifests provide the following types of references: +## Design Points + +OCI Artifact Manifest has the following design points: + +### Artifacts Move Within & Between Registries + +Artifact will move from dev, through test, to staging. They'll continue movement to a distribution point or deployment. Throughout the process an artifact may move to other repositories within a registry or across different registries. + +Content movement within a registry: + +```bash +registry.acme-rockets.io\ + dev\ + web-image:v1 + web-image:v2 + web-image:v3 + web-deploy:v1 + web-deploy:v2 + web-deploy:v3 + staging\ + web-image:v2 + web-image:v3 + web-deploy:v2 + web-deploy:v3 + prod\ + web-image:v2 + web-deploy:v2 +``` + +Content movement across registries: + +```bash +dev-registry.acme-rockets.io\ + web-image:v1 + web-image:v2 + web-image:v3 + web-deploy:v1 + web-deploy:v2 + web-deploy:v3 +``` + +```bash +prod-registry.acme-rockets.io\ + web-image:v2 + web-deploy:v2 +``` + +Content published for public consumption + +```bash +products.wabbit-networks.io\ + net-monitor:v1 + net-monitor:v2 + net-monitor-charts:v1 +``` + +To support artifact movement, the content that constitutes an artifact to individually represent itself must be maintained within the same registry. For example, the layers of an container image, or the signature blob of a Notary v2 signature artifact. + +### Deferred Resolution -1. **Blobs:** Content that represents the artifact. These are analogues to layers from the OCI Image manifest and Config objects. Layers are renamed blobs as they represent a generic collection of content, as opposed to an ordered layered collection as defined by OCI Image Manifest. An artifact may treat them as ordered, but it is not required. -1. **References** to other artifacts, used to complete a scenario, but may not be stored within the same repository or registry. These references are defined by the source artifact and known at the time of upload to a registry, such as a Helm chart that references other images. These references are included in the manifest and computed in the digest of the manifest. -1. **Dependencies** on other artifacts that enhance the content, such as a Notary v2 signature or an SBoM. These dependencies are *unknown* by the original artifact as they are added at a later time. A registry would need to index these references as registry apis would request all content related to the source artifact. +To support artifact movement to various registry and namespace structures, the registry and path must not be embedded within the artifact definition. Client CLIs and configurations will provide default locations and mappings for where to find the referenced content. + +Artifacts that reference other artifacts must include an OCI Artifact Descriptor which includes the `manifest type`, `digest`, `size` and `repo:tag` of the artifact, however it will defer resolution of the reference to client tools that MAY reconstitute the references from multiple repositories and/or registries. + +Clients MAY choose to bind to specific digests, assuring they are testing and using the exact graph initially specified. Or, clients may choose to float to a newer version of a tag, benefiting from patches. In all cases, a Notary v2 signature may be used to assure the artifacts are true to their initial ownership and authors. ## Supported Artifact Types @@ -76,15 +136,15 @@ In the above case, the graph of references can be expanded showing the reference ![mysql image copy](media/mysql-copy.svg) -Copying a container from a public registry to a private registry would involve `docker pull`, `docker tag` and `docker push` +As a reference, copying a container from a public registry to a private registry would involve `docker pull`, `docker tag` and `docker push` ```bash docker pull mysql:8 -docker tag mysql:8 registry.acmerockets.io/base-artifacts/mysql:8 -docker push registry.acmerockets.io/base-artifacts/mysql:8 +docker tag mysql:8 registry.acme-rockets.io/base-artifacts/mysql:8 +docker push registry.acme-rockets.io/base-artifacts/mysql:8 ``` -The above commands account for the image manifest and the associated layers. Note the directionality of the manifest to layers references. A manifest declares the layers that must be accounted for before a manifest may be considered valid within a registry. In addition, most registries implement layer de-duping and reference counting to avoid maintaining multiple copies of the same layers. +The above commands account for the image manifest and the associated layers. Note the directionality of the manifest `-->` layers references. A manifest declares the layers that must be accounted for before a manifest may be considered valid within a registry. In addition, most registries implement layer de-duping and reference counting to avoid maintaining multiple copies of the same layers. ```json { @@ -113,19 +173,21 @@ The above commands account for the image manifest and the associated layers. Not ![mysql image copy](./media/mysql-with-sigs-copy.svg) -In the above example, the layers have been removed for clarity. In this scenario, Notary v2 signatures have been added. Note the directionality of the Notary v2 signatures references. The `mysql:8` image has no reference to the signatures. The signatures may be added to existing artifacts. +In this scenario, Notary v2 signatures have been added. Note the directionality of the Notary v2 signatures references. The `mysql:8` image has no reference to the signatures. The signatures may be added to existing artifacts. The signatures declare a reference `-->` to the `mysql:8` image. This assure the `mysql:8` image tag and digest need not change to support signatures added throughout the secured supply chain. From a user experience perspective, copying a container from a public registry to a private registry would likely be expected to copy the signatures alongside the artifact they've signed. The `oci.artifact.manifest` supports the Notary v2 requirements, including: - support for additive signatures, assuring the target manifest digest and tag do not change -- support for multiple signatures. In the above scenario, `mysql` signed the original image. As `mysql` was copied to Docker Hub, an additional `docker signature` was added, providing a certified content attestation. Once the image copy to ACME Rockets is completed, an additional `acmerockets signature` is added providing assurance the `mysql:8` image was security scanned and verified applicable to the ACME Rockets environment. +- support for multiple signatures. In the above scenario, `mysql` signed the original image. As `mysql` was copied to Docker Hub, an additional `docker community signature` was added, providing certified content attestation. Once the image copy to ACME Rockets is completed, an additional `acme-rockets signature` is added providing assurance the `mysql:8` image was security scanned and verified it's applicable to the ACME Rockets environment. From a user experience, the signature artifacts have no unique value beyond the artifact they represent, therefore they would be persisted to a registry in a form by which they are known to copy with the artifact, and be deleted when the artifact they are associated with is deleted. To support hard references, an additional dependencies collection is added to a new `application/vnd.oci.artifact.manifest.v1+json` schema. The `dependencies` collection declares the artifact the signature is dependent upon. Similar to pypi packages, the validation of dependencies are deferred. If the dependent artifacts are found, they are valid. Depending on the validation options, a signature may exist without its dependent artifact. +**A Notary v2 signature of the `mysql:8` image example:** + ```json { "mediaType": "application/vnd.oci.artifact.manifest.v1+json", @@ -145,10 +207,11 @@ To support hard references, an additional dependencies collection is added to a ], "dependencies": [ { - "mediaType": "application/vnd.oci.image.manifest.v1", + "artifact": "mysql:8", + "artifactType": "application/vnd.oci.image.manifest.v1.config.json", + "mediaType": "application/vnd.oci.image.manifest.v1.config.json", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", "size": 16724, - "artifact": "mysql:8" } ] } @@ -156,9 +219,9 @@ To support hard references, an additional dependencies collection is added to a #### OCI-Registry CLI -To copy the above image and the associated signatures, a new `oci-reg` cli is proposed. +To copy the above image and the associated signatures, a new `oci-reg` cli is proposed. The oci-reg cli is an independent tool that demonstrates the value of these collections, providing a unified standard means for working within and across different OCI compliant registry implementations. -The following command would copy the `mysql:8` image from docker hub to the acmerockets registry. The CLI could be run within the source or target cloud. +The following command would copy the `mysql:8` image from docker hub to the acme-rockets registry. The CLI could be run within the source or target cloud. ```bash oci-reg copy \ @@ -179,7 +242,15 @@ There are a set of artifact types that declare references to other artifacts tha ![mysql image copy](./media/wordpress-helm-chart-copy.svg) -In the above scenario, a helm chart is copied from a public registry to the ACME Rockets registry. The `wordpress-chart:v5` is represented as an `application/vnd.oci.artifact.manifest.v1+json`. In addition to the Notary v2 signatures declaring a dependency on the `wordpress:v5` image, the `mysql:8` image, the `wordpress-chart:v5` helm chart can also represent signed content. The new references collection within the `oci.artifact.manifest` schema provides a means to identify the images the helm chart references. +In the above scenario, a helm chart is copied from a public registry to the ACME Rockets registry. The `wordpress-chart:v5` is represented as an `application/vnd.oci.artifact.manifest.v1+json`. The `wordpress-chart:v5` helm chart references the `wordpress:v5` image and the `mysql:8` image. All three artifacts have signatures attesting to their authenticity. + +As the copy is initiated, the `oci.artifact.manifest` of the `wordpress-chart:v5` is evaluated. As the chart references the same version (digest) of the `mysql:8` image already in theACME Rockets registry, the copy skips duplicating the content and moves to copying the `wordpress:v5` image, the `wordpress-chart:v5` and their associated signatures. + +In this case, the images referenced in the chart existed in the source registry. However, this may not be the case in all scenarios. A helm chart may be acquired from a different location, referencing images from docker hub. This deferred validation is left to client tools, enabling common package management resolution scenarios. + +To support the loose references between artifacts, a `references` collection is added to the `oci.artifact.manifest`: + +**A `wordpress-chart:v5` Helm Chart example:** ```json { @@ -205,13 +276,15 @@ In the above scenario, a helm chart is copied from a public registry to the ACME ], "references": [ { - "reference": "wordpress:5.7", + "artifact": "wordpress:5.7", + "artifactType": "application/vnd.oci.image.manifest.v1.config.json", "mediaType": "application/vnd.oci.image.manifest.v1.config.json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", "size": 1510 }, { - "reference": "mysql:8", + "artifact": "mysql:8", + "artifactType": "application/vnd.oci.image.manifest.v1.config.json", "mediaType": "application/vnd.oci.image.manifest.v1.config.json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", "size": 1578 @@ -222,11 +295,13 @@ In the above scenario, a helm chart is copied from a public registry to the ACME #### CNAB Reference -A CNAB is yet another reference artifact. While the current CNAB spec incorporates the helm-cli ahd helm chart within an invocation image, the `artifact.manifest` provides more natural package management experiences where the references can be resolved based on the users intent. +A CNAB is yet another reference artifact. While the current CNAB spec incorporates the helm-cli ahd helm chart within an invocation image, the `artifact.manifest` provides more natural package management experiences where the references can be resolved based on the users intent, while leveraging the capabilities of an OCI compliant registry to store all OCI Artifact types. ![mysql image copy](./media/wordpress-cnab-copy.svg) -Similar to the Helm example, a CNAB is copied from a public registry to the ACME Rockets registry. The `wordpress-cnab:v5` CNAB declares references to an invocation image that includes the `helm-cli`. This provides an environment to run `helm install`. The CNAB includes an additional refernece to `wordpress-chart:v5`. The chart includes references to the `wordpress:v5` and `mysql:8` images. As the `oci-reg copy` command is executed, the graph of references may be expanded. As the copy proceeds, only those artifacts that don't already exist in the target registry are required to be copied. The CNAB and Helm `artifact.manifest` may declare how strict they wish to couple their references to **stable tags** or **unique digests** +Similar to the Helm example, a CNAB is copied from a public registry to the ACME Rockets registry. The `wordpress-cnab:v5` CNAB declares references `-->` to an invocation image that includes the `helm-cli:v3`. This invocation image provides an environment to run `helm install` of the referenced `wordpress-chart:v5`. The CNAB includes an additional reference `-->` to `wordpress-chart:v5`. The chart includes references `-->` to the `wordpress:v5` and `mysql:8` images. Lastly, each artifact has a Notary v2 signature that points to `<--` the artifact they are signing. + +As the `oci-reg copy` command is executed, the graph of references are expanded. As the copy proceeds, only those artifacts that don't already exist in the target registry are required to be copied. The references may be hard bound to the digest, or loosely bound to the `artifact:tag` enabling more recently patched versions of a given `artifact:tag`. The CNAB and Helm `artifact.manifest` may declare how strict they wish to couple their references to **stable tags** or **unique digests** ```json { @@ -252,13 +327,15 @@ Similar to the Helm example, a CNAB is copied from a public registry to the ACME ], "references": [ { - "reference": "wordpress-chart:v5", - "mediaType": "application/vnd.cncf.helm.v1.config.json", + "artifact": "wordpress-chart:v5", + "artifactType": "application/vnd.cncf.helm.v1.config.json", + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", "size": 1510 }, { - "reference": "helm-cli:3", + "artifact": "helm-cli:3", + "artifactType": "application/vnd.oci.image.manifest.v1.config.json", "mediaType": "application/vnd.oci.image.manifest.v1.config.json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", "size": 1578 @@ -267,112 +344,97 @@ Similar to the Helm example, a CNAB is copied from a public registry to the ACME } ``` ----- -# ADDITIONAL EDITING REQUIRED BEYOND THIS POINT ----- +### Deletion -## Goals of Artifact Manifest +Distribution-spec APIs will provide standard delete operations, including options for deleting referenced artifacts, or blocking a delete as the artifact is referenced by other artifacts. The `oci.artifact.manifest` collection will provide the information, as defined by the artifact author` for how an artifact should be handled for delete operations. The registry, nor the `oci-reg` cli would need to know about specific artifact implementations. -### Bi-directional Hierarchies +The deletion scenarios include: -The OCI Distribution-spec 1.0 supports tops down hierarchies for tracking a manifest, a config object, and a collection of layers. This works well for immutable artifacts that are individually pushed to a registry. As an artifact is pushed, a manifest and digest of the manifest and it's referenced layers are computed. +- Which references should be deleted (ref counted) +- Which artifacts may be blocked from deletion as another artifact depends upon it. -The artifact-manifest will support additional references to existing content within a registry. Rather than update the original manifest with the additional objects, the additional object will provide the digest by which it's enhancing. +- Examples: + - deleting the wordpress helm chart deletes the config, chart and values blobs. + - deleting the wordpress helm chart will reduce the ref-count of the images it may reference. + - deleting the mysql image should warn if referenced by any helm charts. However, based on the parameters of the cli, it may delete images referenced by helm charts within the registry as these references are considered loose references and may be resolved externally to the registry. + - deleting the wordpress helm chart, wordpress image, or mysql image would delete the associated signatures as the signatures have no value unto themselves. The `oci-reg` cli may accomplish these delete steps without any knowledge of Notary v2 spec as the `oci-reg` delete cli will follow the rules of the `oci.artifact.manifest` collections. -- `hello-world:v1` with a digest of `sha256:8b895ffec9fe33301cee47b0edc1600ea67604c3d138fa8ecb43ae62ad3b6fd4` is pushed to the registry -- A **S**oftware **B**ill **o**f **M**aterials (SBoM) for `hello-world:v1` is pushed to the registry. -- A `hello-world:v1` SBoM is pushed, using digest of the `hello-world:v1` image. +## OCI Artifact Manifest Content Descriptor -In the above case, the original `hello-world:v1` image digest remains the same. Deployments of the `hello-world:v1` image can be made using the `hello-world:v1` tag, or the `sha256:8b89...` digest. With additional distribution-spec artifact APIs, requests may be made to list objects that reference the `hello-world:v1` artifact. In this case, returning the SBoM references. +The OCI Artifact Manifest content descriptor is enhanced with an additional `artifact` property enabling loose or hard references between artifact types. -### Artifact Copying Within and Across OCI Compliant Registries +- **`mediaType`** *string* -Distribution-spec APIs will provide a means to discover, pull and push content within and across registries. No knowledge of the specific artifact type will be necessary. + This property identifies the OCI schema of the manifest being referenced. + An OCI v_ compliant registry must support at least the following schemas: -### Delete Operations + - `"application/vnd.oci.image.manifest.v1+json"` + - `"application/vnd.oci.image.index.v1+json"` + - `"application/vnd.oci.artifact.manifest.v1+json"` -Distribution-spec APIs will provide standard delete operations, including options for deleting referenced artifacts, or blocking a delete as the artifact is referenced by other artifacts. +- **`digest`** *string* -- Which references should be deleted (ref counted) -- Which references should just reduce ref counting? -- Which artifacts should be blocked from deletion as another artifact depends upon it? -- Examples: - - deleting the wordpress helm chart deletes the config, chart and values blobs - - deleting the mysql image should warn if referenced by helm charts - - deleting the wordpress chart removes a ref count to the mysql image, for mysql deletion + This REQUIRED property is the digest of the targeted content, conforming to the requirements outlined in Digests. Retrieved content SHOULD be verified against this digest when consumed via untrusted sources. -## Link Types +- **`size`** *int64* -Artifact manifest will support bi-directional references enabling additional artifacts to be added to a registry after an artifact was persisted. + This REQUIRED property specifies the size, in bytes, of the raw content. This property exists so that a client will have an expected size for the content before processing. If the length of the retrieved content does not match the specified length, the content SHOULD NOT be trusted. -As artifacts reference others, hard and soft references will be supported, enabling artifacts to be individually deleted, or an extent of the dependency graph to be removed. +- **`artifact-type`** *string* -### Notes -Artifact-manifest has 3 collections -```json -{ - blobs:{}, physical content that is always associated with the object - just like oci image - dependencies:{} - can be loosely defined (cnab, helm) - references:{} - always copied (signature) -} -``` + This property defines the OCI Artifact Type. In previous versions of the OCI Artifact spec, this was defined with `manifest.config.mediaType`. This property is lifted and formalized in the `oci.artifact.manifest` enabling filtering of references to those of a given `artifact-type`, such as returning a list of Notary v2 signatures. -# copy the helm chart, the images (if found) and all signatures found -registry copy wordpress-helm:v1 +- **`artifact`** *string* -# copy with limited references (signatures but not source) -registry copy wordpress-helm:v1 --with-dependencies --filter-references "+notary.v2" "-gpl-source.v2" + This property provides a reference to the `artifact:tag`, enabling floating to a newer/patched version of a tag. An OCI Artifact Manifest content descriptor must include the digest to assure a client may validate the initially referenced artifact, however this is a client choice for binding to a specific digest, or newer version based on the `artifact:tag` named reference. -## *Image Manifest* Property Descriptions +## OCI Artifact Collections -- **`schemaVersion`** *int* +OCI Artifact Manifests provide the following types of references: - This REQUIRED property specifies the artifact manifest schema version. - For this version of the specification, this MUST be `1`. The value of this MAY change if the schema is enhanced. +- **Blobs:** Content that represents the artifact. These are analogues to layers from the OCI Image manifest and Config objects. Layers are renamed blobs as they represent a generic collection of content, as opposed to an ordered layered collection as defined by OCI Image Manifest. An artifact may treat them as ordered, but it is not required. +- **Dependencies** on other artifacts that enhance the content, such as a Notary v2 signature or an SBoM. These dependencies are *unknown* by the original artifact as they are added at a later time. A registry would need to index these references as registry apis would request all content related to the source artifact. +- **References** to other artifacts, used to complete a scenario, but may not be stored within the same repository or registry. These references are defined by the source artifact and known at the time of upload to a registry, such as a Helm chart that references other images. These references are included in the manifest and computed in the digest of the manifest. -- **`mediaType`** *string* +### Blobs Collection - This property identifies the OCI Artifact Manifest schema. This field MUST be `"application/vnd.oci.artifact.manifest.v1+json"` +All blobs are considered to be hard dependencies that must be resolvable within a registry. An artifact is considered invalid if the manifest blobs are not resolvable. Registries MAY implement de-duping, using ref-counting to assure at least one copy of the blob is resolvable for any given `oci.artifact.manifest`. OCI Artifact blobs are generalizations of the OCI Image Spec layers definition. -- **`config`** *[descriptor](descriptor.md)* +### Dependencies Collection - This REQUIRED property references a configuration object for a container, by digest. - Beyond the [descriptor requirements](descriptor.md#properties), the value has the following additional restrictions: +Alternate names: - - **`mediaType`** *string* +- `dependent-upon` +- `parents` +- `enhances` - This [descriptor property](descriptor.md#properties) has additional restrictions for `config`. - Implementations MUST support at least the following media types: +The dependencies collection is an optional collection of references to other artifacts. The artifact is said to enhance the dependent artifacts by adding additional content. The content may be added after the initial content was created or pushed to a registry. By supporting additional content, the referenced artifact can be enhanced without having to change the referenced artifacts manifest, digest or tag. - - [`application/vnd.oci.image.config.v1+json`](config.md) +Examples include: - Manifests concerned with portability SHOULD use one of the above media types. +- Notary v2 signatures +- SBoM documents +- Artifact Meta-data -- **`layers`** *array of objects* +Dependencies are collections of OCI Artifact Content Descriptors. - Each item in the array MUST be a [descriptor](descriptor.md). - The array MUST have the base layer at index 0. - Subsequent layers MUST then follow in stack order (i.e. from `layers[0]` to `layers[len(layers)-1]`). - The final filesystem layout MUST match the result of [applying](layer.md#applying-changesets) the layers to an empty directory. - The [ownership, mode, and other attributes](layer.md#file-attributes) of the initial empty directory are unspecified. +### References Collection - Beyond the [descriptor requirements](descriptor.md#properties), the value has the following additional restrictions: +The references collection is an optional collection of loose references to additional artifacts that complete a given scenario. The references may be stored in other repositories and/or other registries. The references collection allows an artifact to define a graph of content, used by it's client tools. While providing generic references to a registry that maintains the references without having to validate them for artifact submission or removal from a registry. - - **`mediaType`** *string* +References are made to specific content digests and tags, however it is up to the client to determine how to resolve the reference. The client MAY bind directly to the content digest, or bind to the tag, allowing newer patched versions of the tag. In all cases, a Notary v2 signature MAY be used to assure the content derives from the original authority. - This [descriptor property](descriptor.md#properties) has additional restrictions for `layers[]`. - Implementations MUST support at least the following media types: +Examples include: - - [`application/vnd.oci.image.layer.v1.tar`](layer.md) - - [`application/vnd.oci.image.layer.v1.tar+gzip`](layer.md#gzip-media-types) - - [`application/vnd.oci.image.layer.nondistributable.v1.tar`](layer.md#non-distributable-layers) - - [`application/vnd.oci.image.layer.nondistributable.v1.tar+gzip`](layer.md#gzip-media-types) +- A helm chart referencing container images +- A CNAB referencing Helm charts or other artifacts the CNAB may need to complete it's operation +- A WASM that may reference other packages that may be stored in a registry. - Manifests concerned with portability SHOULD use one of the above media types. - An encountered `mediaType` that is unknown to the implementation MUST be ignored. +References are collections of OCI Artifact Content Descriptors. +## Annotations - Entries in this field will frequently use the `+gzip` types. +OCI Artifact Manifest includes several annotations that have been generalized from the image-spec annotations. - **`annotations`** *string-string map* @@ -381,108 +443,22 @@ registry copy wordpress-helm:v1 --with-dependencies --filter-references "+notary See [Pre-Defined Annotation Keys](annotations.md#pre-defined-annotation-keys). -## Example Image Manifest - -*Example showing an image manifest:* -```json,title=Manifest&mediatype=application/vnd.oci.image.manifest.v1%2Bjson -{ - "schemaVersion": 2, - "config": { - "mediaType": "application/vnd.oci.image.config.v1+json", - "size": 7023, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" - }, - "layers": [ - { - "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 32654, - "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0" - }, - { - "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 16724, - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" - }, - { - "mediaType": "application/vnd.oci.artifact.layer.v1.tar+gzip", - "size": 73109, - "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" - } - ], - "annotations": { - "com.example.key1": "value1", - "com.example.key2": "value2" - } -} -``` - -## Pre-Defined Annotation Keys +### Pre-Defined Annotation Keys This specification defines the following annotation keys, intended for but not limited to Artifact Manifest authors: -* **org.opencontainers.artifact.created** date and time on which the artifact was built (string, date-time as defined by [RFC 3339](https://tools.ietf.org/html/rfc3339#section-5.6)). -* **org.opencontainers.artifact.authors** contact details of the people or organization responsible for the artifact (freeform string) -* **org.opencontainers.artifact.url** URL to find more information on the artifact (string) -* **org.opencontainers.artifact.documentation** URL to get documentation on the artifact (string) -* **org.opencontainers.artifact.source** URL to get source code for building the artifact (string) -* **org.opencontainers.artifact.version** version of the packaged software - * The version MAY match a label or tag in the source code repository - * version MAY be [Semantic versioning-compatible](http://semver.org/) -* **org.opencontainers.artifact.revision** Source control revision identifier for the packaged software. -* **org.opencontainers.artifact.vendor** Name of the distributing entity, organization or individual. -* **org.opencontainers.artifact.licenses** License(s) under which contained software is distributed as an [SPDX License Expression][spdx-license-expression]. -* **org.opencontainers.artifact.title** Human-readable title of the artifact (string) -* **org.opencontainers.artifact.description** Human-readable description of the software packaged in the artifact (string) - -## Setting meta-data - -Should be as simple as setting a name/value pair for a specific tag and/or digest -Setting a name/value pair for a tag will assign the meta-data to the digest currently associated with the tag. We do not currently see the need to set meta-data specific to a tag. - -Setting the git digest to a tagged artifact: - -```shell -/charts/wordpress:5.7 -{ - "name": "git.digest", - "value": "1124125" -} -``` - -Setting the contact info to a tagged artifact: - -```shell -/charts/wordpress:5.7 -{ - "name": "oci.meta-data.contact", - "value": '{ - "first": "Steve", - "last": "Lasker", - "email" "stevenlasker@hotmail.com" - }' -} -``` - -## Collections - -## Parent - -Parent elements MUST NOT have tags as they are attributions to the parent element - -Optional elements are optional as they represent metadata that has persistance. - -### Blobs - -All blobs are considered to be hard dependencies. These support ref counting, but would be deleted when the manifest is deleted. - -### Dependencies - -All dependencies are considered soft dependencies. - - -## Pushing Artifact Manifests -Manifest validation -Each mediaType is evaluated. If the manifestType is +- **org.opencontainers.artifact.created** date and time on which the artifact was built (string, date-time as defined by [RFC 3339](https://tools.ietf.org/html/rfc3339#section-5.6)). +- **org.opencontainers.artifact.authors** contact details of the people or organization responsible for the artifact (freeform string) +- **org.opencontainers.artifact.url** URL to find more information on the artifact (string) +- **org.opencontainers.artifact.documentation** URL to get documentation on the artifact (string) +- **org.opencontainers.artifact.source** URL to get source code for building the artifact (string) +- **org.opencontainers.artifact.version** version of the packaged software + - The version MAY match a label or tag in the source code repository + - version MAY be [Semantic versioning-compatible](http://semver.org/) +- **org.opencontainers.artifact.revision** Source control revision identifier for the packaged software. +- **org.opencontainers.artifact.vendor** Name of the distributing entity, organization or individual. +- **org.opencontainers.artifact.title** Human-readable title of the artifact (string) +- **org.opencontainers.artifact.description** Human-readable description of the software packaged in the artifact (string) ## Open Questions From d3e24fb4f889df6768708db95e6b45a19597f96f Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Mon, 25 Jan 2021 08:45:22 -0800 Subject: [PATCH 06/10] Add oci-reg mapping examples Signed-off-by: Steve Lasker --- artifact-manifest/artifact-manifest.md | 37 ++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index 859635f..758caf0 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -76,6 +76,43 @@ Artifacts that reference other artifacts must include an OCI Artifact Descriptor Clients MAY choose to bind to specific digests, assuring they are testing and using the exact graph initially specified. Or, clients may choose to float to a newer version of a tag, benefiting from patches. In all cases, a Notary v2 signature may be used to assure the artifacts are true to their initial ownership and authors. +**Setting the default registry:** + +```bash +oci-reg default-registry registry.acme-rockets.io +``` + +**Setting repository mappings for where to push and pull unqualified artifacts:** + +`oci-reg.config` + +```json +{ + "root-namespace": "dev" +} +``` + +**Setting repository mappings for specific artifacts:** + +`oci-reg.config` + +```json +{ + "default-registry": "registry.acme-rockets.io", + "root-namespace": "prod", + "repo-mappings": [ + { + "repo": "wordpress-chart", + "path": "/charts" + }, + { + "repo": "wordpress-cnab", + "path": "/cnabs" + } + ] +} +``` + ## Supported Artifact Types Artifact manifest is intended to support the following artifact types: From b13f2284a4309b1f3c38934ebe398d60056cc201 Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Wed, 27 Jan 2021 13:48:26 -0800 Subject: [PATCH 07/10] Cleanup config and dependencies examples Signed-off-by: Steve Lasker --- artifact-manifest/artifact-manifest.md | 44 ++------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index 758caf0..f4e763f 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -76,43 +76,6 @@ Artifacts that reference other artifacts must include an OCI Artifact Descriptor Clients MAY choose to bind to specific digests, assuring they are testing and using the exact graph initially specified. Or, clients may choose to float to a newer version of a tag, benefiting from patches. In all cases, a Notary v2 signature may be used to assure the artifacts are true to their initial ownership and authors. -**Setting the default registry:** - -```bash -oci-reg default-registry registry.acme-rockets.io -``` - -**Setting repository mappings for where to push and pull unqualified artifacts:** - -`oci-reg.config` - -```json -{ - "root-namespace": "dev" -} -``` - -**Setting repository mappings for specific artifacts:** - -`oci-reg.config` - -```json -{ - "default-registry": "registry.acme-rockets.io", - "root-namespace": "prod", - "repo-mappings": [ - { - "repo": "wordpress-chart", - "path": "/charts" - }, - { - "repo": "wordpress-cnab", - "path": "/cnabs" - } - ] -} -``` - ## Supported Artifact Types Artifact manifest is intended to support the following artifact types: @@ -238,17 +201,14 @@ To support hard references, an additional dependencies collection is added to a { "mediaType": "application/vnd.cncf.notary.v2.json", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", - "size": 32654, - "reference": "registry.wabbitnetworks.io" + "size": 32654 } ], "dependencies": [ { - "artifact": "mysql:8", - "artifactType": "application/vnd.oci.image.manifest.v1.config.json", "mediaType": "application/vnd.oci.image.manifest.v1.config.json", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", - "size": 16724, + "size": 16724 } ] } From 77cc3be5cc98fefa31eeb5ee1d8a414c63ca4e8d Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Tue, 2 Feb 2021 15:51:18 -0800 Subject: [PATCH 08/10] Converge dependencies & references to manifests Signed-off-by: Steve Lasker --- artifact-manifest/artifact-manifest.md | 97 ++++++++++++++++---------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index f4e763f..11bee18 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -110,10 +110,10 @@ A CNAB may also be persisted with configuration information, along with a refere The main scenarios include: -1. Discovery of content within a registry for content listing through CLI and visualizations. +1. Discovery of content within a registry for content listing through a CLI and visualizations. 1. Copying within and across registries. 1. Deletion management, providing information to de-dupe content with reference counting. -1. Support enhancing information related to existing content. Such as adding a Notary v2 signature or SBoM. +1. Support enhancing information related to existing content. Such as adding a Notary v2 signature or SBoM artifacts. 1. Validation, with required and optional references. ### Content Discovery @@ -193,43 +193,50 @@ To support hard references, an additional dependencies collection is added to a "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "artifactType": "application/vnd.cncf.notary.v2", "config": { - "mediaType": "application/vnd.cncf.notary.config.v2", + "mediaType": "application/vnd.cncf.notary.config.v2+json", "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", "size": 102 }, "blobs": [ { - "mediaType": "application/vnd.cncf.notary.v2.json", + "mediaType": "application/vnd.cncf.notary.signature.v2+json", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654 } ], - "dependencies": [ + "manifests": [ { - "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", - "size": 16724 + "size": 16724, + "annotations: { + "oci.distribution.relationship": "depends-on" + } } - ] -} + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } ``` +In the above example, the signing entity is Docker, which is represented as a notary scoped annotation: `"org.cncf.notary.v2.signature.subject": "docker.io"` + #### OCI-Registry CLI -To copy the above image and the associated signatures, a new `oci-reg` cli is proposed. The oci-reg cli is an independent tool that demonstrates the value of these collections, providing a unified standard means for working within and across different OCI compliant registry implementations. +To copy the above image and the associated signatures, a new `oci-reg` cli is proposed for illustrative purposes. The `oci-reg` cli is an independent tool that demonstrates the value of these collections, providing a standard means for working within and across different OCI conformant registry implementations. -The following command would copy the `mysql:8` image from docker hub to the acme-rockets registry. The CLI could be run within the source or target cloud. +The following command would copy the `mysql:8` image from docker hub to the acme-rockets registry. The CLI _could_ be run within the source or target cloud eliminating the download/upload network hops. ```bash oci-reg copy \ - --source hub.docker.io/mysql:8 \ + --source docker.io/mysql:8 \ --target registry.acme-rockets.io/base-artifacts/mysql:8 ``` The `oci-reg copy` command would: - assure the manifest and layer/blob digests remain the same -- copy any artifacts that are dependent on the source artifact-manifest, persisting them in the target registry. +- copy any artifacts that are dependent on the source artifact-manifest, persisting them in the target registry. These _could_ include Notary v2 signatures, SBoMs, GPL source or other referenced artifacts. ### Reference Artifacts @@ -239,7 +246,7 @@ There are a set of artifact types that declare references to other artifacts tha ![mysql image copy](./media/wordpress-helm-chart-copy.svg) -In the above scenario, a helm chart is copied from a public registry to the ACME Rockets registry. The `wordpress-chart:v5` is represented as an `application/vnd.oci.artifact.manifest.v1+json`. The `wordpress-chart:v5` helm chart references the `wordpress:v5` image and the `mysql:8` image. All three artifacts have signatures attesting to their authenticity. +In the above scenario, a helm chart is copied from a public registry to the ACME Rockets registry. The `wordpress-chart:v5` is represented as an `application/vnd.oci.artifact.manifest.v1+json`. The `wordpress-chart:v5` helm chart references the `wordpress:v5` image and the `mysql:8` image. All three artifacts have Notary v2 signatures attesting to their authenticity. As the copy is initiated, the `oci.artifact.manifest` of the `wordpress-chart:v5` is evaluated. As the chart references the same version (digest) of the `mysql:8` image already in theACME Rockets registry, the copy skips duplicating the content and moves to copying the `wordpress:v5` image, the `wordpress-chart:v5` and their associated signatures. @@ -251,40 +258,45 @@ To support the loose references between artifacts, a `references` collection is ```json { - "schemaVersion": 2, "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "artifactType": "application/vnd.cncf.helm.v3", "config": { "mediaType": "application/vnd.cncf.helm.config.v1+json", - "size": 0, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 0 }, "blobs": [ { - "mediaType": "application/vnd.cncf.helm.chart.v1.tar", + "mediaType": "application/vnd.cncf.helm.chart.v1+tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654 }, { - "mediaType": "application/vnd.cncf.helm.values.v1.yaml", + "mediaType": "application/vnd.cncf.helm.values.v1+yaml", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", "size": 16724 } ], - "references": [ + "manifests": [ { - "artifact": "wordpress:5.7", - "artifactType": "application/vnd.oci.image.manifest.v1.config.json", - "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", - "size": 1510 + "size": 1510, + "annotations": [ + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "wordpress:5.7", + "oci.distribution.artifactType": "application/vnd.oci.image.v1", + ] }, { - "artifact": "mysql:8", - "artifactType": "application/vnd.oci.image.manifest.v1.config.json", - "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", - "size": 1578 + "size": 1578, + "annotations": [ + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "mysql:8", + "oci.distribution.artifactType": "application/vnd.oci.image.v1", + ] } ] } @@ -302,7 +314,6 @@ As the `oci-reg copy` command is executed, the graph of references are expanded. ```json { - "schemaVersion": 2, "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "artifactType": "application/vnd.cncf.cnab.v1", "config": { @@ -312,30 +323,37 @@ As the `oci-reg copy` command is executed, the graph of references are expanded. }, "blobs": [ { - "mediaType": "application/vnd.cncf.cnab.v1.tar", + "mediaType": "application/vnd.cncf.cnab.v1+tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654 }, { - "mediaType": "application/vnd.cncf.cnab.params.v1.json", + "mediaType": "application/vnd.cncf.cnab.params.v1+json", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", "size": 16724 } ], - "references": [ + "manifests": [ { - "artifact": "wordpress-chart:v5", - "artifactType": "application/vnd.cncf.helm.v1.config.json", "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", - "size": 1510 + "size": 1510, + "annotations": [ + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "wordpress-chart:v5", + "oci.distribution.artifactType": "application/vnd.cncf.helm.v3", + ] }, { "artifact": "helm-cli:3", - "artifactType": "application/vnd.oci.image.manifest.v1.config.json", - "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", - "size": 1578 + "size": 1578, + "annotations": [ + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "helm-cli:3", + "oci.distribution.artifactType": "application/vnd.oci.image.manifest.v1", + ] } ] } @@ -396,6 +414,9 @@ OCI Artifact Manifests provide the following types of references: ### Blobs Collection All blobs are considered to be hard dependencies that must be resolvable within a registry. An artifact is considered invalid if the manifest blobs are not resolvable. Registries MAY implement de-duping, using ref-counting to assure at least one copy of the blob is resolvable for any given `oci.artifact.manifest`. OCI Artifact blobs are generalizations of the OCI Image Spec layers definition. +## Manifests Collection + +> **NOTE!** Update to consolidate the Dependencies and References collections ### Dependencies Collection From 8760ac5e42bc7a36802559481b34e2f4e8584492 Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Tue, 2 Feb 2021 15:58:01 -0800 Subject: [PATCH 09/10] Converge dependencies & references to manifests Signed-off-by: Steve Lasker --- artifact-manifest/artifact-manifest.md | 29 +++++++++++++------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index 11bee18..d9a5a86 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -209,7 +209,7 @@ To support hard references, an additional dependencies collection is added to a "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", "size": 16724, - "annotations: { + "annotations": { "oci.distribution.relationship": "depends-on" } } @@ -282,21 +282,21 @@ To support the loose references between artifacts, a `references` collection is "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", "size": 1510, - "annotations": [ + "annotations": { "oci.distribution.relationship": "references", "oci.distribution.artifact": "wordpress:5.7", - "oci.distribution.artifactType": "application/vnd.oci.image.v1", - ] + "oci.distribution.artifactType": "application/vnd.oci.image.v1" + } }, { "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", "size": 1578, - "annotations": [ + "annotations": { "oci.distribution.relationship": "references", "oci.distribution.artifact": "mysql:8", - "oci.distribution.artifactType": "application/vnd.oci.image.v1", - ] + "oci.distribution.artifactType": "application/vnd.oci.image.v1" + } } ] } @@ -338,22 +338,22 @@ As the `oci-reg copy` command is executed, the graph of references are expanded. "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", "size": 1510, - "annotations": [ + "annotations": { "oci.distribution.relationship": "references", "oci.distribution.artifact": "wordpress-chart:v5", - "oci.distribution.artifactType": "application/vnd.cncf.helm.v3", - ] + "oci.distribution.artifactType": "application/vnd.cncf.helm.v3" + } }, { "artifact": "helm-cli:3", "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", "size": 1578, - "annotations": [ + "annotations": { "oci.distribution.relationship": "references", "oci.distribution.artifact": "helm-cli:3", - "oci.distribution.artifactType": "application/vnd.oci.image.manifest.v1", - ] + "oci.distribution.artifactType": "application/vnd.oci.image.manifest.v1" + } } ] } @@ -414,6 +414,7 @@ OCI Artifact Manifests provide the following types of references: ### Blobs Collection All blobs are considered to be hard dependencies that must be resolvable within a registry. An artifact is considered invalid if the manifest blobs are not resolvable. Registries MAY implement de-duping, using ref-counting to assure at least one copy of the blob is resolvable for any given `oci.artifact.manifest`. OCI Artifact blobs are generalizations of the OCI Image Spec layers definition. + ## Manifests Collection > **NOTE!** Update to consolidate the Dependencies and References collections @@ -480,4 +481,4 @@ This specification defines the following annotation keys, intended for but not l ## Open Questions -Should the references collection support additional types, like loose urls \ No newline at end of file +Should the references collection support additional types, like loose urls From a56aaad3afb5bab321644e3508f76d915031b3da Mon Sep 17 00:00:00 2001 From: Steve Lasker Date: Wed, 3 Feb 2021 18:26:53 -0800 Subject: [PATCH 10/10] A/B examples of manifests & references collection Signed-off-by: Steve Lasker --- .../artifact-manifest-bicep.json | 41 --- ...tifact-manifest-mysql-image-sbom copy.json | 28 ++ .../artifact-manifest-mysql-image-sbom.json | 28 ++ ...tifact-manifest-mysql-image-signature.json | 26 +- ...anifest-wordpress-cnab-signature copy.json | 27 ++ ...act-manifest-wordpress-cnab-signature.json | 27 ++ .../artifact-manifest-wordpress-cnab..json | 37 +-- ...act-manifest-wordpress-helm-signature.json | 27 -- .../artifact-manifest-wordpress-helm.json | 32 +-- ...ct-manifest-wordpress-image-signature.json | 43 ++- artifact-manifest/artifact-manifest.json | 61 ---- artifact-manifest/artifact-manifest.md | 266 ++++++++++++------ .../media/mysql-with-sigs-copy.svg | 2 +- artifact-manifest/media/sbom-document.svg | 1 + artifact-manifest/media/wordpress-cnab.svg | 2 +- .../media/wordpress-helm-chart.svg | 2 +- .../media/wordpress-image-layers-sig-sbom.svg | 1 + .../artifact-manifest-mysql-image-sbom.json | 30 ++ ...tifact-manifest-mysql-image-signature.json | 30 ++ ...act-manifest-wordpress-cnab-signature.json | 30 ++ .../artifact-manifest-wordpress-cnab..json | 37 +++ ...act-manifest-wordpress-helm-signature.json | 30 ++ .../artifact-manifest-wordpress-helm.json | 37 +++ ...ct-manifest-wordpress-image-signature.json | 30 ++ .../artifact-manifest-mysql-image-sbom.json | 28 ++ ...tifact-manifest-mysql-image-signature.json | 28 ++ ...anifest-wordpress-cnab-signature copy.json | 27 ++ ...act-manifest-wordpress-cnab-signature.json | 27 ++ .../artifact-manifest-wordpress-cnab..json | 36 +++ .../artifact-manifest-wordpress-helm.json | 36 +++ ...ct-manifest-wordpress-image-signature.json | 28 ++ 31 files changed, 800 insertions(+), 285 deletions(-) delete mode 100644 artifact-manifest/artifact-manifest-bicep.json create mode 100644 artifact-manifest/artifact-manifest-mysql-image-sbom copy.json create mode 100644 artifact-manifest/artifact-manifest-mysql-image-sbom.json create mode 100644 artifact-manifest/artifact-manifest-wordpress-cnab-signature copy.json delete mode 100644 artifact-manifest/artifact-manifest-wordpress-helm-signature.json delete mode 100644 artifact-manifest/artifact-manifest.json create mode 100644 artifact-manifest/media/sbom-document.svg create mode 100644 artifact-manifest/media/wordpress-image-layers-sig-sbom.svg create mode 100644 artifact-manifest/option-a/artifact-manifest-mysql-image-sbom.json create mode 100644 artifact-manifest/option-a/artifact-manifest-mysql-image-signature.json create mode 100644 artifact-manifest/option-a/artifact-manifest-wordpress-cnab-signature.json create mode 100644 artifact-manifest/option-a/artifact-manifest-wordpress-cnab..json create mode 100644 artifact-manifest/option-a/artifact-manifest-wordpress-helm-signature.json create mode 100644 artifact-manifest/option-a/artifact-manifest-wordpress-helm.json create mode 100644 artifact-manifest/option-a/artifact-manifest-wordpress-image-signature.json create mode 100644 artifact-manifest/option-b/artifact-manifest-mysql-image-sbom.json create mode 100644 artifact-manifest/option-b/artifact-manifest-mysql-image-signature.json create mode 100644 artifact-manifest/option-b/artifact-manifest-wordpress-cnab-signature copy.json create mode 100644 artifact-manifest/option-b/artifact-manifest-wordpress-cnab-signature.json create mode 100644 artifact-manifest/option-b/artifact-manifest-wordpress-cnab..json create mode 100644 artifact-manifest/option-b/artifact-manifest-wordpress-helm.json create mode 100644 artifact-manifest/option-b/artifact-manifest-wordpress-image-signature.json diff --git a/artifact-manifest/artifact-manifest-bicep.json b/artifact-manifest/artifact-manifest-bicep.json deleted file mode 100644 index e00ff14..0000000 --- a/artifact-manifest/artifact-manifest-bicep.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "schemaVersion": 2, - "mediaType": "application/vnd.oci.artifact.collection.v1+json", - "config": { - "mediaType": "application/vnd.azure.arm.bicep.config.v1+json", - "size": 7023, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" - }, - "references": [ - { - "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 32654, - "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0" - }, - { - "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 16724, - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" - }, - { - "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 73109, - "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" - }, - { - "mediaType": "image|index|signature|helm|CNAB|...", - "digest": "---", - "refType": "hard|soft" - }, - { - "mediaType": "image|index|signature|helm|CNAB|...", - "digest": "---", - "refType": "hard|soft" - }, - { - "mediaType": "image|index|signature|helm|CNAB|...", - "digest": "---", - "refType": "hard|soft" - } - ] -} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-mysql-image-sbom copy.json b/artifact-manifest/artifact-manifest-mysql-image-sbom copy.json new file mode 100644 index 0000000..157adb6 --- /dev/null +++ b/artifact-manifest/artifact-manifest-mysql-image-sbom copy.json @@ -0,0 +1,28 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.openssf.sbom.v1+json", + "config": { + "mediaType": "application/vnd.openssf.sbom.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 102 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [], + "annotations": { + "openssf.sbom.author": "mysql" + } +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-mysql-image-sbom.json b/artifact-manifest/artifact-manifest-mysql-image-sbom.json new file mode 100644 index 0000000..3bc8ebd --- /dev/null +++ b/artifact-manifest/artifact-manifest-mysql-image-sbom.json @@ -0,0 +1,28 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.openssf.sbom.v1", + "config": { + "mediaType": "application/vnd.openssf.sbom.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 102 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.config.v1+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [], + "annotations": { + "openssf.sbom.author": "mysql" + } +} diff --git a/artifact-manifest/artifact-manifest-mysql-image-signature.json b/artifact-manifest/artifact-manifest-mysql-image-signature.json index bd182e6..1848120 100644 --- a/artifact-manifest/artifact-manifest-mysql-image-signature.json +++ b/artifact-manifest/artifact-manifest-mysql-image-signature.json @@ -1,26 +1,28 @@ { - "schemaVersion": 2, + "schemaVersion": 1, "mediaType": "application/vnd.oci.artifact.manifest.v1+json", - "artifactType": "application/vnd.cncf.notary.v2", + "artifactType": "application/vnd.cncf.notary.v2+json", "config": { - "mediaType": "application/vnd.cncf.notary.config.v2", + "mediaType": "application/vnd.cncf.notary.config.v2+json", "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", "size": 102 }, "blobs": [ { - "mediaType": "application/vnd.cncf.notary.v2.json", + "mediaType": "application/tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", - "size": 32654, - "reference": "registry.wabbitnetworks.io" + "size": 32654 } ], - "dependencies": [ + "manifests": [ { - "mediaType": "application/vnd.oci.image.manifest.v1", + "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", - "size": 16724, - "artifact": "mysql:3.1" + "size": 16724 } - ] -} + ], + "references": [], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-wordpress-cnab-signature copy.json b/artifact-manifest/artifact-manifest-wordpress-cnab-signature copy.json new file mode 100644 index 0000000..41424cd --- /dev/null +++ b/artifact-manifest/artifact-manifest-wordpress-cnab-signature copy.json @@ -0,0 +1,27 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 1303 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-wordpress-cnab-signature.json b/artifact-manifest/artifact-manifest-wordpress-cnab-signature.json index e69de29..41424cd 100644 --- a/artifact-manifest/artifact-manifest-wordpress-cnab-signature.json +++ b/artifact-manifest/artifact-manifest-wordpress-cnab-signature.json @@ -0,0 +1,27 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 1303 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-wordpress-cnab..json b/artifact-manifest/artifact-manifest-wordpress-cnab..json index 4b618d4..9dc174e 100644 --- a/artifact-manifest/artifact-manifest-wordpress-cnab..json +++ b/artifact-manifest/artifact-manifest-wordpress-cnab..json @@ -1,36 +1,37 @@ { - "schemaVersion": 2, + "schemaVersion": 1, "mediaType": "application/vnd.oci.artifact.manifest.v1+json", - "artifactType": "application/vnd.cncf.cnab.v1", + "artifactType": "application/vnd.cncf.cnab.v1+json.", "config": { "mediaType": "application/vnd.cncf.cnab.config.v1+json", - "size": 0, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 134 }, "blobs": [ { - "mediaType": "application/vnd.cncf.cnab.v1.tar", + "mediaType": "application/tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654 - }, - { - "mediaType": "application/vnd.cncf.cnab.params.v1.json", - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", - "size": 16724 } ], + "manifests": [], "references": [ { - "reference": "wordpress-chart:v5", - "mediaType": "application/vnd.cncf.helm.v1.config.json", - "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", - "size": 1510 + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578, + "annotations": { + "oci.distribution.artifact": "helm-cli:3" + } }, { - "reference": "helm-cli:3", - "mediaType": "application/vnd.oci.image.manifest.v1.config.json", - "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", - "size": 1578 + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510, + "annotations": { + "oci.distribution.artifact": "wordpress-chart:v5" + } + } ] } \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-wordpress-helm-signature.json b/artifact-manifest/artifact-manifest-wordpress-helm-signature.json deleted file mode 100644 index ee49d80..0000000 --- a/artifact-manifest/artifact-manifest-wordpress-helm-signature.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "schemaVersion": 2, - "mediaType": "application/vnd.oci.artifact.manifest.v1+json", - "artifactType": "application/vnd.cncf.notary.v2", - "config": { - "mediaType": "application/vnd.cncf.notary.config.v2", - "size": 0, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" - }, - "blobs": [ - { - "mediaType": "application/vnd.cncf.notary.v2.json", - "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", - "size": 32654, - "reference": "registry.wabbitnetworks.io" - } - ], - "references": [ - { - "mediaType": "application/vnd.oci.image.index.v1.config.json", - "reference": "/wordpress:5.7" - # digest not necessary as the signature has the digest embedded in it - } - ] -} - - diff --git a/artifact-manifest/artifact-manifest-wordpress-helm.json b/artifact-manifest/artifact-manifest-wordpress-helm.json index a93db68..496ab8d 100644 --- a/artifact-manifest/artifact-manifest-wordpress-helm.json +++ b/artifact-manifest/artifact-manifest-wordpress-helm.json @@ -1,36 +1,36 @@ { - "schemaVersion": 2, + "schemaVersion": 1, "mediaType": "application/vnd.oci.artifact.manifest.v1+json", - "artifactType": "application/vnd.cncf.helm.v3", + "artifactType": "application/vnd.cncf.helm.v3+json", "config": { "mediaType": "application/vnd.cncf.helm.config.v1+json", - "size": 0, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 0 }, "blobs": [ { - "mediaType": "application/vnd.cncf.helm.chart.v1.tar", + "mediaType": "application/tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654 - }, - { - "mediaType": "application/vnd.cncf.helm.values.v1.yaml", - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", - "size": 16724 } ], + "manifests": [], "references": [ { - "reference": "wordpress:5.7", - "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", - "size": 1510 + "size": 1510, + "annotations": { + "oci.distribution.artifact": "wordpress:5.7" + } }, { - "reference": "mysql:8", - "mediaType": "application/vnd.oci.image.manifest.v1.config.json", + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", - "size": 1578 + "size": 1578, + "annotations": { + "oci.distribution.artifact": "mysql:8" + } } ] } \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest-wordpress-image-signature.json b/artifact-manifest/artifact-manifest-wordpress-image-signature.json index 094ddab..e6fffcd 100644 --- a/artifact-manifest/artifact-manifest-wordpress-image-signature.json +++ b/artifact-manifest/artifact-manifest-wordpress-image-signature.json @@ -1,33 +1,28 @@ { - "schemaVersion": 2, + "schemaVersion": 1, "mediaType": "application/vnd.oci.artifact.collection.v1+json", - "artifactType": "application/vnd.cncf.notary.v2", + "artifactType": "application/vnd.cncf.notary.v2+json", "config": { - "mediaType": "application/vnd.cncf.notary.config.v2", + "mediaType": "application/vnd.cncf.notary.config.v2+json", "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", - "size": 0 + "size": 120 }, - "dependencies": [ + "blobs": [ { - "mediaType": "application/vnd.cncf.notary.v2.json", - "refType": "blob", + "mediaType": "application/tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", - "size": 32654, - "reference": "registry.wabbitnetworks.io" - }, + "size": 32654 + } + ], + "manifests": [ { - "mediaType": "application/vnd.oci.image.manifest.v1", - "digest": "wordpress@sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", - "size": 16724, - "linkType": "hard|soft", - "linkType": "parent|child", - "reference": "/wordpress:5.7" - }, - "links": [ - { - "mediaType": "application/vnd.oci.image.index.v1.config.json", - "refType": "manifest", - "reference": "/wordpress:5.7" - } - ] + "mediaType": "application/vnd.oci.image.index.v1.config+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } } \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest.json b/artifact-manifest/artifact-manifest.json deleted file mode 100644 index a197d91..0000000 --- a/artifact-manifest/artifact-manifest.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "schemaVersion": 2, - "mediaType": "application/vnd.oci.artifact.manifest.v1+json", - "config": { - "mediaType": "application/vnd.oci.artifact.manifest.config.v1+json", - "size": 7023, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" - }, - "blobs": [ - { - "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 32654, - "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0" - }, - { - "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 16724, - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" - }, - { - "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "size": 73109, - "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" - } - ], - "dependencies":[ - { - - } - ], - "references": [ - { - "mediaType": "image|index|signature|helm|CNAB|...", - "digest": "---", - "refType": "hard|soft" - }, - { - "mediaType": "image|index|signature|helm|CNAB|...", - "digest": "---", - "refType": "hard|soft" - }, - { - "mediaType": "image|index|signature|helm|CNAB|...", - "digest": "---", - "refType": "hard|soft" - } - ], - "annotations": { - "org.opencontainers.artifact.created": "", - "org.opencontainers.artifact.authors": "", - "org.opencontainers.artifact.url": "opencontainers.org", - "org.opencontainers.artifact.documentation": "opencontainers.org", - "org.opencontainers.artifact.source": "https://github.com/opencontainers/artifacts", - "org.opencontainers.artifact.version": "v1.0", - "org.opencontainers.artifact.revision": "v1.1.0", - "org.opencontainers.artifact.vendor": "Open Containers Initiative", - "org.opencontainers.artifact.licenses": "MIT", - "org.opencontainers.artifact.title": "Open Containers Artifact Manifest", - "org.opencontainers.artifact.description": "A schema for defining artifacts" - } -} \ No newline at end of file diff --git a/artifact-manifest/artifact-manifest.md b/artifact-manifest/artifact-manifest.md index d9a5a86..30d5bf0 100644 --- a/artifact-manifest/artifact-manifest.md +++ b/artifact-manifest/artifact-manifest.md @@ -68,11 +68,17 @@ products.wabbit-networks.io\ To support artifact movement, the content that constitutes an artifact to individually represent itself must be maintained within the same registry. For example, the layers of an container image, or the signature blob of a Notary v2 signature artifact. +### Dependencies on Blobs and Other Artifacts + +A class of of artifacts will have content (blobs) that represent the artifact (eg: Notary, SBoM), however they are extensions of another artifact (eg: container image) which are dependencies on other `manifests`. The other manifests could be any OCI supported manifest, including `image-manifest`, `image-index` and other `oci.artifact.manifest` references. + +All extension artifacts are stored without tags, and must be stored in the same repository as the artifact they are extending. + ### Deferred Resolution To support artifact movement to various registry and namespace structures, the registry and path must not be embedded within the artifact definition. Client CLIs and configurations will provide default locations and mappings for where to find the referenced content. -Artifacts that reference other artifacts must include an OCI Artifact Descriptor which includes the `manifest type`, `digest`, `size` and `repo:tag` of the artifact, however it will defer resolution of the reference to client tools that MAY reconstitute the references from multiple repositories and/or registries. +Artifacts that reference other artifacts must include an OCI Descriptor which includes the `manifest type`, `digest` and `size`. An annotation will include the `repo:tag`, which may be used to resolve the name of the artifact. The resolution is defered to client tools that MAY reconstitute the references from multiple repositories and/or registries. Clients MAY choose to bind to specific digests, assuring they are testing and using the exact graph initially specified. Or, clients may choose to float to a newer version of a tag, benefiting from patches. In all cases, a Notary v2 signature may be used to assure the artifacts are true to their initial ownership and authors. @@ -82,19 +88,21 @@ Artifact manifest is intended to support the following artifact types: ### OCI Image -An OCI Image is based on the oci-image-manifest. It's shown as a comparison to the examples below. +An OCI Image is based on the oci-image-manifest. It's shown as a comparison to the examples below that may depend upon, or reference OCI images. Note: all references below may be made to oci-index as well as oci-manifest. ![OCI Image](media/wordpress-image-layers.svg) -### Notary v2 Signature Persistance +### Notary v2 Signatures and SBoM Persistance -A Notary v2 signature would persist as a manifest with a config object and a signature, persisted as a blob. However, the signature has no value unto itself. A signature is applied to a given artifact. It's said to be dependent upon another artifact to be complete. +A Notary v2 signature, or an SBoM document would persist as a manifest with a config object and a signature, persisted as a blob. However, neither the signature, nor the SBoM have value unto themselves. A signature and SBoM extend a given artifact. They're considered as dependent upon another artifact to be complete. ![notary v2 signature](media/notaryv2-signature.svg) -The Notary v2 signature would reference an artifact, such as the `wordpress:v5` image above. Notice the directionality of the references. One or more signatures may be added to a registry after the image was persisted. While an image knows of it's layers, and a Notary v2 signature knows of its config and blob, the Notary v2 signature declares a dependency to the artifact it's signing. The visualization indicates the references through solid lines as these reference types are said to be hard references. Just as the layers of an OCI Image are deleted (*ref-counted -1*), the blobs of a signature are deleted (*ref-counted -1*) when the signature is deleted. Likewise, when an artifact is deleted, the signature would be deleted (*ref-counted -1*) as the signatures have no value without the artifact they are signing. +![SBoM document](media/sbom-document.svg) -![wordpress image with layers](media/wordpress-image-layers-sig.svg) +The Notary v2 signature and SBoM would reference an artifact, such as the `wordpress:v5` image above. Notice the directionality of the references. One or more signatures may be added to a registry after the image was persisted. While an image knows of it's layers, and a Notary v2 signature knows of its config and blob, the Notary v2 signature declares a dependency to the artifact it's signing. The visualization indicates the references through solid lines as these reference types are said to be hard references. Just as the layers of an OCI Image are deleted (*ref-counted -1*), the blobs of a signature are deleted (*ref-counted -1*) when the signature is deleted. Likewise, when an artifact is deleted, the signatures and SBoM would be deleted (*ref-counted -1*) as the signatures and SBoMs have no value without the artifact they are signing. + +![wordpress image with layers](media/wordpress-image-layers-sig-sbom.svg) ### Helm Charts & CNAB @@ -111,8 +119,8 @@ A CNAB may also be persisted with configuration information, along with a refere The main scenarios include: 1. Discovery of content within a registry for content listing through a CLI and visualizations. -1. Copying within and across registries. -1. Deletion management, providing information to de-dupe content with reference counting. +1. Copying within and across registries, with the option to copy loose references, if resolved. +1. Deletion management, providing information to de-dupe content with reference counting, and the option to delete loose references. 1. Support enhancing information related to existing content. Such as adding a Notary v2 signature or SBoM artifacts. 1. Validation, with required and optional references. @@ -169,29 +177,32 @@ The above commands account for the image manifest and the associated layers. Not } ``` -### Container Image, with Signatures +### Container Image, with Signatures and an SBoM ![mysql image copy](./media/mysql-with-sigs-copy.svg) -In this scenario, Notary v2 signatures have been added. Note the directionality of the Notary v2 signatures references. The `mysql:8` image has no reference to the signatures. The signatures may be added to existing artifacts. The signatures declare a reference `-->` to the `mysql:8` image. This assure the `mysql:8` image tag and digest need not change to support signatures added throughout the secured supply chain. +In this scenario, Notary v2 signatures have been added. Note the directionality of the Notary v2 signatures references. The `mysql:8` image has no reference to the signatures. The signatures may be added to existing artifacts. The signatures declare a reference `-->` to the `mysql:8` image. This assures the `mysql:8` image tag and digest need not change to support signatures, nor SBoMs added throughout the secured supply chain. -From a user experience perspective, copying a container from a public registry to a private registry would likely be expected to copy the signatures alongside the artifact they've signed. +From a user experience perspective, copying a container from a public registry to a private registry would likely be expected to copy the signatures alongside the artifact they've signed, as well as other extension artifacts like SBoMs. -The `oci.artifact.manifest` supports the Notary v2 requirements, including: +The `oci.artifact.manifest` supports the Notary v2 and SBoM requirements, including: - support for additive signatures, assuring the target manifest digest and tag do not change - support for multiple signatures. In the above scenario, `mysql` signed the original image. As `mysql` was copied to Docker Hub, an additional `docker community signature` was added, providing certified content attestation. Once the image copy to ACME Rockets is completed, an additional `acme-rockets signature` is added providing assurance the `mysql:8` image was security scanned and verified it's applicable to the ACME Rockets environment. From a user experience, the signature artifacts have no unique value beyond the artifact they represent, therefore they would be persisted to a registry in a form by which they are known to copy with the artifact, and be deleted when the artifact they are associated with is deleted. -To support hard references, an additional dependencies collection is added to a new `application/vnd.oci.artifact.manifest.v1+json` schema. The `dependencies` collection declares the artifact the signature is dependent upon. Similar to pypi packages, the validation of dependencies are deferred. If the dependent artifacts are found, they are valid. Depending on the validation options, a signature may exist without its dependent artifact. +To support hard references, an additional dependencies collection is added to a new `application/vnd.oci.artifact.manifest.v1+json` schema. The `manifests` collection declares the artifact the signature is dependent upon. **A Notary v2 signature of the `mysql:8` image example:** +> **OPTION A** + ```json { + "schemaVersion": 1, "mediaType": "application/vnd.oci.artifact.manifest.v1+json", - "artifactType": "application/vnd.cncf.notary.v2", + "artifactType": "application/vnd.cncf.notary.v2+json", "config": { "mediaType": "application/vnd.cncf.notary.config.v2+json", "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", @@ -199,7 +210,7 @@ To support hard references, an additional dependencies collection is added to a }, "blobs": [ { - "mediaType": "application/vnd.cncf.notary.signature.v2+json", + "mediaType": "application/tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654 } @@ -217,8 +228,41 @@ To support hard references, an additional dependencies collection is added to a "annotations": { "org.cncf.notary.v2.signature.subject": "docker.io" } +} ``` +> **OPTION B** + +```json +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 102 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} +``` In the above example, the signing entity is Docker, which is represented as a notary scoped annotation: `"org.cncf.notary.v2.signature.subject": "docker.io"` #### OCI-Registry CLI @@ -256,10 +300,13 @@ To support the loose references between artifacts, a `references` collection is **A `wordpress-chart:v5` Helm Chart example:** +> **OPTION A** + ```json { + "schemaVersion": 1, "mediaType": "application/vnd.oci.artifact.manifest.v1+json", - "artifactType": "application/vnd.cncf.helm.v3", + "artifactType": "application/vnd.cncf.helm.v3+json", "config": { "mediaType": "application/vnd.cncf.helm.config.v1+json", "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", @@ -267,41 +314,74 @@ To support the loose references between artifacts, a `references` collection is }, "blobs": [ { - "mediaType": "application/vnd.cncf.helm.chart.v1+tar", + "mediaType": "application/tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654 - }, - { - "mediaType": "application/vnd.cncf.helm.values.v1+yaml", - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", - "size": 16724 } ], "manifests": [ { - "mediaType": "application/vnd.oci.image.manifest.v1+json", + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", "size": 1510, "annotations": { "oci.distribution.relationship": "references", - "oci.distribution.artifact": "wordpress:5.7", - "oci.distribution.artifactType": "application/vnd.oci.image.v1" + "oci.distribution.artifact": "wordpress:5.7" } }, { - "mediaType": "application/vnd.oci.image.manifest.v1+json", + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", "size": 1578, "annotations": { "oci.distribution.relationship": "references", - "oci.distribution.artifact": "mysql:8", - "oci.distribution.artifactType": "application/vnd.oci.image.v1" + "oci.distribution.artifact": "mysql:8" } } ] } ``` +> **OPTION B** + +```json +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.helm.v3+json", + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 0 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [], + "references": [ + { + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510, + "annotations": { + "oci.distribution.artifact": "wordpress:5.7" + } + }, + { + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578, + "annotations": { + "oci.distribution.artifact": "mysql:8" + } + } + ] +} +``` #### CNAB Reference A CNAB is yet another reference artifact. While the current CNAB spec incorporates the helm-cli ahd helm chart within an invocation image, the `artifact.manifest` provides more natural package management experiences where the references can be resolved based on the users intent, while leveraging the capabilities of an OCI compliant registry to store all OCI Artifact types. @@ -312,53 +392,88 @@ Similar to the Helm example, a CNAB is copied from a public registry to the ACME As the `oci-reg copy` command is executed, the graph of references are expanded. As the copy proceeds, only those artifacts that don't already exist in the target registry are required to be copied. The references may be hard bound to the digest, or loosely bound to the `artifact:tag` enabling more recently patched versions of a given `artifact:tag`. The CNAB and Helm `artifact.manifest` may declare how strict they wish to couple their references to **stable tags** or **unique digests** +> **OPTION A** + ```json { + "schemaVersion": 1, "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "artifactType": "application/vnd.cncf.cnab.v1", "config": { "mediaType": "application/vnd.cncf.cnab.config.v1+json", - "size": 0, - "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 134 }, "blobs": [ { - "mediaType": "application/vnd.cncf.cnab.v1+tar", + "mediaType": "application/tar", "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", "size": 32654 - }, - { - "mediaType": "application/vnd.cncf.cnab.params.v1+json", - "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", - "size": 16724 } ], "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578, + "annotations": { + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "helm-cli:3" + } + }, { "mediaType": "application/vnd.oci.artifact.manifest.v1+json", "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", "size": 1510, "annotations": { "oci.distribution.relationship": "references", - "oci.distribution.artifact": "wordpress-chart:v5", - "oci.distribution.artifactType": "application/vnd.cncf.helm.v3" + "oci.distribution.artifact": "wordpress-chart:v5" } - }, + } + ] +} +``` + +> **OPTION B** + +```json +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.cnab.v1+json.", + "config": { + "mediaType": "application/vnd.cncf.cnab.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 134 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [], + "references": [ { - "artifact": "helm-cli:3", "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", "size": 1578, "annotations": { - "oci.distribution.relationship": "references", - "oci.distribution.artifact": "helm-cli:3", - "oci.distribution.artifactType": "application/vnd.oci.image.manifest.v1" + "oci.distribution.artifact": "helm-cli:3" + } + }, + { + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510, + "annotations": { + "oci.distribution.artifact": "wordpress-chart:v5" } } ] } ``` - ### Deletion Distribution-spec APIs will provide standard delete operations, including options for deleting referenced artifacts, or blocking a delete as the artifact is referenced by other artifacts. The `oci.artifact.manifest` collection will provide the information, as defined by the artifact author` for how an artifact should be handled for delete operations. The registry, nor the `oci-reg` cli would need to know about specific artifact implementations. @@ -374,52 +489,19 @@ The deletion scenarios include: - deleting the mysql image should warn if referenced by any helm charts. However, based on the parameters of the cli, it may delete images referenced by helm charts within the registry as these references are considered loose references and may be resolved externally to the registry. - deleting the wordpress helm chart, wordpress image, or mysql image would delete the associated signatures as the signatures have no value unto themselves. The `oci-reg` cli may accomplish these delete steps without any knowledge of Notary v2 spec as the `oci-reg` delete cli will follow the rules of the `oci.artifact.manifest` collections. -## OCI Artifact Manifest Content Descriptor - -The OCI Artifact Manifest content descriptor is enhanced with an additional `artifact` property enabling loose or hard references between artifact types. - -- **`mediaType`** *string* - - This property identifies the OCI schema of the manifest being referenced. - An OCI v_ compliant registry must support at least the following schemas: - - - `"application/vnd.oci.image.manifest.v1+json"` - - `"application/vnd.oci.image.index.v1+json"` - - `"application/vnd.oci.artifact.manifest.v1+json"` - -- **`digest`** *string* - - This REQUIRED property is the digest of the targeted content, conforming to the requirements outlined in Digests. Retrieved content SHOULD be verified against this digest when consumed via untrusted sources. - -- **`size`** *int64* - - This REQUIRED property specifies the size, in bytes, of the raw content. This property exists so that a client will have an expected size for the content before processing. If the length of the retrieved content does not match the specified length, the content SHOULD NOT be trusted. - -- **`artifact-type`** *string* - - This property defines the OCI Artifact Type. In previous versions of the OCI Artifact spec, this was defined with `manifest.config.mediaType`. This property is lifted and formalized in the `oci.artifact.manifest` enabling filtering of references to those of a given `artifact-type`, such as returning a list of Notary v2 signatures. - -- **`artifact`** *string* - - This property provides a reference to the `artifact:tag`, enabling floating to a newer/patched version of a tag. An OCI Artifact Manifest content descriptor must include the digest to assure a client may validate the initially referenced artifact, however this is a client choice for binding to a specific digest, or newer version based on the `artifact:tag` named reference. - ## OCI Artifact Collections OCI Artifact Manifests provide the following types of references: - **Blobs:** Content that represents the artifact. These are analogues to layers from the OCI Image manifest and Config objects. Layers are renamed blobs as they represent a generic collection of content, as opposed to an ordered layered collection as defined by OCI Image Manifest. An artifact may treat them as ordered, but it is not required. -- **Dependencies** on other artifacts that enhance the content, such as a Notary v2 signature or an SBoM. These dependencies are *unknown* by the original artifact as they are added at a later time. A registry would need to index these references as registry apis would request all content related to the source artifact. +- **Manifests** are dependent references to other artifacts that enhance the content, such as a Notary v2 signature or an SBoM. These dependencies are *unknown* by the original artifact as they are added at a later time. A registry would need to index these references as registry apis would request all content related to the source artifact. - **References** to other artifacts, used to complete a scenario, but may not be stored within the same repository or registry. These references are defined by the source artifact and known at the time of upload to a registry, such as a Helm chart that references other images. These references are included in the manifest and computed in the digest of the manifest. ### Blobs Collection -All blobs are considered to be hard dependencies that must be resolvable within a registry. An artifact is considered invalid if the manifest blobs are not resolvable. Registries MAY implement de-duping, using ref-counting to assure at least one copy of the blob is resolvable for any given `oci.artifact.manifest`. OCI Artifact blobs are generalizations of the OCI Image Spec layers definition. - -## Manifests Collection +All `blobs` are considered to be hard dependencies that must be resolvable within a registry. An artifact is considered invalid if the manifest blobs are not resolvable. Registries MAY implement de-duping, using ref-counting to assure at least one copy of the blob is resolvable for any given `oci.artifact.manifest`. OCI Artifact blobs are generalizations of the OCI Image Spec layers definition. -> **NOTE!** Update to consolidate the Dependencies and References collections - -### Dependencies Collection +### Manifests Collection Alternate names: @@ -427,7 +509,7 @@ Alternate names: - `parents` - `enhances` -The dependencies collection is an optional collection of references to other artifacts. The artifact is said to enhance the dependent artifacts by adding additional content. The content may be added after the initial content was created or pushed to a registry. By supporting additional content, the referenced artifact can be enhanced without having to change the referenced artifacts manifest, digest or tag. +The `manifests` collection is an optional collection of references to other artifacts. The artifact is said to enhance the dependent artifacts by adding additional content. The content may be added after the initial content was created or pushed to a registry. By supporting additional content, the referenced artifact can be enhanced without having to change the referenced artifacts manifest, digest or tag. Examples include: @@ -435,7 +517,7 @@ Examples include: - SBoM documents - Artifact Meta-data -Dependencies are collections of OCI Artifact Content Descriptors. +`manifests` are collections of Content Descriptors. ### References Collection @@ -479,6 +561,24 @@ This specification defines the following annotation keys, intended for but not l - **org.opencontainers.artifact.title** Human-readable title of the artifact (string) - **org.opencontainers.artifact.description** Human-readable description of the software packaged in the artifact (string) +```json +{ + "annotations": { + "org.opencontainers.artifact.created": "", + "org.opencontainers.artifact.authors": "", + "org.opencontainers.artifact.url": "opencontainers.org", + "org.opencontainers.artifact.documentation": "opencontainers.org", + "org.opencontainers.artifact.source": "https://github.com/opencontainers/artifacts", + "org.opencontainers.artifact.version": "v1.0", + "org.opencontainers.artifact.revision": "v1.1.0", + "org.opencontainers.artifact.vendor": "Open Containers Initiative", + "org.opencontainers.artifact.licenses": "MIT", + "org.opencontainers.artifact.title": "Open Containers Artifact Manifest", + "org.opencontainers.artifact.description": "A schema for defining artifacts" + } +} +``` + ## Open Questions -Should the references collection support additional types, like loose urls +1. Should the references collection support additional types, like loose urls diff --git a/artifact-manifest/media/mysql-with-sigs-copy.svg b/artifact-manifest/media/mysql-with-sigs-copy.svg index 295ba78..56969f5 100644 --- a/artifact-manifest/media/mysql-with-sigs-copy.svg +++ b/artifact-manifest/media/mysql-with-sigs-copy.svg @@ -1 +1 @@ -mysql:8MySQL signatureDocker community signatureACME Rockets signatureLayer1Layer2ACME Rocketsmysql:8MySQL signatureDocker community signatureACME Rockets signatureArtifact ImportLayer1Layer2 \ No newline at end of file +ACME Rocketsmysql:8MySQL signatureDocker community signatureACME Rockets signatureArtifact ImportLayer1Layer2SBoMDocumentSBoMmysql:8MySQL signatureDocker community signatureLayer1Layer2SBoMDocumentSBoM \ No newline at end of file diff --git a/artifact-manifest/media/sbom-document.svg b/artifact-manifest/media/sbom-document.svg new file mode 100644 index 0000000..1d99c8d --- /dev/null +++ b/artifact-manifest/media/sbom-document.svg @@ -0,0 +1 @@ +SBoMSBoMconfig-blobSBoM-document-blob \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-cnab.svg b/artifact-manifest/media/wordpress-cnab.svg index 7330757..d0d4300 100644 --- a/artifact-manifest/media/wordpress-cnab.svg +++ b/artifact-manifest/media/wordpress-cnab.svg @@ -1 +1 @@ -mysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturehelm-cli:v3Helm community signaturewordpress-chart:v5Helm community signaturewordpress-cnab:v5Helm community signature \ No newline at end of file +helm-cli:v3Helm community signaturewordpress-cnab:v5Helm community signaturemysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturewordpress-chart:v5Helm community signatureSBoMDocumentSBoMSBoMDocumentSBoMSBoMDocumentSBoMSBoMDocumentSBoMSBoMDocumentSBoM \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-helm-chart.svg b/artifact-manifest/media/wordpress-helm-chart.svg index 591ca72..790d937 100644 --- a/artifact-manifest/media/wordpress-helm-chart.svg +++ b/artifact-manifest/media/wordpress-helm-chart.svg @@ -1 +1 @@ -mysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturewordpress-chart:v5Helm community signature \ No newline at end of file +mysql:8MySQL signatureDocker community signatureACME Rockets signaturewordpress:v5Docker community signaturewordpress-chart:v5Helm community signatureSBoMDocumentSBoMSBoMDocumentSBoMSBoMDocumentSBoM \ No newline at end of file diff --git a/artifact-manifest/media/wordpress-image-layers-sig-sbom.svg b/artifact-manifest/media/wordpress-image-layers-sig-sbom.svg new file mode 100644 index 0000000..cce5559 --- /dev/null +++ b/artifact-manifest/media/wordpress-image-layers-sig-sbom.svg @@ -0,0 +1 @@ +wordpress:v5Docker community signatureLayer1Layer2ACME Rockets signatureSBoMDocumentSBoM \ No newline at end of file diff --git a/artifact-manifest/option-a/artifact-manifest-mysql-image-sbom.json b/artifact-manifest/option-a/artifact-manifest-mysql-image-sbom.json new file mode 100644 index 0000000..e30fcdd --- /dev/null +++ b/artifact-manifest/option-a/artifact-manifest-mysql-image-sbom.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.openssf.sbom.v1+json", + "config": { + "mediaType": "application/vnd.openssf.sbom.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 102 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724, + "annotations": { + "oci.distribution.relationship": "depends-on" + } + } + ], + "annotations": { + "openssf.sbom.author": "mysql" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-a/artifact-manifest-mysql-image-signature.json b/artifact-manifest/option-a/artifact-manifest-mysql-image-signature.json new file mode 100644 index 0000000..97b6e36 --- /dev/null +++ b/artifact-manifest/option-a/artifact-manifest-mysql-image-signature.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 102 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724, + "annotations": { + "oci.distribution.relationship": "depends-on" + } + } + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-a/artifact-manifest-wordpress-cnab-signature.json b/artifact-manifest/option-a/artifact-manifest-wordpress-cnab-signature.json new file mode 100644 index 0000000..298b97c --- /dev/null +++ b/artifact-manifest/option-a/artifact-manifest-wordpress-cnab-signature.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 1303 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724, + "annotations": { + "oci.distribution.relationship": "depends-on" + } + } + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-a/artifact-manifest-wordpress-cnab..json b/artifact-manifest/option-a/artifact-manifest-wordpress-cnab..json new file mode 100644 index 0000000..b63a52c --- /dev/null +++ b/artifact-manifest/option-a/artifact-manifest-wordpress-cnab..json @@ -0,0 +1,37 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.cnab.v1", + "config": { + "mediaType": "application/vnd.cncf.cnab.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 134 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578, + "annotations": { + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "helm-cli:3" + } + }, + { + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510, + "annotations": { + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "wordpress-chart:v5" + } + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/option-a/artifact-manifest-wordpress-helm-signature.json b/artifact-manifest/option-a/artifact-manifest-wordpress-helm-signature.json new file mode 100644 index 0000000..298b97c --- /dev/null +++ b/artifact-manifest/option-a/artifact-manifest-wordpress-helm-signature.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 1303 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724, + "annotations": { + "oci.distribution.relationship": "depends-on" + } + } + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-a/artifact-manifest-wordpress-helm.json b/artifact-manifest/option-a/artifact-manifest-wordpress-helm.json new file mode 100644 index 0000000..e8c9147 --- /dev/null +++ b/artifact-manifest/option-a/artifact-manifest-wordpress-helm.json @@ -0,0 +1,37 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.helm.v3+json", + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 0 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510, + "annotations": { + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "wordpress:5.7" + } + }, + { + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578, + "annotations": { + "oci.distribution.relationship": "references", + "oci.distribution.artifact": "mysql:8" + } + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/option-a/artifact-manifest-wordpress-image-signature.json b/artifact-manifest/option-a/artifact-manifest-wordpress-image-signature.json new file mode 100644 index 0000000..dba2e46 --- /dev/null +++ b/artifact-manifest/option-a/artifact-manifest-wordpress-image-signature.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 2, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 120 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724, + "annotations": { + "oci.distribution.relationship": "depends-on" + } + } + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-b/artifact-manifest-mysql-image-sbom.json b/artifact-manifest/option-b/artifact-manifest-mysql-image-sbom.json new file mode 100644 index 0000000..157adb6 --- /dev/null +++ b/artifact-manifest/option-b/artifact-manifest-mysql-image-sbom.json @@ -0,0 +1,28 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.openssf.sbom.v1+json", + "config": { + "mediaType": "application/vnd.openssf.sbom.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 102 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [], + "annotations": { + "openssf.sbom.author": "mysql" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-b/artifact-manifest-mysql-image-signature.json b/artifact-manifest/option-b/artifact-manifest-mysql-image-signature.json new file mode 100644 index 0000000..1848120 --- /dev/null +++ b/artifact-manifest/option-b/artifact-manifest-mysql-image-signature.json @@ -0,0 +1,28 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 102 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-b/artifact-manifest-wordpress-cnab-signature copy.json b/artifact-manifest/option-b/artifact-manifest-wordpress-cnab-signature copy.json new file mode 100644 index 0000000..41424cd --- /dev/null +++ b/artifact-manifest/option-b/artifact-manifest-wordpress-cnab-signature copy.json @@ -0,0 +1,27 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 1303 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-b/artifact-manifest-wordpress-cnab-signature.json b/artifact-manifest/option-b/artifact-manifest-wordpress-cnab-signature.json new file mode 100644 index 0000000..41424cd --- /dev/null +++ b/artifact-manifest/option-b/artifact-manifest-wordpress-cnab-signature.json @@ -0,0 +1,27 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 1303 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file diff --git a/artifact-manifest/option-b/artifact-manifest-wordpress-cnab..json b/artifact-manifest/option-b/artifact-manifest-wordpress-cnab..json new file mode 100644 index 0000000..d573d64 --- /dev/null +++ b/artifact-manifest/option-b/artifact-manifest-wordpress-cnab..json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.cnab.v1+json.", + "config": { + "mediaType": "application/vnd.cncf.cnab.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 134 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [], + "references": [ + { + "mediaType": "application/vnd.oci.image.manifest.v1+json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578, + "annotations": { + "oci.distribution.artifact": "helm-cli:3" + } + }, + { + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510, + "annotations": { + "oci.distribution.artifact": "wordpress-chart:v5" + } + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/option-b/artifact-manifest-wordpress-helm.json b/artifact-manifest/option-b/artifact-manifest-wordpress-helm.json new file mode 100644 index 0000000..496ab8d --- /dev/null +++ b/artifact-manifest/option-b/artifact-manifest-wordpress-helm.json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.manifest.v1+json", + "artifactType": "application/vnd.cncf.helm.v3+json", + "config": { + "mediaType": "application/vnd.cncf.helm.config.v1+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 0 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [], + "references": [ + { + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", + "digest": "sha256:5c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c82", + "size": 1510, + "annotations": { + "oci.distribution.artifact": "wordpress:5.7" + } + }, + { + "mediaType": "application/vnd.oci.image.manifest.config.v1+json", + "digest": "sha256:8c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c31", + "size": 1578, + "annotations": { + "oci.distribution.artifact": "mysql:8" + } + } + ] +} \ No newline at end of file diff --git a/artifact-manifest/option-b/artifact-manifest-wordpress-image-signature.json b/artifact-manifest/option-b/artifact-manifest-wordpress-image-signature.json new file mode 100644 index 0000000..e6fffcd --- /dev/null +++ b/artifact-manifest/option-b/artifact-manifest-wordpress-image-signature.json @@ -0,0 +1,28 @@ +{ + "schemaVersion": 1, + "mediaType": "application/vnd.oci.artifact.collection.v1+json", + "artifactType": "application/vnd.cncf.notary.v2+json", + "config": { + "mediaType": "application/vnd.cncf.notary.config.v2+json", + "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7", + "size": 120 + }, + "blobs": [ + { + "mediaType": "application/tar", + "digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0", + "size": 32654 + } + ], + "manifests": [ + { + "mediaType": "application/vnd.oci.image.index.v1.config+json", + "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b", + "size": 16724 + } + ], + "references": [], + "annotations": { + "org.cncf.notary.v2.signature.subject": "docker.io" + } +} \ No newline at end of file