# Background Ratify is going to support multi-tenancy model in the next release. One major necessary refactoring is CRD scope. Currently we have 4 CRDs with different scopes, including policy, store, verifier and certificateStore. |CRD| scope | |---|---| |policy|cluster| |store|cluster| |verifier|cluster| |certificateStore|namespaced| Take Policy and CertificateStore as examples: ```yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: policies.config.ratify.deislabs.io spec: group: config.ratify.deislabs.io names: kind: Policy listKind: PolicyList plural: policies singular: policy scope: Cluster ``` ```yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: certificatestores.config.ratify.deislabs.io spec: group: config.ratify.deislabs.io names: kind: CertificateStore listKind: CertificateStoreList plural: certificatestores singular: certificatestore scope: Namespaced ``` To support both namespaced and cluster-wide resources, we would have to create 2 CRDs for each resource, one is namespaced, and the other is cluster-wide. For each resource, the name of 2 CRDs would be different in terms of the scope. Therefore, there are 3 options to make this change. ## 1. ClusterResource vs Resource For cluster-wide resources, we would prefix CRD name with `Cluster`. e.g. - ClusterPolicy - ClusterStore - ClusterVerifier - ClusterCertificateStore And for namespaced resources, we would keep the original names like: Policy/Store/Verifier/CertificateStore ### Examples Cluster-wide Policy: ```yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: clusterpolicies.config.ratify.deislabs.io spec: group: config.ratify.deislabs.io names: kind: ClusterPolicy listKind: ClusterPolicyList plural: clusterpolicies singular: clusterpolicy scope: Cluster ``` Namespaced Policy: ```yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: policies.config.ratify.deislabs.io spec: group: config.ratify.deislabs.io names: kind: Policy listKind: PolicyList plural: policies singular: policy scope: Namespaced ``` ### Pros & Cons #### Pros - It's clear to customers to differentiate between cluster-wide and namespaced resources. - It's the same as the way Kyverno handles ClusterPolicy/Policy. - User Experience: it's convenient and clear for users to apply correspoding CRs per namespace(cluster). #### Cons - Current verifier/store/policy are cluster-wide resources, we have to update their scope to namespaced, which is a breaking change since spec.scope is immutable. ## 2. Resource vs NamespacedResource For cluster-wide resources, we would keep the original names like: Policy/Store/Verifier/CertificateStore For namespaced resources, names would be prefixed with `Namespaced`, e.g. - NamespacedPolicy - NamespacedStore - NamespacedVerifier - NamespacedCertificateStore ### Examples Cluster-wide policy: ```yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: policies.config.ratify.deislabs.io spec: group: config.ratify.deislabs.io names: kind: Policy listKind: PolicyList plural: policies singular: policy scope: Cluster ``` Namespaced policy: ```yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: namespacedpolicies.config.ratify.deislabs.io spec: group: config.ratify.deislabs.io names: kind: NamespacedPolicy listKind: NamespacedPolicyList plural: namespacedpolicies singular: namespacedpolicy scope: Namespaced ``` ### Pros & Cons #### Pros - It's relatively clear for customers to differentiate between cluster-wide and namespaced resources. - Though it requires breaking change to certificateStore naming, it's less work and change than option 1. #### Cons - It's more more to name ClusterResource/Resource than Resource/NamespacedResource. - It also requires breaking change to cetificateStore which is namespaced now. ## 3. Mixture of Option 1 and 2 The purpose of this option is to avoid breaking changes. The overall naming for each resource is below: | Resource | Cluster-wide | Namespaced| |---|---|---| | Policy| Policy | NamespacedPolicy | | Verifier | Verifier | NamespacedVerifier | | Store | Store | NamespacedStore | | CertificateStore | ClusterCertificateStore | CertificateStore | This option have different naming approaches for 2 groups, one is policy/verifier/store, and the other is certStore. #### Pros - It avoids breaking change to CRD names. We don't need to update existing CRDs but just add new CRDs. #### Cons - User Experience: Resources have different name prefix in terms of the scope. # Conclusion Option 1 and 2 are the same under the hood except option 2 requires less breaking change. And we need to consider user experience from 2 perspective: 1. Compatibility during upgrading Ratify with multi-tenancy support. - Breaking change in CRD means that users have to delete all existing CRDs before upgrading Ratify. - If customers are fine with this one-time operation, then option 1 would be best. - If this is not acceptable, then we can only adopt option 3. 2. User experience post upgrading Ratify. - This is on-going user experience for customers as they need to keep applying CRs. - To make it more convenient and clear for customers to apply CRs in terms of scopes, option 1 would be the best option.