<!--
This template is adapted from Kubernetes Enhancements KEP template https://raw.githubusercontent.com/kubernetes/enhancements/a86942e8ba802d0035ec7d4a9c992f03bca7dce9/keps/NNNN-kep-template/README.md
-->

# Push cert-manager Helm Charts to an OCI Registry

<!-- toc -->
- [Release Signoff Checklist](#release-signoff-checklist)
- [Summary](#summary)
- [Motivation](#motivation)
  - [Goals](#goals)
  - [Non-Goals](#non-goals)
- [Proposal](#proposal)
  - [Risks and Mitigations](#risks-and-mitigations)
- [Design Details](#design-details)
  - [Test Plan](#test-plan)
  - [Graduation Criteria](#graduation-criteria)
  - [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy)
  - [Supported Versions](#supported-versions)
- [Production Readiness](#production-readiness)
- [Drawbacks](#drawbacks)
- [Alternatives](#alternatives)
<!-- /toc -->

## Release Signoff Checklist

This checklist contains actions which must be completed before a PR implementing this design can be merged:

- [ ] This design doc has been discussed and approved
- [ ] Test plan has been agreed upon and the tests implemented
- [ ] Feature gate status has been agreed upon (whether the new functionality will be placed behind a feature gate or not)
- [ ] Graduation criteria is in place if required (if the new functionality is placed behind a feature gate, how will it graduate between stages)
- [ ] User-facing documentation has been PR-ed against the release branch in [cert-manager/website]

## Summary

<!--
This section is important for producing high-quality, user-focused
documentation such as release notes.

A good summary is probably around a paragraph in length.

[documentation style guide]: https://github.com/kubernetes/community/blob/master/contributors/guide/style-guide.md
-->

This design proposes to start pushing cert-manager's Helm charts to an OCI registry - `quay.io/jetstack`.

It proposes no other changes - specifically, after this design is implemented charts would still be pushed to their current location
- `charts.jetstack.io` - for every release.

## Motivation

<!--
This section is for explicitly listing the motivation, goals, and non-goals of
the proposed enhancement.  Describe why the change is important and the benefits to users. The
motivation section can optionally provide links to
demonstrate the interest in this functionality amongst the community.
-->

cert-manager's Helm charts are the primary way we encourage users to install the project. The same applies to sub-projects, each of which
has a Helm chart.

All Helm charts for all projects are currently hosted in a Helm repository available at `https://charts.jetstack.io`. This is primarily
for simplicity and for historical reasons - that location was the easiest back when we started building charts and there's been no pressing
need to change.

There is increasing pressure to change this. Firstly, there seems to be a movement away from Helm repositories in general.
There have been several [requests](https://github.com/cert-manager/cert-manager/issues/5566) for cert-manager to push charts to an OCI registry
and claims that certain tools no longer support Helm repositories.

Secondly, we're conscious of trying to replace references to any one company in the cert-manager projects and the use of the Jetstack
domain name is obviously in tension with that. cert-manager seeks to be an entirely [vendor-neutral](https://contribute.cncf.io/maintainers/community/vendor-neutrality/)
project and the use of this domain for charts is one of the few remaining places where the cert-manager project still references Jetstack.

While this proposal doesn't directly address this vendor-neutrality issue, it should make it simpler to address in the future as
migrating from one OCI registry to another should be simpler than migrating a repository.

The use of the `jetstack.io` domain also implies that Jetstack (now part of Venafi) has some say over access to this repo and who can push to it.
The company could reasonably request that have non-Venafi maintainers not be given access to the chart repo. This hasn't been a problem in practice
but the risk is not ideal for a project which seeks to encourage contributors from any company.

In addition, Venafi uses `charts.jetstack.io` for other, non-CNCF, charts. Access controls over who can push to the Helm repo are well
established and require code reviews, but given cert-manager's size and wide level of adoption it would be prudent to isolate it from
other unrelated projects. This mixing [has caused issues](https://github.com/cert-manager/cert-manager/issues/7117) for users.

### Goals

<!--
List specific goals. What is this proposal trying to achieve? How will we
know that this has succeeded?
-->

- Have charts be pullable from an OCI registry
- Force no change on users but give them the option to change to OCI registries

### Non-Goals

<!--
What is out of scope for this proposal? Listing non-goals helps to focus discussion
and make progress.
-->

- Change anything about `charts.jetstack.io`
- Force anyone to change where they get their charts

## Proposal

<!--
This is where we get down to the specifics of what the proposal actually is.
What is the desired outcome and how do we measure success?
This should have enough detail that reviewers can understand exactly what
you're proposing, but should not include things like API designs or
implementation - those should go into "Design Details" below.
-->

### Risks and Mitigations

<!--
What are the risks of this proposal, and how do we mitigate? Think broadly.
For example, consider both security and how this will impact the larger
Kubernetes/PKI ecosystem.
-->

### Risk 1

Since this proposal is only to add a new source for fetching Helm charts, there are few risks anticipated.

One potential risk is that our current approach for signing Helm charts might need to be tweaked. We currently produce
"detached" `.prov` signature files for cert-manager which are served on `charts.jetstack.io` alongside the charts
themselves.

Some experimentation may be required to work out how these detached signatures work with OCI registries. This isn't
urgent, as we'll continue to serve the signatures on our existing chart repository and there are other methods of
signing available with OCI registries - notably, using sigstore / cosign. Note that the detached signatures are only
relevant for cert-manager itself and not subprojects.

### Risk 2

Changing cmrel will apply to future releases of cert-manager (v1.16.x) but also to past releases. Unless we make
efforts to tag a cmrel version which doesn't push charts to OCI registries, or otherwise disable the pushing of
charts for older cert-manager releases, we'll start pushing charts to OCI registries if we do a patch release of an
existing supported cert-manager version.

This risk is minimal since - once again - the new registry won't be a default.

## Design Details

<!--
This section should contain enough information that the specifics of your
change are understandable. This may include API specs (though not always
required) or even code snippets. If there's any ambiguity about HOW your
proposal will be implemented, this is the place to discuss them.
-->

First, we'll create a new repository in quay.io, called `quay.io/jetstack/charts`.

Next, add a new step to the release process which pushes Helm charts to an OCI registry. This would be a code change in cmrel.

Once this publishing step is confirmed to work for new charts, we'll write a small one-off script which pushes all older versions
of the chart to the new registry, or else find some off-the-shelf script to do the same thing.

### Test Plan

<!---
Describe how the new functionality will be tested (unit tests, integration tests (if applicable), e2e tests)
-->

Once the changes to cmrel are made, we should be able to do an alpha release of cert-manager v1.16.0 and install
cert-manager locally in a kind cluster using the chart from the OCI registry.

### Graduation Criteria

Obviously no feature gates will apply to this change.

Once all cert-manager charts are pushed to the new registry and all older cert-manager charts are mirrored,
there'll be future work to publish subproject charts and the related mirroring of those charts. This design
does not attempt to solve that problem, and focuses on cert-manager first.

### Upgrade / Downgrade Strategy

<!--
Will this feature affect upgrade/downgrade of cert-manager?
-->

N/A

### Supported Versions

<!--
What versions of Kubernetes (and other external services if applicable) will this feature support?
-->

N/A

## Production Readiness
<!--
This section should confirm that the feature can be safely operated in production environment and can be disabled or rolled back in case it is found to increase failures.
-->

N/A

### Does this feature depend on any specific services running in the cluster?

<!--
For example, are external dependencies such as ingress controllers, third party CRDs etc required for this feature to function?
-->

N/A

### Will enabling / using this feature result in new API calls (i.e to Kubernetes apiserver or external services)?

<!--
We should ensure that cert-manager does not hammer any external services with excessive calls.
Consider whether there will be sufficient backoff if any external calls fail and need to be retried.
-->

N/A

### Will enabling / using this feature result in increasing size or count of the existing API objects?

<!--
For example, will cert-manager `CustomResourceDefinition`s increase in size, will there be more `Secret`s or `CertificateRequest`s created?
-->

N/A

### Will enabling / using this feature result in significant increase of resource usage? (CPU, RAM...)

<!--
For example, will implementing this feature result in more objects being cache thus increasing memory consumption?
-->

N/A

## Drawbacks

<!--
Why should this proposal _not_ be implemented?
-->

This proposal does not remove or break any functionality for users. For maintainers, pushing to multiple repositories would make gathering pull metrics more complex.

## Alternatives

<!--
What other approaches did you consider, and why did you rule them out? These do
not need to be as detailed as the proposal, but should include enough
information to express the idea and why it was not acceptable.
-->

A reasonable alternative to using OCI registries would be for the cert-manager project to host its own
Helm chart repository (e.g., `charts.cert-manager.io`).

This would require running additional infrastructure (similar to what `charts.jetstack.io` does), and would
not be satisfactory for those users who've been asking for an OCI registry for compatibility reasons.

In short, running a repo seems to be more work for less gain than pushing to an OCI registry.
