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

# Push image artifacts to multiple repositories


<!-- toc -->
- [Release Signoff Checklist](#release-signoff-checklist)
- [Summary](#summary)
- [Motivation](#motivation)
  - [Goals](#goals)
  - [Non-Goals](#non-goals)
- [Proposal](#proposal)
  - [User Stories (Optional)](#user-stories-optional)
    - [Story 1](#story-1)
    - [Story 2](#story-2)
  - [Notes/Constraints/Caveats (Optional)](#notesconstraintscaveats-optional)
  - [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
-->
The cert-manager project, along with its sub-projects, currently utilizes the quay.io/jetstack registry for pushing OCI (Open Container Initiative) artifacts. This originates from the project's beginnings under Jetstack. However, to reflect the project's growth and establish a more neutral and independent identity, this proposal recommends adding a new OCI artifact registry location without the Jetstack branding.

## 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.
-->
The primary motivation for this enhancement is to reinforce the independence and neutrality of the cert-manager project. Originally developed by Jetstack, cert-manager currently pushes OCI artifacts to the quay.io/jetstack registry. As the project has grown and evolved into a community-driven initiative, it is essential to establish a neutral artifact repository that better represents the project's diverse and independent nature.

### Goals

<!--
List specific goals. What is this proposal trying to achieve? How will we
know that this has succeeded?
-->
- Decouple the cert-manager project from Jetstack’s branding to highlight its status as a community-driven project.
- Ensure all project documentation reflects the new registry to guide users appropriately without disrupting existing workflows.
- Continue pushing artifacts to the current quay.io/jetstack registry to avoid breaking changes for existing users while transitioning to the new registry.

### Non-Goals

<!--
What is out of scope for this proposal? Listing non-goals helps to focus discussion
and make progress.
-->
- This proposal does not aim to immediately deprecate the quay.io/jetstack registry but to introduce an additional registry.
- No changes to the functionality or features of cert-manager are included in this proposal.

## 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.
-->

### User Stories (Optional)

<!--
Detail the things that people will be able to do if this proposal gets implemented.
Include as much detail as possible so that people can understand the "how" of
the system. The goal here is to make this feel real for users without getting
bogged down.
-->

#### Story 1

*As a* new user of cert-manager, *I want to* find clear documentation that directs me to the appropriate registry for downloading OCI artifacts, *so that* I can easily set up and use cert-manager in my environment without confusion about which registry to use.

Details:

- The updated documentation prominently lists the new neutral registry URL.
- The documentation includes notes that the artifacts are also available in the quay.io/jetstack registry for backward compatibility.

#### Story 2

*As an* existing user of cert-manager, *I want to* continue receiving updates from the quay.io/jetstack registry while gradually transitioning to the new registry, *so that* my current setup remains functional without immediate changes, giving me time to update my configurations.

Details:

- Artifacts continue to be pushed to both the quay.io/jetstack and the new registry.
- A clear migration guide is provided, explaining how to switch to the new registry at a convenient time.

### Notes/Constraints/Caveats (Optional)

<!--
What are the caveats to the proposal?
What are some important details that didn't come across above?
Go into as much detail as necessary here.
This might be a good place to talk about core concepts and how they relate.
-->

### 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:* The new registry might introduce security vulnerabilities, such as unauthorized access to artifacts.

*Mitigation:*
- Existing CI/CD will be used to publish images, this is proven and secure. 
- The new registry should have the same access control restrictions as the current quay.io/jetstack registry - ensuring that only maintainers have write access.

## 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.
-->
To implement the transition to a new OCI artifact registry, our existing CI/CD pipeline will be updated to push artifacts to both the existing quay.io/jetstack registry and the new registry. This dual-publishing approach ensures continuity and minimizes disruption for current users. We are considering multiple options for the new registry, with "ghcr.io/cert-manager" (GitHub Container Registry) and "quay.io/cert-manager" being the primary candidates. The final registry will be chosen based on community feedback on this proposal. Regardless of the registry, we will also need to update the CI pipeline to authenticate with the new registry, ensuring secure and seamless artifact uploads.

Within projects using makefile modules we may need to make changes to the [OCI publish module](https://github.com/cert-manager/makefile-modules/tree/main/modules/oci-publish) to handle cases where we need different auth for different registries. After this, the pushing to multiple destinations is already supported by this module and would be a simple change to the config of each repos.

A new E2E tests run should be performed by our nightly automation that runs the E2E suite against the new registry, to ensure that everything is working as expected.

Once the images are being dual published, the official documentation and Helm chart will be updated to reflect the new repository.

### Test Plan

<!---
Describe how the new functionality will be tested (unit tests, integration tests (if applicable), e2e tests)
-->
By using existing automation that runs the E2E test suite each night we can add automated tests that will pull from the new registry. This tests multiple versions so is a good baseline that the image can be pulled.

### Graduation Criteria

<!--

Describe whether the proposed functionality will be feature gated and why (or why not).

Define graduation milestones and criteria if it should be feature-gated.

Feature maturity is defined using stages alpha, beta, GA.
Feature-gated functionality starts off at alpha and graduates through stages following the defined graduation criteria.
A feature that is in alpha or beta must be opt-in.

Example graduation criteria:

Alpha:

- Feature implemented behind a feature flag
- It is clearly defined which Kubernetes versions this feature supports
- CI tests pass for all supported Kubernetes versions

Beta:

- Gather user feedback

GA:

- N examples of real-world usage
- N installs
- Allowing time for feedback
- Works on all versions of Kubernetes supported by the version of cert-manager at which this feature becomes GA

References in Kubernetes documentation:

[feature gate]: https://git.k8s.io/community/contributors/devel/sig-architecture/feature-gates.md
[maturity-levels]: https://git.k8s.io/community/contributors/devel/sig-architecture/api_changes.md#alpha-beta-and-stable-versions
-->
Since this proposal has no code changes, it does not have any feature flags. However its graduation should be managed. To accomplish this we should do the following:

Alpha/Beta:
- Start publishing images to the new registry - we document the new registry but do not push it as the new default

GA:
- Update the official Helm charts to use the new registry
- Update documentation to reflect that the new registry is the preferred one 

The criteria for graduation will be a based off maintainer confidence in the new registry, informed by the E2E test runs using the new registries and any feedback from early adopters.

### Upgrade / Downgrade Strategy

<!--
Will this feature affect upgrade/downgrade of cert-manager?
-->
Once we are happy to make this GA the Helm chart will be updated to use the new registry, this will mean that for users using the official Helm chart the change will be automatic. For other users nothing will break by them using the old registry, so they can update their deployment at their own convenience. Furthermore a user could choose to set the registry back to quay.io/jetstack in their Helm configuration if they so choose.

### 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

### How can this feature be enabled / disabled for an existing cert-manager installation?

<!--

Can the feature be disabled after having been enabled?

Consider whether any additional steps will need to be taken to start/stop using this feature, i.e change existing resources that have had new field added for the feature before disabling it.


Do the test cases cover both the feature being enabled and it being disabled (where relevant)?

-->
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.
-->
There are many competing container registries, the two currently in contention (ghcr and quay) were selected because we already have access and availability to push there. They also offer their services for free for open source projects such as ours.