hip | title | authors | created | type | status | |
---|---|---|---|---|---|---|
0006 |
OCI Support |
|
2020-07-21 |
feature |
accepted |
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.
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?
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.
The specification for this HIP is broken into six (6) major sections:
- Implement
Getter
and introducePusher
- Support for provenance files
- Chart versions == OCI reference tags
- Chart names == OCI reference basenames
- Cache is removed
helm chart
is removed, integrated into rest of CLI- Experimental until clear messaging from OCI
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)
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
}
]
}
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>
.
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.
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.
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.
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.
Since the existing feature set is currently experimental, there will be no promise of backwards compatibility with prior OCI support (sorry!)
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.
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
.
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
, andhelm chart push
need to be removed- The Helm documentation for OCI support needs to be updated (https://helm.sh/docs/topics/registries/))
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.
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.
The issues below are still unresolved.
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.
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
.
The following links are used as references in this HIP: