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