Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial draft for registry specification #362

Merged
merged 1 commit into from
Jul 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 000-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ weight: 001
- [Repositories](803-repositories.md)
- [Well known custom actions](804-well-known-custom-actions.md)
- [Disconnected Scenarios](805-airgap.md)
- [Known implementations for CNAB Registries](807-registries-known-implementations.md)
- [Well known custom extensions](810-well-known-custom-extensions.md)
6. Process Documentation
- [Specification Process](901-process.md)
26 changes: 26 additions & 0 deletions 200-CNAB-registries.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ weight: 200
---

# CNAB Registries 1.0

Draft, Feb. 2020

![cnab-registry](https://user-images.githubusercontent.com/686194/61753147-2b387a80-ad63-11e9-8a63-f250bcdf06b0.png)
Expand All @@ -15,3 +16,28 @@ This specification describes how CNAB bundles can be stored inside of OCI Regist
This specification, the CNAB Registries specification, is not part of the CNAB Core specification. An implementation of CNAB Core MAY NOT implement this specification, yet still claim compliance with CNAB Core. A CNAB implementation MUST NOT claim to be CNAB Registries-compliant unless it meets this specification.

> Previous versions of the CNAB Core draft specification included a repository protocol. That work is completely superseded by this specification.

The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). The use of these keywords in this document are statements about how a CNAB implementation may fulfill the CNAB registry storage specification only.

The CNAB Core 1.0 specification (CNAB1) does not dictate how bundles should be distributed. This is intentional, so that organizations that already have a way of distributing artifacts may continue to use it.
This document, the CNAB Registries specification, is not part of the core specification, and an implementation of CNAB Core MAY NOT implement it, yet still claim compliance with CNAB Core. A CNAB implementation MUST NOT claim to be CNAB Registries compliant unless it meets this specification.

This specification proposes the use of [OCI registries][oci-org] to distribute CNAB artifacts.

## Approach

Container registries provide a reliable and highly scalable distribution for container images. Implementations of container registries can be found in cloud provider services, vendor services, and open source projects. More and more artifact types are distributed with OCI registries, with the process standardized by the [OCI Artifacts][artifacts] project.

A Cloud Native Application Bundle is a collection of metadata and container images that are needed in order to successfully deploy an application - as such, it is not a _single_ new artifact, but represents a _collection of multiple artifacts_.

An [OCI image index (or simply OCI index)][oci-index] represents a collection of container images stored in a repository - so rather than using a new artifact, this specification proposes reusing the OCI index to represent Cloud Native Application Bundles, and use it as a natural distribution mechanism for the bundle file, invocation image, and images used by the application.

The approach of this specification is to reuse the existing distribution infrastructure for OCI artifacts when distributing CNAB bundles, to ensure compatibility with the CNAB Security specification, and to enable workflows such as the relocation of bundles and images.

In the following sections, we will explore [the representation of bundles in OCI registries](201-representing-CNAB-in-OCI.md) and [on disk representations](210-on-disk-representation.md).

[oci-org]: https://github.com/opencontainers/
[artifacts]: https://github.com/opencontainers/artifacts
[oci-index]: https://github.com/opencontainers/image-spec/blob/master/image-index.md
[oci-manifest]: https://github.com/opencontainers/image-spec/blob/master/manifest.md
radu-matei marked this conversation as resolved.
Show resolved Hide resolved
[docker-manifest]: https://docs.docker.com/registry/spec/manifest-v2-2/
128 changes: 128 additions & 0 deletions 201-representing-CNAB-in-OCI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
title: Representing CNAB bundles in OCI Registries
weight: 201
---

# Representing CNAB bundles in OCI Registries

This section describes how the bundle file and the information contained in the bundle MUST be represented when distributing bundles using OCI registries.

A CNAB is made up of a descriptor file (`bundle.json`), one or more invocation images, and a list of zero or more component images. Each of these objects can be individually packaged into an [OCI manifest][oci-manifest] or [OCI index][oci-index]. An OCI index can then be used to combine these all into a single object.
carolynvs marked this conversation as resolved.
Show resolved Hide resolved

Runtimes and registries MAY choose to _relocate_ the images and invocation images referenced in the bundle to the registry where the bundle is pushed, but in its simplest form, a CNAB bundle MAY be represented in an OCI registry by the canonical `bundle.json` file descriptor, referenced in an OCI index (or manifest list).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be "to the repository where the bundle is pushed"? That's what cnab-to-oci does right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would leave this discussion open, as both are valid and different use cases.


![](https://i.imgur.com/PfTcKOm.png)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting! Would like to discuss this at the next Security/Registry meeting to make sure I fully understand the proposal here.


### `bundle.json` manifest

The `bundle.json` MUST be serialized as canonical JSON and MUST be stored in the registry as a blob. This blob MUST be referenced by its digest in an OCI manifest. The manifest media type SHOULD be `application/vnd.cnab.bundle.config.v1+json` but MAY be a standard container image config type (`application/vnd.oci.image.config.v1+json`) if the target registry does not support the CNAB media type.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit/question: is application/vnd.cnab.bundle.config.v1+json redundant? We've been using application/vnd.cnab.config.v1+json internally. I can see the former being nice if we add more cnab-scoped artifact types in the future though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think at this point we should follow the guidance in the OCI Artifacts repository.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #381 to track this.

carolynvs marked this conversation as resolved.
Show resolved Hide resolved

### Example

The following non-canonical `bundle.json` file will be used as an example:

```json
{
"schemaVersion": "v1.0.0",
"name": "helloworld",
"version": "0.1.1",
"description": "A short description of your bundle",
"keywords": ["helloworld", "cnab", "tutorial"],
"maintainers": [
{
"name": "Jane Doe",
"email": "[email protected]",
"url": "https://example.com"
}
],
"invocationImages": [
{
"imageType": "docker",
"image": "cnab/helloworld:0.1.1",
"size": 942,
"contentDigest": "sha256:a59a4e74d9cc89e4e75dfb2cc7ea5c108e4236ba6231b53081a9e2506d1197b6",
"mediaType": "application/vnd.docker.distribution.manifest.v2+json"
}
],
"images": null,
"parameters": null,
"credentials": null
}
```

The `bundle.json` is serialized into canonical JSON and is pushed as a blob to the registry. This blob is then referenced by its digest (for example `sha256:e91b9dfcbbb3b88bac94726f276b89de46e4460b55f6e6d6f876e666b150ec5b`) as the object config.

The bundle is encapsulated in an OCI manifest which is then referenced as part of an OCI index (or manifest list):

```json
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.cnab.bundle.config.v1+json",
"digest": "sha256:e91b9dfcbbb3b88bac94726f276b89de46e4460b55f6e6d6f876e666b150ec5b",
"size": 498
},
"layers": null
}
```

The bundle file MUST be stored in the OCI registry, as it is the canonical representation of a CNAB bundle, and is the object that is used to compute the signature for a thin bundle.
While implementations MAY choose to surface information from the bundle as top-level annotations in the OCI representations, they MUST store the unmodified bundle file as a blob.

The bundle file and registry location MAY be used by implementations to generate relocation maps at runtime.

### Invocation images

Each invocation image SHOULD be packaged as an OCI image but MAY be packaged as a Docker v2 image. If there are multiple invocation images, these SHOULD be referenced by an OCI index but MAY be referenced by a Docker manifest list.

### Component images

Each component image SHOULD be packaged as an OCI image but MAY be packaged as a Docker v2 image. In the case that a component has multiple equivalent forms, such as a multiarch container image, each component MUST be packaged and then SHOULD be referenced by an OCI index but MAY be referenced by a Docker manifest list.

## Top-level representation

The top-level representation of the CNAB SHOULD be an OCI index but may be a Docker manifest list.

The `manifests` list MUST be filled in the following order:

- A reference to packaged `bundle.json` manifest
- References to the invocation images
- References to the component images

### Example
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, sorry, I'm confused. The example doesn't seem to match the preceding prescription, but I might just be missing something. Could someone please explain?

Copy link
Member Author

@radu-matei radu-matei Jul 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is happening because the example itself only contains the reference to bundle.json and an invocation image, but it does follow this structure.

We could probably update this later with a more complete example.


```json
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:6ec4fd695cace0e3d4305838fdf9fcd646798d3fea42b3abb28c117f903a6a5f",
"size": 188,
"annotations": {
"io.cnab.manifest.type": "config"
}
},
{
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:a59a4e74d9cc89e4e75dfb2cc7ea5c108e4236ba6231b53081a9e2506d1197b6",
"size": 942,
"annotations": {
"io.cnab.manifest.type": "invocation"
}
}
],
"annotations": {
"io.cnab.keywords": "[\"helloworld\",\"cnab\",\"tutorial\"]",
carolynvs marked this conversation as resolved.
Show resolved Hide resolved
"io.cnab.runtime_version": "v1.0.0",
"org.opencontainers.artifactType": "application/vnd.cnab.manifest.v1",
"org.opencontainers.image.authors": "[{\"name\":\"Jane Doe\",\"email\":\"[email protected]\",\"url\":\"https://example.com\"}]",
"org.opencontainers.image.description": "A short description of your bundle",
"org.opencontainers.image.title": "helloworld",
"org.opencontainers.image.version": "0.1.1"
}
}
```

[oci-index]: https://github.com/opencontainers/image-spec/blob/master/image-index.md
[oci-manifest]: https://github.com/opencontainers/image-spec/blob/master/manifest.md
8 changes: 8 additions & 0 deletions 210-on-disk-representation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: On Disk Representation of a CNAB bundle
weight: 210
---

# On Disk Representation of a CNAB bundle

TODO:
radu-matei marked this conversation as resolved.
Show resolved Hide resolved
8 changes: 8 additions & 0 deletions 807-registries-known-implementations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Known implementations of CNAB Registry
weight: 807
---

TODO:

As of July 2020, [the list of known container registries that support CNAB bundles can be found on the CNAB website](https://cnab.io/registries/).