Feature request
Allow a default / cluster-wide store that Executor and NamespacedExecutor resources can inherit, so users don't have to repeat the same stores block in every executor — and so registries that allow anonymous access don't require a boilerplate, meaningless store definition.
Background
In Ratify v2, ExecutorSpec makes stores required (+kubebuilder:validation:MinItems=1), alongside scopes and verifiers:
// Stores contains the configuration options for the stores. At least one
// store must be provided. Required.
// +kubebuilder:validation:MinItems=1
Stores []*StoreOptions `json:"stores"`
With the newly added namespaced multi-tenancy support (NamespacedExecutor, see #2862), every tenant that wants its own executor must re-declare the full stores block, even when it only wants the same registry access as everyone else. The fallback in v2 is whole-executor granularity: GetExecutor(namespace) returns either the namespace's entire ScopedExecutor or the cluster one — it never mixes "namespaced verifiers + cluster store".
Problem
- Repetition: In a multi-tenant cluster, the
stores config (registry endpoint, plainHttp, credential provider, etc.) is duplicated in every NamespacedExecutor, even when identical to the cluster default.
- Meaningless config for anonymous registries: For registries that allow anonymous pulls, users still must write a
stores entry (with type: registry-store + a credential provider block) just to satisfy the required field, even though there's no real credential to configure. This is boilerplate with no semantic value.
Proposal
Support inheriting a default cluster-wide store when an executor does not define its own:
- Make
stores optional on NamespacedExecutor (and/or Executor), and when omitted, fall back to the cluster-scoped Executor's stores at the component level (i.e., namespaced verifiers/policy + inherited cluster stores). This mirrors Ratify v1, where stores, verifiers, and policies each fell back to cluster-wide independently (ActiveStores.GetStores(scope) returns cluster stores when the namespace has none).
- Additionally / alternatively, allow omitting
stores to imply a sensible default anonymous registry store for registries that don't need credentials, so anonymous-access scenarios need zero store config.
Alternatives considered
- Keep
stores required (status quo) — simple and explicit, but forces duplication and boilerplate as described above.
- Whole-executor fallback only (current v2 behavior) — a
NamespacedExecutor must be fully self-contained (stores + verifiers + policy). Does not solve the repetition problem.
Acceptance criteria
- A
NamespacedExecutor (and/or Executor) can be created without a stores block.
- When
stores is omitted, the executor inherits the cluster-wide default store(s); for anonymous registries, no store config is required at all.
- Behavior is documented (including how it interacts with the "namespaced overrides cluster, cluster is fallback" decision from
docs/discussion/Multi-Tenancy Support.md).
- Backward compatible: existing executors that specify
stores are unaffected.
References
Feature request
Allow a default / cluster-wide store that
ExecutorandNamespacedExecutorresources can inherit, so users don't have to repeat the samestoresblock in every executor — and so registries that allow anonymous access don't require a boilerplate, meaningless store definition.Background
In Ratify v2,
ExecutorSpecmakesstoresrequired (+kubebuilder:validation:MinItems=1), alongsidescopesandverifiers:With the newly added namespaced multi-tenancy support (
NamespacedExecutor, see #2862), every tenant that wants its own executor must re-declare the fullstoresblock, even when it only wants the same registry access as everyone else. The fallback in v2 is whole-executor granularity:GetExecutor(namespace)returns either the namespace's entireScopedExecutoror the cluster one — it never mixes "namespaced verifiers + cluster store".Problem
storesconfig (registry endpoint,plainHttp, credential provider, etc.) is duplicated in everyNamespacedExecutor, even when identical to the cluster default.storesentry (withtype: registry-store+ a credential provider block) just to satisfy the required field, even though there's no real credential to configure. This is boilerplate with no semantic value.Proposal
Support inheriting a default cluster-wide store when an executor does not define its own:
storesoptional onNamespacedExecutor(and/orExecutor), and when omitted, fall back to the cluster-scopedExecutor's stores at the component level (i.e., namespaced verifiers/policy + inherited cluster stores). This mirrors Ratify v1, wherestores,verifiers, andpolicieseach fell back to cluster-wide independently (ActiveStores.GetStores(scope)returns cluster stores when the namespace has none).storesto imply a sensible default anonymous registry store for registries that don't need credentials, so anonymous-access scenarios need zero store config.Alternatives considered
storesrequired (status quo) — simple and explicit, but forces duplication and boilerplate as described above.NamespacedExecutormust be fully self-contained (stores + verifiers + policy). Does not solve the repetition problem.Acceptance criteria
NamespacedExecutor(and/orExecutor) can be created without astoresblock.storesis omitted, the executor inherits the cluster-wide default store(s); for anonymous registries, no store config is required at all.docs/discussion/Multi-Tenancy Support.md).storesare unaffected.References
Executormulti-tenancy)docs/discussion/Multi-Tenancy Support.md— "Cluster-wide Image Validation" (adopts namespaced overrides cluster)pkg/customresources/referrerstores/stores.goGetStores(scope)