Skip to content

Latest commit

 

History

History
253 lines (167 loc) · 12.6 KB

hip-0006.md

File metadata and controls

253 lines (167 loc) · 12.6 KB
hip title authors created type status
0006
OCI Support
Josh Dolitsky
2020-07-21
feature
accepted

Abstract

This feature proposal outlines a concrete plan for finalizing Helm's OCI integration, which has been available as an experimental feature since Helm 3.0.0.

Motivation

Until now, all OCI integration has been kept separate from the existing Helm user experience, and nested under the helm chart and helm registry subcommands. These subcommands were designed to mimic the user experience of the Docker CLI. For example, helm chart list is the equivalent of docker images.

While this experimental feature set has succeeded in providing a "Docker-like" user experience, it is too far removed from existing Helm features and should be partially redesigned.

In addition, there has not yet been a clear response to the following questions concerning Helm's OCI support:

  • What is the relationship between a chart version and registry tag?
  • Will this work with helm install / helm upgrade / helm dependency?
  • How will provenance files (.prov) be supported?
  • When will the experimental flag be removed?

Rationale

The true value of leveraging OCI specs has very little to do with the command-line experience (i.e. Docker). OCI registries provide a common API for all types of packages, and address several security and scalability concerns. Additionally, many companies and organizations have invested in the infrastructure surrounding their container registry. Storing Helm charts in a registry reduces the number of moving parts.

By making Helm's OCI support more closely aligned with the way that Helm currently works, users will have a more stable experience and still benefit from the advantages of OCI.

Specification

The specification for this HIP is broken into six (6) major sections:

  1. Implement Getter and introduce Pusher
  2. Support for provenance files
  3. Chart versions == OCI reference tags
  4. Chart names == OCI reference basenames
  5. Cache is removed
  6. helm chart is removed, integrated into rest of CLI
  7. Experimental until clear messaging from OCI

1. Implement Getter and introduce Pusher

As of yet, the code related to registry support has been written standalone (see internal/experimental/registry).

The act of downloading a chart from an OCI registry should mimic what is already possible using downloader plugins. Using the protocol prefix oci:// in any place where chart repos are referenced should work just by implementing a Getter for OCI.

Currently there is no Helm-specific way to upload chart packages. Using the same model of Getter, a new interface called Pusher should be introduced, with a single built-in implementation (OCI). This opens the door for plugins to implement their own upload mechanism, and for Helm to add a new top-level upload command helm push. For example, plugins may include a new uploaders section in plugin.yaml, similar to the existing downloaders section (see "Downloader Plugins").

This will also include a new, top-level subcommand, helm push, which will leverage this new functionality. This command will take, as its first argument, the path to a chart archive (.tgz), and as the second argument a URL pointing to a remote OCI registry.

Here is an example of what the helm push UX will look like:

$ helm create mychart
Creating mychart

$ helm package mychart/
Successfully packaged chart and saved it to: /home/user/mychart-0.1.0.tgz

$ helm push mychart-0.1.0.tgz oci://example.com/some/root/namespace
The push refers to repository [oci://example.com/some/root/namespace/mychart]
ref:     oci://example.com/some/root/namespace/mychart:0.1.0
digest:  1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617
size:    2.4 KiB
name:    mychart
version: 0.1.0
0.1.0: pushed to remote (1 layer, 2.4 KiB total)

2. Support for provenance files

Helm currently has the ability to verify package signatures, assuming the presence of a file suffixed with .prov sitting next to a chart .tgz in a repository.

Support for this method of signature validation should be carried over into OCI storage. As the format of the OCI manifest is custom to Helm, Helm can also choose to modify the resulting manifest on upload when a chart is being signed (e.g. helm push --sign).

As far as the low-level details, the .prov file will simply be stored as another layer on the manifest. If running helm pull --verify oci://..., the layer containing the provenance file will be retrieved from the registry. The order and total number of layers on the manifest is not significant. The list of layers will be inspected, and the first one found matching the media type of the provenance file will be used. If multiple layers containing the provenance file media type are found, an error will occur. The same applies to the chart layer.

Here is an example of what a manifest will look like with a provenance file attached:

{
  "schemaVersion": 2,
  "config": {
    "mediaType": "application/vnd.cncf.helm.config.v1+json",
    "digest": "sha256:8ec7c0f2f6860037c19b54c3cfbab48d9b4b21b485a93d87b64690fdb68c2111",
    "size": 117
  },
  "layers": [
    {
      "mediaType": "application/vnd.cncf.helm.chart.content.v1.tar+gzip",
      "digest": "sha256:1b251d38cfe948dfc0a5745b7af5ca574ecb61e52aed10b19039db39af6e1617",
      "size": 2487
    },
    {
      "mediaType": "application/vnd.cncf.helm.chart.provenance.v1.prov",
      "digest": "sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a",
      "size": 643
    }
  ]
}

3. Chart versions == OCI reference tags

To keep things simple, the version of a chart will be 1-to-1 with the tag used on registry references. Arbitrary tags will not be supported.

This also means that tags are no longer necessary to be provided on the command-line in the form <ref>:<tag>. Instead, users can provide --version <version>.

4. Chart names == OCI reference basenames

Again, to keep things simple, the basename (the last segment of the URL path) on a registry reference should be equivalent to the chart name.

For example, given a chart with the name pepper and the version 1.2.3, users may run a command such as the following:

$ helm push pepper-1.2.3.tgz oci://r.myreg.io/mycharts

which would result in the following reference:

oci://r.myreg.io/mycharts/pepper:1.2.3

By placing such restrictions on registry URLs and tags, Helm users are less likely to do "strange things" with charts in registries.

5. Cache is removed

Since chart packages are small in size (<1mb), the cache is hard to justify. The cache was introduced only to provide a "Docker-like" experience. While this is neat, it does not provide the user with much value.

By removing the cache, much of the existing OCI features can be cut down dramatically in size. This will make OCI features much more seamless with the existing Helm user experience.

6. helm chart is removed, integrated into rest of CLI

Wherever possible, the subcommands provided by the new helm chart command should be integrated into existing Helm CLI commands.

helm chart pull should be baked into helm pull, helm chart push should be helm push (new).

Commands that work with the cache will be removed: helm chart save, helm chart remove and helm chart export.

helm registry will be kept as is. This manages auth against OCI registries.

7. Experimental until clear messaging from OCI

Considering that the rest of the items above are implemented and resolved, the OCI feature set will not be made generally available until there is clear messaging from the Open Container Initiative (OCI) regarding the way that Helm is using registries.

The technical details of how Helm is using the OCI distribution spec must be further validated. It is currently unclear whether or not this is the correct way to publish an arbitrary artifact. Only after more clarity will these features be taken out of experimental mode and made generally available.

Backwards compatibility

Since the existing feature set is currently experimental, there will be no promise of backwards compatibility with prior OCI support (sorry!)

Security implications

Registry authentication introduces a new attack vector. Upon running helm registry login, these credentials can possibly be stored in an unencrypted JSON file. However, if your system supports Docker's credential helpers (such as osxkeychain), then no crendetials are stored in this file. Credentials are stored elsewhere, such as in the system's secure keychain.

Here is an example of a registry config file using a credential helper:

{
	"auths": {
		"example.com": {}
	},
	"credsStore": "osxkeychain"
}

Here is an example of a registry config file without a credential helper:

{
	"auths": {
		"example.com": {
			"auth": "<password>",
			"email": "<username>"
		}
	}
}

So, while a new attack vector has been introduced, it should not be considered any less safe than using docker login. In fact, he underlying code is leveraging docker/cli, and existing logins created with docker login are leveraged if not found in Helm's config.

Note: this is already implemented in the current OCI feature set.

How to teach this

Following the implementation of all facets of this HIP, extensive documentation should be added to the Helm website on how to leverage OCI.

Additionally, sites containing community charts, such as Artifact Hub, should enable providers to distribute charts over OCI, and display friendly copy-paste instructions for how to download an OCI-based chart.

Helm and charts maintainers should be educated on how to make a transition from classic chart repositories to registries. In short the workflow for uploading a chart goes from helm package (+ custom upload) to helm package && helm registry login && helm push.

Reference implementation

The features are currently under development.

Here are the following outstanding tasks:

  • We need to implement helm push, which does not exist
  • Helm needs to implement OCI Getter support so that helm dependency and helm pull can support OCI registries (see helm/helm#8843)
  • Support for provenance files must be added
  • helm chart save, helm chart export, helm chart list, helm chart remove, helm chart pull, and helm chart push need to be removed
  • The Helm documentation for OCI support needs to be updated (https://helm.sh/docs/topics/registries/))

Rejected ideas

Will I be able to use custom tags such as "latest"?

The implications of this are not yet fully understood. For now, it will be strictly enforced that the tag on the reference will match the version found in Chart.yaml. This functionality may be added at a later time.

Will I be able to pull a chart using the :<tag> syntax?

It's unclear if users will be able to pull charts with a specific version using the :<tag> syntax (vs. --version <version>). This seems relatively harmless to allow both, but this may have implications on dependencies and other areas.

Open issues

The issues below are still unresolved.

What is the correct media type to use for the chart content layer?

The media type for the chart content layer is currently application/tar+gzip, however it has been pointed out that this is not an official type in the IANA database.

Due to this, a unique media type will be used: application/vnd.cncf.helm.chart.content.v1.tar+gzip.

The only real issue with this is that the chart package is not technically a unique type. As in, a registry vendor could treat it as a typical gzipped tarball.

What is the correct media type to use for the provenance file layer?

Again, there doesn't appear to be an IANA media type for this type of file. Additionally, this file format appears unique to Helm.

In this case, it seems the only option is to use a custom media type such as application/vnd.cncf.helm.chart.provenance.v1.prov.

References

The following links are used as references in this HIP: