Kaynağa Gözat

feat: new provider structure

Signed-off-by: Gustavo Carvalho <gusfcarvalho@gmail.com>
Gustavo Carvalho 1 yıl önce
ebeveyn
işleme
bf6b2cfc57
92 değiştirilmiş dosya ile 5127 ekleme ve 509 silme
  1. 9 1
      apis/externalsecrets/v1beta1/provider.go
  2. 24 0
      apis/externalsecrets/v1beta1/provider_schema.go
  3. 13 0
      apis/externalsecrets/v1beta1/provider_schema_test.go
  4. 1 1
      apis/externalsecrets/v1beta1/secretsstore_bitwarden_types.go
  5. 1 1
      apis/externalsecrets/v1beta1/secretstore_akeyless_types.go
  6. 2 2
      apis/externalsecrets/v1beta1/secretstore_conjur_types.go
  7. 1 1
      apis/externalsecrets/v1beta1/secretstore_kubernetes_types.go
  8. 8 35
      apis/externalsecrets/v1beta1/secretstore_types.go
  9. 1 1
      apis/externalsecrets/v1beta1/secretstore_vault_types.go
  10. 11 51
      apis/externalsecrets/v1beta1/zz_generated.deepcopy.go
  11. 2 2
      apis/generators/v1alpha1/generator_acr.go
  12. 51 0
      apis/meta/v1/types.go
  13. 60 0
      apis/meta/v1/zz_generated.deepcopy.go
  14. 19 0
      apis/providers/v1alpha1/doc.go
  15. 132 0
      apis/providers/v1alpha1/provider_akeyless.go
  16. 99 0
      apis/providers/v1alpha1/provider_alibaba.go
  17. 179 0
      apis/providers/v1alpha1/provider_aws.go
  18. 156 0
      apis/providers/v1alpha1/provider_azurekv.go
  19. 79 0
      apis/providers/v1alpha1/provider_fake.go
  20. 97 0
      apis/providers/v1alpha1/provider_gitlab.go
  21. 43 0
      apis/providers/v1alpha1/register.go
  22. 85 0
      apis/providers/v1alpha1/schema.go
  23. 896 0
      apis/providers/v1alpha1/zz_generated.deepcopy.go
  24. 2 0
      cmd/root.go
  25. 16 2
      config/crds/bases/external-secrets.io_clustersecretstores.yaml
  26. 16 2
      config/crds/bases/external-secrets.io_secretstores.yaml
  27. 6 0
      config/crds/bases/kustomization.yaml
  28. 241 0
      config/crds/bases/providers.external-secrets.io_akeylesses.yaml
  29. 139 0
      config/crds/bases/providers.external-secrets.io_alibabas.yaml
  30. 233 0
      config/crds/bases/providers.external-secrets.io_awses.yaml
  31. 211 0
      config/crds/bases/providers.external-secrets.io_azurekvs.yaml
  32. 86 0
      config/crds/bases/providers.external-secrets.io_fakes.yaml
  33. 119 0
      config/crds/bases/providers.external-secrets.io_gitlabs.yaml
  34. 0 4
      deploy/charts/external-secrets/templates/crds/README.md
  35. 16 2
      deploy/charts/external-secrets/tests/__snapshot__/crds_test.yaml.snap
  36. 1 1
      deploy/charts/external-secrets/tests/crds_test.yaml
  37. 3 3
      deploy/charts/external-secrets/tests/webhook_test.yaml
  38. 1080 4
      deploy/crds/bundle.yaml
  39. 61 148
      docs/api/spec.md
  40. 2 2
      e2e/suites/provider/cases/alibaba/provider.go
  41. 2 1
      e2e/suites/provider/cases/azure/provider.go
  42. 2 2
      e2e/suites/provider/cases/kubernetes/provider.go
  43. 3 3
      hack/helm.generate.sh
  44. 2 2
      pkg/common/webhook/models.go
  45. 60 4
      pkg/controllers/secretstore/client_manager.go
  46. 13 0
      pkg/controllers/secretstore/client_manager_test.go
  47. 7 1
      pkg/controllers/secretstore/common.go
  48. 9 9
      pkg/generator/acr/acr.go
  49. 67 13
      pkg/provider/akeyless/akeyless.go
  50. 3 2
      pkg/provider/akeyless/akeyless_api.go
  51. 1 5
      pkg/provider/akeyless/auth.go
  52. 60 24
      pkg/provider/alibaba/kms.go
  53. 19 0
      pkg/provider/aws/provider.go
  54. 1 1
      pkg/provider/aws/provider_test.go
  55. 87 41
      pkg/provider/azure/keyvault/keyvault.go
  56. 67 69
      pkg/provider/azure/keyvault/keyvault_auth_test.go
  57. 7 6
      pkg/provider/azure/keyvault/keyvault_test.go
  58. 13 0
      pkg/provider/beyondtrust/provider.go
  59. 13 0
      pkg/provider/bitwarden/provider.go
  60. 13 0
      pkg/provider/chef/chef.go
  61. 14 0
      pkg/provider/conjur/provider.go
  62. 4 4
      pkg/provider/conjur/provider_test.go
  63. 13 0
      pkg/provider/delinea/provider.go
  64. 13 0
      pkg/provider/device42/device42.go
  65. 12 0
      pkg/provider/doppler/provider.go
  66. 79 0
      pkg/provider/fake/fake.go
  67. 12 0
      pkg/provider/fortanix/provider.go
  68. 12 0
      pkg/provider/gcp/secretmanager/provider.go
  69. 22 25
      pkg/provider/gitlab/gitlab_test.go
  70. 62 14
      pkg/provider/gitlab/provider.go
  71. 13 0
      pkg/provider/ibm/provider.go
  72. 1 1
      pkg/provider/ibm/provider_test.go
  73. 11 0
      pkg/provider/infisical/provider.go
  74. 13 0
      pkg/provider/keepersecurity/provider.go
  75. 4 4
      pkg/provider/kubernetes/auth_test.go
  76. 12 0
      pkg/provider/kubernetes/provider.go
  77. 13 0
      pkg/provider/onboardbase/provider.go
  78. 13 0
      pkg/provider/onepassword/onepassword.go
  79. 12 0
      pkg/provider/oracle/oracle.go
  80. 5 5
      pkg/provider/oracle/oracle_test.go
  81. 13 0
      pkg/provider/passbolt/passbolt.go
  82. 13 0
      pkg/provider/passworddepot/passworddepot.go
  83. 12 0
      pkg/provider/pulumi/provider.go
  84. 12 0
      pkg/provider/scaleway/provider.go
  85. 13 0
      pkg/provider/secretserver/provider.go
  86. 13 0
      pkg/provider/senhasegura/provider.go
  87. 13 0
      pkg/provider/testing/fake/fake.go
  88. 14 1
      pkg/provider/vault/provider.go
  89. 4 4
      pkg/provider/vault/provider_test.go
  90. 13 0
      pkg/provider/webhook/webhook.go
  91. 12 0
      pkg/provider/yandex/common/provider.go
  92. 5 5
      pkg/utils/utils.go

+ 9 - 1
apis/externalsecrets/v1beta1/provider.go

@@ -20,6 +20,8 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 const (
@@ -48,9 +50,15 @@ func (v ValidationResult) String() string {
 
 // Provider is a common interface for interacting with secret backends.
 type Provider interface {
+	// NewClient based on a provider spec
+	NewClientFromObj(ctx context.Context, obj client.Object, kube client.Client, namespace string) (SecretsClient, error)
+
+	// ApplyReferent gets an object and changes namespace fields according to referent strategy
+	ApplyReferent(spec client.Object, caller esmeta.ReferentCallOrigin, namespace string) (client.Object, error)
+
 	// NewClient constructs a SecretsManager Provider
 	NewClient(ctx context.Context, store GenericStore, kube client.Client, namespace string) (SecretsClient, error)
-
+	Convert(store GenericStore) (client.Object, error)
 	// ValidateStore checks if the provided store is valid
 	// The provider may return a warning and an error.
 	// The intended use of the warning to indicate a deprecation of behavior

+ 24 - 0
apis/externalsecrets/v1beta1/provider_schema.go

@@ -19,6 +19,8 @@ import (
 	"errors"
 	"fmt"
 	"sync"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 var builder map[string]Provider
@@ -46,6 +48,17 @@ func Register(s Provider, storeSpec *SecretStoreProvider) {
 	builder[storeName] = s
 }
 
+func RegisterByName(s Provider, name string) {
+	buildlock.Lock()
+	defer buildlock.Unlock()
+	_, exists := builder[name]
+	if exists {
+		panic(fmt.Sprintf("store %q already registered", name))
+	}
+
+	builder[name] = s
+}
+
 // ForceRegister adds to store schema, overwriting a store if
 // already registered. Should only be used for testing.
 func ForceRegister(s Provider, storeSpec *SecretStoreProvider) {
@@ -67,6 +80,17 @@ func GetProviderByName(name string) (Provider, bool) {
 	return f, ok
 }
 
+// GetProviderByRef returns the provider by its kind.
+func GetProviderByRef(ref esmeta.ProviderRef) (Provider, error) {
+	buildlock.RLock()
+	f, ok := builder[ref.Kind]
+	buildlock.RUnlock()
+	if !ok {
+		return nil, fmt.Errorf("provider %v not found", ref.Kind)
+	}
+	return f, nil
+}
+
 // GetProvider returns the provider from the generic store.
 func GetProvider(s GenericStore) (Provider, error) {
 	if s == nil {

+ 13 - 0
apis/externalsecrets/v1beta1/provider_schema_test.go

@@ -16,22 +16,35 @@ package v1beta1
 
 import (
 	"context"
+	"fmt"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 	corev1 "k8s.io/api/core/v1"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 type PP struct{}
 
 const shouldBeRegistered = "provider should be registered"
 
+func (p *PP) Convert(_ GenericStore) (client.Object, error) {
+	return nil, nil
+}
 func (p *PP) Capabilities() SecretStoreCapabilities {
 	return SecretStoreReadOnly
 }
 
+func (p *PP) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+func (p *PP) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // New constructs a SecretsManager Provider.
 func (p *PP) NewClient(_ context.Context, _ GenericStore, _ client.Client, _ string) (SecretsClient, error) {
 	return p, nil

+ 1 - 1
apis/externalsecrets/v1beta1/secretsstore_bitwarden_types.go

@@ -27,7 +27,7 @@ type BitwardenSecretsManagerProvider struct {
 	CABundle string `json:"caBundle,omitempty"`
 	// see: https://external-secrets.io/latest/spec/#external-secrets.io/v1alpha1.CAProvider
 	// +optional
-	CAProvider *CAProvider `json:"caProvider,omitempty"`
+	CAProvider *esmeta.CAProvider `json:"caProvider,omitempty"`
 	// OrganizationID determines which organization this secret store manages.
 	OrganizationID string `json:"organizationID"`
 	// ProjectID determines which project this secret store manages.

+ 1 - 1
apis/externalsecrets/v1beta1/secretstore_akeyless_types.go

@@ -35,7 +35,7 @@ type AkeylessProvider struct {
 
 	// The provider for the CA bundle to use to validate Akeyless Gateway certificate.
 	// +optional
-	CAProvider *CAProvider `json:"caProvider,omitempty"`
+	CAProvider *esmeta.CAProvider `json:"caProvider,omitempty"`
 }
 
 type AkeylessAuth struct {

+ 2 - 2
apis/externalsecrets/v1beta1/secretstore_conjur_types.go

@@ -21,8 +21,8 @@ type ConjurProvider struct {
 	// +optional
 	CABundle string `json:"caBundle,omitempty"`
 	// +optional
-	CAProvider *CAProvider `json:"caProvider,omitempty"`
-	Auth       ConjurAuth  `json:"auth"`
+	CAProvider *esmeta.CAProvider `json:"caProvider,omitempty"`
+	Auth       ConjurAuth         `json:"auth"`
 }
 
 type ConjurAuth struct {

+ 1 - 1
apis/externalsecrets/v1beta1/secretstore_kubernetes_types.go

@@ -31,7 +31,7 @@ type KubernetesServer struct {
 
 	// see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider
 	// +optional
-	CAProvider *CAProvider `json:"caProvider,omitempty"`
+	CAProvider *esmeta.CAProvider `json:"caProvider,omitempty"`
 }
 
 // Configures a store to sync secrets with a Kubernetes instance.

+ 8 - 35
apis/externalsecrets/v1beta1/secretstore_types.go

@@ -17,6 +17,8 @@ package v1beta1
 import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 // SecretStoreSpec defines the desired state of SecretStore.
@@ -27,11 +29,15 @@ type SecretStoreSpec struct {
 	Controller string `json:"controller,omitempty"`
 
 	// Used to configure the provider. Only one provider may be set
-	Provider *SecretStoreProvider `json:"provider"`
+	// +optional
+	Provider *SecretStoreProvider `json:"provider,omitempty"`
 
+	// Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+	// providerRef takes precedence over provider.
+	ProviderRef *esmeta.ProviderRef `json:"providerRef,omitempty"`
 	// Used to configure http retries if failed
 	// +optional
-	RetrySettings *SecretStoreRetrySettings `json:"retrySettings,omitempty"`
+	RetrySettings *esmeta.RetrySettings `json:"retrySettings,omitempty"`
 
 	// Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
 	// +optional
@@ -191,39 +197,6 @@ type SecretStoreProvider struct {
 	Beyondtrust *BeyondtrustProvider `json:"beyondtrust,omitempty"`
 }
 
-type CAProviderType string
-
-const (
-	CAProviderTypeSecret    CAProviderType = "Secret"
-	CAProviderTypeConfigMap CAProviderType = "ConfigMap"
-)
-
-// Used to provide custom certificate authority (CA) certificates
-// for a secret store. The CAProvider points to a Secret or ConfigMap resource
-// that contains a PEM-encoded certificate.
-type CAProvider struct {
-	// The type of provider to use such as "Secret", or "ConfigMap".
-	// +kubebuilder:validation:Enum="Secret";"ConfigMap"
-	Type CAProviderType `json:"type"`
-
-	// The name of the object located at the provider type.
-	Name string `json:"name"`
-
-	// The key where the CA certificate can be found in the Secret or ConfigMap.
-	// +kubebuilder:validation:Optional
-	Key string `json:"key,omitempty"`
-
-	// The namespace the Provider type is in.
-	// Can only be defined when used in a ClusterSecretStore.
-	// +optional
-	Namespace *string `json:"namespace,omitempty"`
-}
-
-type SecretStoreRetrySettings struct {
-	MaxRetries    *int32  `json:"maxRetries,omitempty"`
-	RetryInterval *string `json:"retryInterval,omitempty"`
-}
-
 type SecretStoreConditionType string
 
 const (

+ 1 - 1
apis/externalsecrets/v1beta1/secretstore_vault_types.go

@@ -71,7 +71,7 @@ type VaultProvider struct {
 
 	// The provider for the CA bundle to use to validate Vault server certificate.
 	// +optional
-	CAProvider *CAProvider `json:"caProvider,omitempty"`
+	CAProvider *esmeta.CAProvider `json:"caProvider,omitempty"`
 
 	// ReadYourWrites ensures isolated read-after-write semantics by
 	// providing discovered cluster replication states in each request.

+ 11 - 51
apis/externalsecrets/v1beta1/zz_generated.deepcopy.go

@@ -223,7 +223,7 @@ func (in *AkeylessProvider) DeepCopyInto(out *AkeylessProvider) {
 	}
 	if in.CAProvider != nil {
 		in, out := &in.CAProvider, &out.CAProvider
-		*out = new(CAProvider)
+		*out = new(metav1.CAProvider)
 		(*in).DeepCopyInto(*out)
 	}
 }
@@ -507,7 +507,7 @@ func (in *BitwardenSecretsManagerProvider) DeepCopyInto(out *BitwardenSecretsMan
 	*out = *in
 	if in.CAProvider != nil {
 		in, out := &in.CAProvider, &out.CAProvider
-		*out = new(CAProvider)
+		*out = new(metav1.CAProvider)
 		(*in).DeepCopyInto(*out)
 	}
 	in.Auth.DeepCopyInto(&out.Auth)
@@ -539,26 +539,6 @@ func (in *BitwardenSecretsManagerSecretRef) DeepCopy() *BitwardenSecretsManagerS
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *CAProvider) DeepCopyInto(out *CAProvider) {
-	*out = *in
-	if in.Namespace != nil {
-		in, out := &in.Namespace, &out.Namespace
-		*out = new(string)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CAProvider.
-func (in *CAProvider) DeepCopy() *CAProvider {
-	if in == nil {
-		return nil
-	}
-	out := new(CAProvider)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *CertAuth) DeepCopyInto(out *CertAuth) {
 	*out = *in
@@ -959,7 +939,7 @@ func (in *ConjurProvider) DeepCopyInto(out *ConjurProvider) {
 	*out = *in
 	if in.CAProvider != nil {
 		in, out := &in.CAProvider, &out.CAProvider
-		*out = new(CAProvider)
+		*out = new(metav1.CAProvider)
 		(*in).DeepCopyInto(*out)
 	}
 	in.Auth.DeepCopyInto(&out.Auth)
@@ -1985,7 +1965,7 @@ func (in *KubernetesServer) DeepCopyInto(out *KubernetesServer) {
 	}
 	if in.CAProvider != nil {
 		in, out := &in.CAProvider, &out.CAProvider
-		*out = new(CAProvider)
+		*out = new(metav1.CAProvider)
 		(*in).DeepCopyInto(*out)
 	}
 }
@@ -2675,31 +2655,6 @@ func (in *SecretStoreRef) DeepCopy() *SecretStoreRef {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SecretStoreRetrySettings) DeepCopyInto(out *SecretStoreRetrySettings) {
-	*out = *in
-	if in.MaxRetries != nil {
-		in, out := &in.MaxRetries, &out.MaxRetries
-		*out = new(int32)
-		**out = **in
-	}
-	if in.RetryInterval != nil {
-		in, out := &in.RetryInterval, &out.RetryInterval
-		*out = new(string)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretStoreRetrySettings.
-func (in *SecretStoreRetrySettings) DeepCopy() *SecretStoreRetrySettings {
-	if in == nil {
-		return nil
-	}
-	out := new(SecretStoreRetrySettings)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *SecretStoreSpec) DeepCopyInto(out *SecretStoreSpec) {
 	*out = *in
@@ -2708,9 +2663,14 @@ func (in *SecretStoreSpec) DeepCopyInto(out *SecretStoreSpec) {
 		*out = new(SecretStoreProvider)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.ProviderRef != nil {
+		in, out := &in.ProviderRef, &out.ProviderRef
+		*out = new(metav1.ProviderRef)
+		**out = **in
+	}
 	if in.RetrySettings != nil {
 		in, out := &in.RetrySettings, &out.RetrySettings
-		*out = new(SecretStoreRetrySettings)
+		*out = new(metav1.RetrySettings)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Conditions != nil {
@@ -3309,7 +3269,7 @@ func (in *VaultProvider) DeepCopyInto(out *VaultProvider) {
 	in.ClientTLS.DeepCopyInto(&out.ClientTLS)
 	if in.CAProvider != nil {
 		in, out := &in.CAProvider, &out.CAProvider
-		*out = new(CAProvider)
+		*out = new(metav1.CAProvider)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Headers != nil {

+ 2 - 2
apis/generators/v1alpha1/generator_acr.go

@@ -17,8 +17,8 @@ package v1alpha1
 import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	smmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 )
 
 // ACRAccessTokenSpec defines how to generate the access token
@@ -50,7 +50,7 @@ type ACRAccessTokenSpec struct {
 	// The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152
 	// PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
 	// +kubebuilder:default=PublicCloud
-	EnvironmentType v1beta1.AzureEnvironmentType `json:"environmentType,omitempty"`
+	EnvironmentType prov.AzureEnvironmentType `json:"environmentType,omitempty"`
 }
 
 type ACRAuth struct {

+ 51 - 0
apis/meta/v1/types.go

@@ -14,6 +14,23 @@ limitations under the License.
 
 package v1
 
+type ProviderRef struct {
+	APIVersion string `json:"apiVersion"`
+	Kind       string `json:"kind"`
+	Name       string `json:"name"`
+}
+
+// ReferentCallOrigin determines if NewClientFromObject was called from the Provider, The SecretStore, or the ClusterSecretStore.
+type ReferentCallOrigin string
+
+const (
+	ReferentCallSecretStore ReferentCallOrigin = "SecretStore"
+
+	ReferentCallClusterSecretStore ReferentCallOrigin = "ClusterSecretStore"
+
+	ReferentCallProvider ReferentCallOrigin = "Provider"
+)
+
 // A reference to a specific 'key' within a Secret resource,
 // In some instances, `key` is a required field.
 type SecretKeySelector struct {
@@ -43,3 +60,37 @@ type ServiceAccountSelector struct {
 	// +optional
 	Audiences []string `json:"audiences,omitempty"`
 }
+
+type CAProviderType string
+
+const (
+	CAProviderTypeSecret    CAProviderType = "Secret"
+	CAProviderTypeConfigMap CAProviderType = "ConfigMap"
+)
+
+// Used to provide custom certificate authority (CA) certificates
+// for a secret store. The CAProvider points to a Secret or ConfigMap resource
+// that contains a PEM-encoded certificate.
+type CAProvider struct {
+	// The type of provider to use such as "Secret", or "ConfigMap".
+	// +kubebuilder:validation:Enum="Secret";"ConfigMap"
+	Type CAProviderType `json:"type"`
+
+	// The name of the object located at the provider type.
+	Name string `json:"name"`
+
+	// The key where the CA certificate can be found in the Secret or ConfigMap.
+	// +kubebuilder:validation:Optional
+	Key string `json:"key,omitempty"`
+
+	// The namespace the Provider type is in.
+	// Can only be defined when used in a ClusterSecretStore.
+	// +optional
+	Namespace *string `json:"namespace,omitempty"`
+}
+
+// Configures Retry Settings for providers/Secret Stores.
+type RetrySettings struct {
+	MaxRetries    *int32  `json:"maxRetries,omitempty"`
+	RetryInterval *string `json:"retryInterval,omitempty"`
+}

+ 60 - 0
apis/meta/v1/zz_generated.deepcopy.go

@@ -20,6 +20,66 @@ package v1
 
 import ()
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CAProvider) DeepCopyInto(out *CAProvider) {
+	*out = *in
+	if in.Namespace != nil {
+		in, out := &in.Namespace, &out.Namespace
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CAProvider.
+func (in *CAProvider) DeepCopy() *CAProvider {
+	if in == nil {
+		return nil
+	}
+	out := new(CAProvider)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ProviderRef) DeepCopyInto(out *ProviderRef) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderRef.
+func (in *ProviderRef) DeepCopy() *ProviderRef {
+	if in == nil {
+		return nil
+	}
+	out := new(ProviderRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *RetrySettings) DeepCopyInto(out *RetrySettings) {
+	*out = *in
+	if in.MaxRetries != nil {
+		in, out := &in.MaxRetries, &out.MaxRetries
+		*out = new(int32)
+		**out = **in
+	}
+	if in.RetryInterval != nil {
+		in, out := &in.RetryInterval, &out.RetryInterval
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RetrySettings.
+func (in *RetrySettings) DeepCopy() *RetrySettings {
+	if in == nil {
+		return nil
+	}
+	out := new(RetrySettings)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) {
 	*out = *in

+ 19 - 0
apis/providers/v1alpha1/doc.go

@@ -0,0 +1,19 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Package v1alpha1 contains resources for providers
+// +kubebuilder:object:generate=true
+// +groupName=providers.external-secrets.io
+// +versionName=v1alpha1
+package v1alpha1

+ 132 - 0
apis/providers/v1alpha1/provider_akeyless.go

@@ -0,0 +1,132 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	"reflect"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+// AkeylessSpec Configures an store to sync secrets using Akeyless KV.
+type AkeylessSpec struct {
+	// Used to select the correct ESO controller (think: ingress.ingressClassName)
+	// The ESO controller is instantiated with a specific controller name and filters ES based on this property
+	// +optional
+	Controller string `json:"controller,omitempty"`
+
+	// Used to configure http retries if failed
+	// +optional
+	RetrySettings *esmeta.RetrySettings `json:"retrySettings,omitempty"`
+
+	// Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+	// +optional
+	RefreshInterval int `json:"refreshInterval,omitempty"`
+	// Akeyless GW API Url from which the secrets to be fetched from.
+	AkeylessGWApiURL *string `json:"akeylessGWApiURL"`
+
+	// Auth configures how the operator authenticates with Akeyless.
+	Auth *AkeylessAuth `json:"authSecretRef"`
+
+	// PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used
+	// if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates
+	// are used to validate the TLS connection.
+	// +optional
+	CABundle []byte `json:"caBundle,omitempty"`
+
+	// The provider for the CA bundle to use to validate Akeyless Gateway certificate.
+	// +optional
+	CAProvider *esmeta.CAProvider `json:"caProvider,omitempty"`
+}
+
+type AkeylessAuth struct {
+
+	// Reference to a Secret that contains the details
+	// to authenticate with Akeyless.
+	// +optional
+	SecretRef AkeylessAuthSecretRef `json:"secretRef,omitempty"`
+
+	// Kubernetes authenticates with Akeyless by passing the ServiceAccount
+	// token stored in the named Secret resource.
+	// +optional
+	KubernetesAuth *AkeylessKubernetesAuth `json:"kubernetesAuth,omitempty"`
+}
+
+// AkeylessAuthSecretRef
+// AKEYLESS_ACCESS_TYPE_PARAM: AZURE_OBJ_ID OR GCP_AUDIENCE OR ACCESS_KEY OR KUB_CONFIG_NAME.
+type AkeylessAuthSecretRef struct {
+	// The SecretAccessID is used for authentication
+	AccessID        esmeta.SecretKeySelector `json:"accessID,omitempty"`
+	AccessType      esmeta.SecretKeySelector `json:"accessType,omitempty"`
+	AccessTypeParam esmeta.SecretKeySelector `json:"accessTypeParam,omitempty"`
+}
+
+// Authenticate with Kubernetes ServiceAccount token stored.
+type AkeylessKubernetesAuth struct {
+
+	// the Akeyless Kubernetes auth-method access-id
+	AccessID string `json:"accessID"`
+
+	// Kubernetes-auth configuration name in Akeyless-Gateway
+	K8sConfName string `json:"k8sConfName"`
+
+	// Optional service account field containing the name of a kubernetes ServiceAccount.
+	// If the service account is specified, the service account secret token JWT will be used
+	// for authenticating with Akeyless. If the service account selector is not supplied,
+	// the secretRef will be used instead.
+	// +optional
+	ServiceAccountRef *esmeta.ServiceAccountSelector `json:"serviceAccountRef,omitempty"`
+
+	// Optional secret field containing a Kubernetes ServiceAccount JWT used
+	// for authenticating with Akeyless. If a name is specified without a key,
+	// `token` is the default. If one is not specified, the one bound to
+	// the controller will be used.
+	// +optional
+	SecretRef *esmeta.SecretKeySelector `json:"secretRef,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:storageversion
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:scope=Cluster,categories={akeyless},shortName=akeyless
+type Akeyless struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Spec AkeylessSpec `json:"spec,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// AkeylessList contains a list of ExternalSecret resources.
+type AkeylessList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []Akeyless `json:"items"`
+}
+
+func init() {
+}
+
+// Akeyless type metadata.
+var (
+	AkeylessKind             = reflect.TypeOf(Akeyless{}).Name()
+	AkeylessoupKind          = schema.GroupKind{Group: Group, Kind: AkeylessKind}.String()
+	AkeylessKindAPIVersion   = AkeylessKind + "." + SchemeGroupVersion.String()
+	AkeylessGroupVersionKind = SchemeGroupVersion.WithKind(AkeylessKind)
+)

+ 99 - 0
apis/providers/v1alpha1/provider_alibaba.go

@@ -0,0 +1,99 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	"reflect"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+// AlibabaAuth contains a secretRef for credentials.
+type AlibabaAuth struct {
+	// +optional
+	SecretRef *AlibabaAuthSecretRef `json:"secretRef,omitempty"`
+	// +optional
+	RRSAAuth *AlibabaRRSAAuth `json:"rrsa,omitempty"`
+}
+
+// AlibabaAuthSecretRef holds secret references for Alibaba credentials.
+type AlibabaAuthSecretRef struct {
+	// The AccessKeyID is used for authentication
+	AccessKeyID esmeta.SecretKeySelector `json:"accessKeyIDSecretRef"`
+	// The AccessKeySecret is used for authentication
+	AccessKeySecret esmeta.SecretKeySelector `json:"accessKeySecretSecretRef"`
+}
+
+// Authenticate against Alibaba using RRSA.
+type AlibabaRRSAAuth struct {
+	OIDCProviderARN   string `json:"oidcProviderArn"`
+	OIDCTokenFilePath string `json:"oidcTokenFilePath"`
+	RoleARN           string `json:"roleArn"`
+	SessionName       string `json:"sessionName"`
+}
+
+// AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
+type AlibabaSpec struct {
+	// Used to select the correct ESO controller (think: ingress.ingressClassName)
+	// The ESO controller is instantiated with a specific controller name and filters ES based on this property
+	// +optional
+	Controller string `json:"controller,omitempty"`
+
+	// Used to configure http retries if failed
+	// +optional
+	RetrySettings *esmeta.RetrySettings `json:"retrySettings,omitempty"`
+
+	// Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+	// +optional
+	RefreshInterval int `json:"refreshInterval,omitempty"`
+
+	Auth AlibabaAuth `json:"auth"`
+	// Alibaba Region to be used for the provider
+	RegionID string `json:"regionID"`
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:storageversion
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:scope=Cluster,categories={alibaba},shortName=alibaba
+type Alibaba struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Spec AlibabaSpec `json:"spec,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// AlibabaList contains a list of Alibaba resources.
+type AlibabaList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []Alibaba `json:"items"`
+}
+
+func init() {
+}
+
+// Alibaba type metadata.
+var (
+	AlibabaKind             = reflect.TypeOf(Alibaba{}).Name()
+	AlibabaGroupKind        = schema.GroupKind{Group: Group, Kind: AlibabaKind}.String()
+	AlibabaKindAPIVersion   = AlibabaKind + "." + SchemeGroupVersion.String()
+	AlibabaGroupVersionKind = SchemeGroupVersion.WithKind(AlibabaKind)
+)

+ 179 - 0
apis/providers/v1alpha1/provider_aws.go

@@ -0,0 +1,179 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	"reflect"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+// AWSAuth tells the controller how to do authentication with aws.
+// Only one of secretRef or jwt can be specified.
+// if none is specified the controller will load credentials using the aws sdk defaults.
+type AWSAuth struct {
+	// +optional
+	SecretRef *AWSAuthSecretRef `json:"secretRef,omitempty"`
+	// +optional
+	JWTAuth *AWSJWTAuth `json:"jwt,omitempty"`
+}
+
+// AWSAuthSecretRef holds secret references for AWS credentials
+// both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
+type AWSAuthSecretRef struct {
+	// The AccessKeyID is used for authentication
+	AccessKeyID esmeta.SecretKeySelector `json:"accessKeyIDSecretRef,omitempty"`
+
+	// The SecretAccessKey is used for authentication
+	SecretAccessKey esmeta.SecretKeySelector `json:"secretAccessKeySecretRef,omitempty"`
+
+	// The SessionToken used for authentication
+	// This must be defined if AccessKeyID and SecretAccessKey are temporary credentials
+	// see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
+	// +Optional
+	SessionToken *esmeta.SecretKeySelector `json:"sessionTokenSecretRef,omitempty"`
+}
+
+// Authenticate against AWS using service account tokens.
+type AWSJWTAuth struct {
+	ServiceAccountRef *esmeta.ServiceAccountSelector `json:"serviceAccountRef,omitempty"`
+}
+
+// AWSServiceType is a enum that defines the service/API that is used to fetch the secrets.
+// +kubebuilder:validation:Enum=SecretsManager;ParameterStore
+type AWSServiceType string
+
+const (
+	// AWSServiceSecretsManager is the AWS SecretsManager service.
+	// see: https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html
+	AWSServiceSecretsManager AWSServiceType = "SecretsManager"
+	// AWSServiceParameterStore is the AWS SystemsManager ParameterStore service.
+	// see: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html
+	AWSServiceParameterStore AWSServiceType = "ParameterStore"
+)
+
+// SecretsManager defines how the provider behaves when interacting with AWS
+// SecretsManager. Some of these settings are only applicable to controlling how
+// secrets are deleted, and hence only apply to PushSecret (and only when
+// deletionPolicy is set to Delete).
+type SecretsManager struct {
+	// Specifies whether to delete the secret without any recovery window. You
+	// can't use both this parameter and RecoveryWindowInDays in the same call.
+	// If you don't use either, then by default Secrets Manager uses a 30 day
+	// recovery window.
+	// see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-ForceDeleteWithoutRecovery
+	// +optional
+	ForceDeleteWithoutRecovery bool `json:"forceDeleteWithoutRecovery,omitempty"`
+	// The number of days from 7 to 30 that Secrets Manager waits before
+	// permanently deleting the secret. You can't use both this parameter and
+	// ForceDeleteWithoutRecovery in the same call. If you don't use either,
+	// then by default Secrets Manager uses a 30 day recovery window.
+	// see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-RecoveryWindowInDays
+	// +optional
+	RecoveryWindowInDays int64 `json:"recoveryWindowInDays,omitempty"`
+}
+
+type Tag struct {
+	Key   string `json:"key"`
+	Value string `json:"value"`
+}
+
+// AWSProvider configures a store to sync secrets with AWS.
+type AWSSpec struct {
+	// Used to select the correct ESO controller (think: ingress.ingressClassName)
+	// The ESO controller is instantiated with a specific controller name and filters ES based on this property
+	// +optional
+	Controller string `json:"controller,omitempty"`
+
+	// Used to configure http retries if failed
+	// +optional
+	RetrySettings *esmeta.RetrySettings `json:"retrySettings,omitempty"`
+
+	// Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+	// +optional
+	RefreshInterval int `json:"refreshInterval,omitempty"`
+	// Service defines which service should be used to fetch the secrets
+	Service AWSServiceType `json:"service"`
+
+	// Auth defines the information necessary to authenticate against AWS
+	// if not set aws sdk will infer credentials from your environment
+	// see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials
+	// +optional
+	Auth AWSAuth `json:"auth,omitempty"`
+
+	// Role is a Role ARN which the provider will assume
+	// +optional
+	Role string `json:"role,omitempty"`
+
+	// AWS Region to be used for the provider
+	Region string `json:"region"`
+
+	// AdditionalRoles is a chained list of Role ARNs which the provider will sequentially assume before assuming the Role
+	// +optional
+	AdditionalRoles []string `json:"additionalRoles,omitempty"`
+
+	// AWS External ID set on assumed IAM roles
+	ExternalID string `json:"externalID,omitempty"`
+
+	// AWS STS assume role session tags
+	// +optional
+	SessionTags []*Tag `json:"sessionTags,omitempty"`
+
+	// SecretsManager defines how the provider behaves when interacting with AWS SecretsManager
+	// +optional
+	SecretsManager *SecretsManager `json:"secretsManager,omitempty"`
+
+	// AWS STS assume role transitive session tags. Required when multiple rules are used with the provider
+	// +optional
+	TransitiveTagKeys []*string `json:"transitiveTagKeys,omitempty"`
+
+	// Prefix adds a prefix to all retrieved values.
+	// +optional
+	Prefix string `json:"prefix,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:storageversion
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:scope=Cluster,categories={aws},shortName=aws
+type AWS struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Spec AWSSpec `json:"spec,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// AWSList contains a list of ExternalSecret resources.
+type AWSList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []AWS `json:"items"`
+}
+
+func init() {
+}
+
+// aws type metadata.
+var (
+	AWSKind             = reflect.TypeOf(AWS{}).Name()
+	AWSGroupKind        = schema.GroupKind{Group: Group, Kind: AWSKind}.String()
+	AWSKindAPIVersion   = AWSKind + "." + SchemeGroupVersion.String()
+	AWSGroupVersionKind = SchemeGroupVersion.WithKind(AWSKind)
+)

+ 156 - 0
apis/providers/v1alpha1/provider_azurekv.go

@@ -0,0 +1,156 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	"reflect"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+
+	smmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+// AuthType describes how to authenticate to the AzureKvKeyvault
+// Only one of the following auth types may be specified.
+// If none of the following auth type is specified, the default one
+// is ServicePrincipal.
+// +kubebuilder:validation:Enum=ServicePrincipal;ManagedIdentity;WorkloadIdentity
+type AzureAuthType string
+
+const (
+	// Using service principal to authenticate, which needs a tenantId, a clientId and a clientSecret.
+	AzureServicePrincipal AzureAuthType = "ServicePrincipal"
+
+	// Using Managed Identity to authenticate. Used with aad-pod-identity installed in the cluster.
+	AzureManagedIdentity AzureAuthType = "ManagedIdentity"
+
+	// Using Workload Identity service accounts to authenticate.
+	AzureWorkloadIdentity AzureAuthType = "WorkloadIdentity"
+)
+
+// AzureEnvironmentType specifies the AzureKvcloud environment endpoints to use for
+// connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint.
+// The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152
+// PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
+// +kubebuilder:validation:Enum=PublicCloud;USGovernmentCloud;ChinaCloud;GermanCloud
+type AzureEnvironmentType string
+
+const (
+	AzureEnvironmentPublicCloud       AzureEnvironmentType = "PublicCloud"
+	AzureEnvironmentUSGovernmentCloud AzureEnvironmentType = "USGovernmentCloud"
+	AzureEnvironmentChinaCloud        AzureEnvironmentType = "ChinaCloud"
+	AzureEnvironmentGermanCloud       AzureEnvironmentType = "GermanCloud"
+)
+
+// Configures an store to sync secrets using AzureKvKV.
+type AzureKVSpec struct {
+	// Used to select the correct ESO controller (think: ingress.ingressClassName)
+	// The ESO controller is instantiated with a specific controller name and filters ES based on this property
+	// +optional
+	Controller string `json:"controller,omitempty"`
+
+	// Used to configure http retries if failed
+	// +optional
+	RetrySettings *smmeta.RetrySettings `json:"retrySettings,omitempty"`
+
+	// Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+	// +optional
+	RefreshInterval int `json:"refreshInterval,omitempty"`
+	// Auth type defines how to authenticate to the keyvault service.
+	// Valid values are:
+	// - "ServicePrincipal" (default): Using a service principal (tenantId, clientId, clientSecret)
+	// - "ManagedIdentity": Using Managed Identity assigned to the pod (see aad-pod-identity)
+	// +optional
+	// +kubebuilder:default=ServicePrincipal
+	AuthType *AzureAuthType `json:"authType,omitempty"`
+
+	// Vault Url from which the secrets to be fetched from.
+	VaultURL *string `json:"vaultUrl"`
+
+	// TenantID configures the AzureKvTenant to send requests to. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
+	// +optional
+	TenantID *string `json:"tenantId,omitempty"`
+
+	// EnvironmentType specifies the AzureKvcloud environment endpoints to use for
+	// connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint.
+	// The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152
+	// PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
+	// +kubebuilder:default=PublicCloud
+	EnvironmentType AzureEnvironmentType `json:"environmentType,omitempty"`
+
+	// Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
+	// +optional
+	AuthSecretRef *AzureKVAuth `json:"authSecretRef,omitempty"`
+
+	// ServiceAccountRef specified the service account
+	// that should be used when authenticating with WorkloadIdentity.
+	// +optional
+	ServiceAccountRef *smmeta.ServiceAccountSelector `json:"serviceAccountRef,omitempty"`
+
+	// If multiple Managed Identity is assigned to the pod, you can select the one to be used
+	// +optional
+	IdentityID *string `json:"identityId,omitempty"`
+}
+
+// Configuration used to authenticate with Azure.
+type AzureKVAuth struct {
+	// The AzureKvclientId of the service principle or managed identity used for authentication.
+	// +optional
+	ClientID *smmeta.SecretKeySelector `json:"clientId,omitempty"`
+
+	// The AzureKvtenantId of the managed identity used for authentication.
+	// +optional
+	TenantID *smmeta.SecretKeySelector `json:"tenantId,omitempty"`
+
+	// The AzureKvClientSecret of the service principle used for authentication.
+	// +optional
+	ClientSecret *smmeta.SecretKeySelector `json:"clientSecret,omitempty"`
+
+	// The AzureKvClientCertificate of the service principle used for authentication.
+	// +optional
+	ClientCertificate *smmeta.SecretKeySelector `json:"clientCertificate,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:storageversion
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:scope=Cluster,categories={azure},shortName=azure
+type AzureKv struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Spec AzureKVSpec `json:"spec,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// AzureList contains a list of ExternalSecret resources.
+type AzureList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []AzureKv `json:"items"`
+}
+
+func init() {
+}
+
+// AzureKv type metadata.
+var (
+	AzureKind             = reflect.TypeOf(AzureKv{}).Name()
+	AzureGroupKind        = schema.GroupKind{Group: Group, Kind: AzureKind}.String()
+	AzureKindAPIVersion   = AzureKind + "." + SchemeGroupVersion.String()
+	AzureGroupVersionKind = SchemeGroupVersion.WithKind(AzureKind)
+)

+ 79 - 0
apis/providers/v1alpha1/provider_fake.go

@@ -0,0 +1,79 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	"reflect"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+// FakeSpec contains the static data.
+type FakeSpec struct {
+	// Used to select the correct ESO controller (think: ingress.ingressClassName)
+	// The ESO controller is instantiated with a specific controller name and filters ES based on this property
+	// +optional
+	Controller string `json:"controller,omitempty"`
+
+	// Used to configure http retries if failed
+	// +optional
+	RetrySettings *esmeta.RetrySettings `json:"retrySettings,omitempty"`
+
+	// Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+	// +optional
+	RefreshInterval int                `json:"refreshInterval,omitempty"`
+	Data            []FakeProviderData `json:"data"`
+}
+
+type FakeProviderData struct {
+	Key      string            `json:"key"`
+	Value    string            `json:"value,omitempty"`
+	ValueMap map[string]string `json:"valueMap,omitempty"`
+	Version  string            `json:"version,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:storageversion
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:scope=Cluster,categories={fake},shortName=fake
+type Fake struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Spec FakeSpec `json:"spec,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// FakeList contains a list of ExternalSecret resources.
+type FakeList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []Fake `json:"items"`
+}
+
+func init() {
+}
+
+// Fake type metadata.
+var (
+	FakeKind             = reflect.TypeOf(Fake{}).Name()
+	FakeGroupKind        = schema.GroupKind{Group: Group, Kind: FakeKind}.String()
+	FakeKindAPIVersion   = FakeKind + "." + SchemeGroupVersion.String()
+	FakeGroupVersionKind = SchemeGroupVersion.WithKind(FakeKind)
+)

+ 97 - 0
apis/providers/v1alpha1/provider_gitlab.go

@@ -0,0 +1,97 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	"reflect"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+// +kubebuilder:object:root=true
+// +kubebuilder:storageversion
+// +kubebuilder:subresource:status
+// +kubebuilder:resource:scope=Cluster,categories={gitlab},shortName=gitlab
+type Gitlab struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Spec GitlabSpec `json:"spec,omitempty"`
+}
+
+// Configures a store to sync secrets with a GitLab instance.
+type GitlabSpec struct {
+	// Used to select the correct ESO controller (think: ingress.ingressClassName)
+	// The ESO controller is instantiated with a specific controller name and filters ES based on this property
+	// +optional
+	Controller string `json:"controller,omitempty"`
+
+	// Used to configure http retries if failed
+	// +optional
+	RetrySettings *esmeta.RetrySettings `json:"retrySettings,omitempty"`
+
+	// Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+	// +optional
+	RefreshInterval int `json:"refreshInterval,omitempty"`
+	// URL configures the GitLab instance URL. Defaults to https://gitlab.com/.
+	URL string `json:"url,omitempty"`
+
+	// Auth configures how secret-manager authenticates with a GitLab instance.
+	Auth GitlabAuth `json:"auth"`
+
+	// ProjectID specifies a project where secrets are located.
+	ProjectID string `json:"projectID,omitempty"`
+
+	// InheritFromGroups specifies whether parent groups should be discovered and checked for secrets.
+	InheritFromGroups bool `json:"inheritFromGroups,omitempty"`
+
+	// GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables.
+	GroupIDs []string `json:"groupIDs,omitempty"`
+
+	// Environment environment_scope of gitlab CI/CD variables (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment on how to create environments)
+	Environment string `json:"environment,omitempty"`
+}
+
+type GitlabAuth struct {
+	SecretRef GitlabSecretRef `json:"SecretRef"`
+}
+
+type GitlabSecretRef struct {
+	// AccessToken is used for authentication.
+	AccessToken esmeta.SecretKeySelector `json:"accessToken,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// FakeList contains a list of ExternalSecret resources.
+type GitlabList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []Gitlab `json:"items"`
+}
+
+func init() {
+}
+
+// Gitlab type metadata.
+var (
+	GitlabKind             = reflect.TypeOf(Gitlab{}).Name()
+	GitlabGroupKind        = schema.GroupKind{Group: Group, Kind: GitlabKind}.String()
+	GitlabKindAPIVersion   = GitlabKind + "." + SchemeGroupVersion.String()
+	GitlabGroupVersionKind = SchemeGroupVersion.WithKind(GitlabKind)
+)

+ 43 - 0
apis/providers/v1alpha1/register.go

@@ -0,0 +1,43 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"sigs.k8s.io/controller-runtime/pkg/scheme"
+)
+
+// Package type metadata.
+const (
+	Group   = "providers.external-secrets.io"
+	Version = "v1alpha1"
+)
+
+var (
+	// SchemeGroupVersion is group version used to register these objects.
+	SchemeGroupVersion = schema.GroupVersion{Group: Group, Version: Version}
+
+	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
+	SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}
+	AddToScheme   = SchemeBuilder.AddToScheme
+)
+
+func init() {
+	SchemeBuilder.Register(&Fake{}, &FakeList{})
+	SchemeBuilder.Register(&Gitlab{}, &GitlabList{})
+	SchemeBuilder.Register(&Akeyless{}, &AkeylessList{})
+	SchemeBuilder.Register(&Alibaba{}, &AlibabaList{})
+	SchemeBuilder.Register(&AWS{}, &AWSList{})
+}

+ 85 - 0
apis/providers/v1alpha1/schema.go

@@ -0,0 +1,85 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+	"errors"
+	"fmt"
+	"strings"
+	"sync"
+
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+var refBuilder map[gvk]client.Object
+var refBuildlock sync.RWMutex
+
+func init() {
+	refBuilder = make(map[gvk]client.Object)
+}
+
+type gvk struct {
+	apiGroup   string
+	apiVersion string
+	kind       string
+}
+
+func newGroupVersionKind(ref esmeta.ProviderRef) gvk {
+	group := strings.Split(ref.APIVersion, "/")[0]
+	version := strings.Split(ref.APIVersion, "/")[1]
+	return gvk{
+		apiGroup:   group,
+		apiVersion: version,
+		kind:       ref.Kind,
+	}
+}
+func RefRegister(s client.Object, provider esmeta.ProviderRef) {
+	refBuildlock.Lock()
+	gvk := newGroupVersionKind(provider)
+	defer refBuildlock.Unlock()
+	_, exists := refBuilder[gvk]
+	if exists {
+		panic(fmt.Sprintf("provider %q already registered", gvk))
+	}
+
+	refBuilder[gvk] = s
+}
+
+// ForceRegister adds to store schema, overwriting a store if
+// already registered. Should only be used for testing.
+func RefForceRegister(s client.Object, ref esmeta.ProviderRef) {
+	gvk := newGroupVersionKind(ref)
+	refBuildlock.Lock()
+	refBuilder[gvk] = s
+	refBuildlock.Unlock()
+}
+
+// GetProvider returns the provider from the generic store.
+func GetManifestByKind(ref *esmeta.ProviderRef) (client.Object, error) {
+	if ref == nil {
+		return nil, errors.New("provider ref cannot be nil")
+	}
+	gvk := newGroupVersionKind(*ref)
+	refBuildlock.RLock()
+	f, ok := refBuilder[gvk]
+	refBuildlock.RUnlock()
+
+	if !ok {
+		return nil, fmt.Errorf("failed to find registered object backend for kind: %s", gvk)
+	}
+	return f, nil
+}

+ 896 - 0
apis/providers/v1alpha1/zz_generated.deepcopy.go

@@ -0,0 +1,896 @@
+//go:build !ignore_autogenerated
+
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Code generated by controller-gen. DO NOT EDIT.
+
+package v1alpha1
+
+import (
+	"github.com/external-secrets/external-secrets/apis/meta/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+)
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AWS) DeepCopyInto(out *AWS) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWS.
+func (in *AWS) DeepCopy() *AWS {
+	if in == nil {
+		return nil
+	}
+	out := new(AWS)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *AWS) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AWSAuth) DeepCopyInto(out *AWSAuth) {
+	*out = *in
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(AWSAuthSecretRef)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.JWTAuth != nil {
+		in, out := &in.JWTAuth, &out.JWTAuth
+		*out = new(AWSJWTAuth)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSAuth.
+func (in *AWSAuth) DeepCopy() *AWSAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(AWSAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AWSAuthSecretRef) DeepCopyInto(out *AWSAuthSecretRef) {
+	*out = *in
+	in.AccessKeyID.DeepCopyInto(&out.AccessKeyID)
+	in.SecretAccessKey.DeepCopyInto(&out.SecretAccessKey)
+	if in.SessionToken != nil {
+		in, out := &in.SessionToken, &out.SessionToken
+		*out = new(v1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSAuthSecretRef.
+func (in *AWSAuthSecretRef) DeepCopy() *AWSAuthSecretRef {
+	if in == nil {
+		return nil
+	}
+	out := new(AWSAuthSecretRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AWSJWTAuth) DeepCopyInto(out *AWSJWTAuth) {
+	*out = *in
+	if in.ServiceAccountRef != nil {
+		in, out := &in.ServiceAccountRef, &out.ServiceAccountRef
+		*out = new(v1.ServiceAccountSelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSJWTAuth.
+func (in *AWSJWTAuth) DeepCopy() *AWSJWTAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(AWSJWTAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AWSList) DeepCopyInto(out *AWSList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]AWS, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSList.
+func (in *AWSList) DeepCopy() *AWSList {
+	if in == nil {
+		return nil
+	}
+	out := new(AWSList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *AWSList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AWSSpec) DeepCopyInto(out *AWSSpec) {
+	*out = *in
+	if in.RetrySettings != nil {
+		in, out := &in.RetrySettings, &out.RetrySettings
+		*out = new(v1.RetrySettings)
+		(*in).DeepCopyInto(*out)
+	}
+	in.Auth.DeepCopyInto(&out.Auth)
+	if in.AdditionalRoles != nil {
+		in, out := &in.AdditionalRoles, &out.AdditionalRoles
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+	if in.SessionTags != nil {
+		in, out := &in.SessionTags, &out.SessionTags
+		*out = make([]*Tag, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(Tag)
+				**out = **in
+			}
+		}
+	}
+	if in.SecretsManager != nil {
+		in, out := &in.SecretsManager, &out.SecretsManager
+		*out = new(SecretsManager)
+		**out = **in
+	}
+	if in.TransitiveTagKeys != nil {
+		in, out := &in.TransitiveTagKeys, &out.TransitiveTagKeys
+		*out = make([]*string, len(*in))
+		for i := range *in {
+			if (*in)[i] != nil {
+				in, out := &(*in)[i], &(*out)[i]
+				*out = new(string)
+				**out = **in
+			}
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AWSSpec.
+func (in *AWSSpec) DeepCopy() *AWSSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(AWSSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Akeyless) DeepCopyInto(out *Akeyless) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Akeyless.
+func (in *Akeyless) DeepCopy() *Akeyless {
+	if in == nil {
+		return nil
+	}
+	out := new(Akeyless)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Akeyless) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AkeylessAuth) DeepCopyInto(out *AkeylessAuth) {
+	*out = *in
+	in.SecretRef.DeepCopyInto(&out.SecretRef)
+	if in.KubernetesAuth != nil {
+		in, out := &in.KubernetesAuth, &out.KubernetesAuth
+		*out = new(AkeylessKubernetesAuth)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AkeylessAuth.
+func (in *AkeylessAuth) DeepCopy() *AkeylessAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(AkeylessAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AkeylessAuthSecretRef) DeepCopyInto(out *AkeylessAuthSecretRef) {
+	*out = *in
+	in.AccessID.DeepCopyInto(&out.AccessID)
+	in.AccessType.DeepCopyInto(&out.AccessType)
+	in.AccessTypeParam.DeepCopyInto(&out.AccessTypeParam)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AkeylessAuthSecretRef.
+func (in *AkeylessAuthSecretRef) DeepCopy() *AkeylessAuthSecretRef {
+	if in == nil {
+		return nil
+	}
+	out := new(AkeylessAuthSecretRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AkeylessKubernetesAuth) DeepCopyInto(out *AkeylessKubernetesAuth) {
+	*out = *in
+	if in.ServiceAccountRef != nil {
+		in, out := &in.ServiceAccountRef, &out.ServiceAccountRef
+		*out = new(v1.ServiceAccountSelector)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(v1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AkeylessKubernetesAuth.
+func (in *AkeylessKubernetesAuth) DeepCopy() *AkeylessKubernetesAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(AkeylessKubernetesAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AkeylessList) DeepCopyInto(out *AkeylessList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]Akeyless, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AkeylessList.
+func (in *AkeylessList) DeepCopy() *AkeylessList {
+	if in == nil {
+		return nil
+	}
+	out := new(AkeylessList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *AkeylessList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AkeylessSpec) DeepCopyInto(out *AkeylessSpec) {
+	*out = *in
+	if in.RetrySettings != nil {
+		in, out := &in.RetrySettings, &out.RetrySettings
+		*out = new(v1.RetrySettings)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.AkeylessGWApiURL != nil {
+		in, out := &in.AkeylessGWApiURL, &out.AkeylessGWApiURL
+		*out = new(string)
+		**out = **in
+	}
+	if in.Auth != nil {
+		in, out := &in.Auth, &out.Auth
+		*out = new(AkeylessAuth)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.CABundle != nil {
+		in, out := &in.CABundle, &out.CABundle
+		*out = make([]byte, len(*in))
+		copy(*out, *in)
+	}
+	if in.CAProvider != nil {
+		in, out := &in.CAProvider, &out.CAProvider
+		*out = new(v1.CAProvider)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AkeylessSpec.
+func (in *AkeylessSpec) DeepCopy() *AkeylessSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(AkeylessSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Alibaba) DeepCopyInto(out *Alibaba) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Alibaba.
+func (in *Alibaba) DeepCopy() *Alibaba {
+	if in == nil {
+		return nil
+	}
+	out := new(Alibaba)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Alibaba) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AlibabaAuth) DeepCopyInto(out *AlibabaAuth) {
+	*out = *in
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(AlibabaAuthSecretRef)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.RRSAAuth != nil {
+		in, out := &in.RRSAAuth, &out.RRSAAuth
+		*out = new(AlibabaRRSAAuth)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaAuth.
+func (in *AlibabaAuth) DeepCopy() *AlibabaAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(AlibabaAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AlibabaAuthSecretRef) DeepCopyInto(out *AlibabaAuthSecretRef) {
+	*out = *in
+	in.AccessKeyID.DeepCopyInto(&out.AccessKeyID)
+	in.AccessKeySecret.DeepCopyInto(&out.AccessKeySecret)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaAuthSecretRef.
+func (in *AlibabaAuthSecretRef) DeepCopy() *AlibabaAuthSecretRef {
+	if in == nil {
+		return nil
+	}
+	out := new(AlibabaAuthSecretRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AlibabaList) DeepCopyInto(out *AlibabaList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]Alibaba, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaList.
+func (in *AlibabaList) DeepCopy() *AlibabaList {
+	if in == nil {
+		return nil
+	}
+	out := new(AlibabaList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *AlibabaList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AlibabaRRSAAuth) DeepCopyInto(out *AlibabaRRSAAuth) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaRRSAAuth.
+func (in *AlibabaRRSAAuth) DeepCopy() *AlibabaRRSAAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(AlibabaRRSAAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AlibabaSpec) DeepCopyInto(out *AlibabaSpec) {
+	*out = *in
+	if in.RetrySettings != nil {
+		in, out := &in.RetrySettings, &out.RetrySettings
+		*out = new(v1.RetrySettings)
+		(*in).DeepCopyInto(*out)
+	}
+	in.Auth.DeepCopyInto(&out.Auth)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaSpec.
+func (in *AlibabaSpec) DeepCopy() *AlibabaSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(AlibabaSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AzureKVAuth) DeepCopyInto(out *AzureKVAuth) {
+	*out = *in
+	if in.ClientID != nil {
+		in, out := &in.ClientID, &out.ClientID
+		*out = new(v1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.TenantID != nil {
+		in, out := &in.TenantID, &out.TenantID
+		*out = new(v1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.ClientSecret != nil {
+		in, out := &in.ClientSecret, &out.ClientSecret
+		*out = new(v1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.ClientCertificate != nil {
+		in, out := &in.ClientCertificate, &out.ClientCertificate
+		*out = new(v1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureKVAuth.
+func (in *AzureKVAuth) DeepCopy() *AzureKVAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(AzureKVAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AzureKVSpec) DeepCopyInto(out *AzureKVSpec) {
+	*out = *in
+	if in.RetrySettings != nil {
+		in, out := &in.RetrySettings, &out.RetrySettings
+		*out = new(v1.RetrySettings)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.AuthType != nil {
+		in, out := &in.AuthType, &out.AuthType
+		*out = new(AzureAuthType)
+		**out = **in
+	}
+	if in.VaultURL != nil {
+		in, out := &in.VaultURL, &out.VaultURL
+		*out = new(string)
+		**out = **in
+	}
+	if in.TenantID != nil {
+		in, out := &in.TenantID, &out.TenantID
+		*out = new(string)
+		**out = **in
+	}
+	if in.AuthSecretRef != nil {
+		in, out := &in.AuthSecretRef, &out.AuthSecretRef
+		*out = new(AzureKVAuth)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.ServiceAccountRef != nil {
+		in, out := &in.ServiceAccountRef, &out.ServiceAccountRef
+		*out = new(v1.ServiceAccountSelector)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.IdentityID != nil {
+		in, out := &in.IdentityID, &out.IdentityID
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureKVSpec.
+func (in *AzureKVSpec) DeepCopy() *AzureKVSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(AzureKVSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AzureKv) DeepCopyInto(out *AzureKv) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureKv.
+func (in *AzureKv) DeepCopy() *AzureKv {
+	if in == nil {
+		return nil
+	}
+	out := new(AzureKv)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *AzureKv) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AzureList) DeepCopyInto(out *AzureList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]AzureKv, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureList.
+func (in *AzureList) DeepCopy() *AzureList {
+	if in == nil {
+		return nil
+	}
+	out := new(AzureList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *AzureList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Fake) DeepCopyInto(out *Fake) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Fake.
+func (in *Fake) DeepCopy() *Fake {
+	if in == nil {
+		return nil
+	}
+	out := new(Fake)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Fake) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FakeList) DeepCopyInto(out *FakeList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]Fake, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FakeList.
+func (in *FakeList) DeepCopy() *FakeList {
+	if in == nil {
+		return nil
+	}
+	out := new(FakeList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *FakeList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FakeProviderData) DeepCopyInto(out *FakeProviderData) {
+	*out = *in
+	if in.ValueMap != nil {
+		in, out := &in.ValueMap, &out.ValueMap
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FakeProviderData.
+func (in *FakeProviderData) DeepCopy() *FakeProviderData {
+	if in == nil {
+		return nil
+	}
+	out := new(FakeProviderData)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FakeSpec) DeepCopyInto(out *FakeSpec) {
+	*out = *in
+	if in.RetrySettings != nil {
+		in, out := &in.RetrySettings, &out.RetrySettings
+		*out = new(v1.RetrySettings)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.Data != nil {
+		in, out := &in.Data, &out.Data
+		*out = make([]FakeProviderData, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FakeSpec.
+func (in *FakeSpec) DeepCopy() *FakeSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(FakeSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Gitlab) DeepCopyInto(out *Gitlab) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Gitlab.
+func (in *Gitlab) DeepCopy() *Gitlab {
+	if in == nil {
+		return nil
+	}
+	out := new(Gitlab)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Gitlab) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GitlabAuth) DeepCopyInto(out *GitlabAuth) {
+	*out = *in
+	in.SecretRef.DeepCopyInto(&out.SecretRef)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitlabAuth.
+func (in *GitlabAuth) DeepCopy() *GitlabAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(GitlabAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GitlabList) DeepCopyInto(out *GitlabList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]Gitlab, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitlabList.
+func (in *GitlabList) DeepCopy() *GitlabList {
+	if in == nil {
+		return nil
+	}
+	out := new(GitlabList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *GitlabList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GitlabSecretRef) DeepCopyInto(out *GitlabSecretRef) {
+	*out = *in
+	in.AccessToken.DeepCopyInto(&out.AccessToken)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitlabSecretRef.
+func (in *GitlabSecretRef) DeepCopy() *GitlabSecretRef {
+	if in == nil {
+		return nil
+	}
+	out := new(GitlabSecretRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GitlabSpec) DeepCopyInto(out *GitlabSpec) {
+	*out = *in
+	if in.RetrySettings != nil {
+		in, out := &in.RetrySettings, &out.RetrySettings
+		*out = new(v1.RetrySettings)
+		(*in).DeepCopyInto(*out)
+	}
+	in.Auth.DeepCopyInto(&out.Auth)
+	if in.GroupIDs != nil {
+		in, out := &in.GroupIDs, &out.GroupIDs
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitlabSpec.
+func (in *GitlabSpec) DeepCopy() *GitlabSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(GitlabSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SecretsManager) DeepCopyInto(out *SecretsManager) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretsManager.
+func (in *SecretsManager) DeepCopy() *SecretsManager {
+	if in == nil {
+		return nil
+	}
+	out := new(SecretsManager)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Tag) DeepCopyInto(out *Tag) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tag.
+func (in *Tag) DeepCopy() *Tag {
+	if in == nil {
+		return nil
+	}
+	out := new(Tag)
+	in.DeepCopyInto(out)
+	return out
+}

+ 2 - 0
cmd/root.go

@@ -37,6 +37,7 @@ import (
 	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	genv1alpha1 "github.com/external-secrets/external-secrets/apis/generators/v1alpha1"
+	providers "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/controllers/clusterexternalsecret"
 	"github.com/external-secrets/external-secrets/pkg/controllers/clusterexternalsecret/cesmetrics"
 	"github.com/external-secrets/external-secrets/pkg/controllers/externalsecret"
@@ -96,6 +97,7 @@ func init() {
 	_ = clientgoscheme.AddToScheme(scheme)
 	_ = esv1beta1.AddToScheme(scheme)
 	_ = esv1alpha1.AddToScheme(scheme)
+	_ = providers.AddToScheme(scheme)
 	_ = genv1alpha1.AddToScheme(scheme)
 	_ = apiextensionsv1.AddToScheme(scheme)
 }

+ 16 - 2
config/crds/bases/external-secrets.io_clustersecretstores.yaml

@@ -4888,6 +4888,22 @@ spec:
                     - auth
                     type: object
                 type: object
+              providerRef:
+                description: |-
+                  Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+                  providerRef takes precedence over provider.
+                properties:
+                  apiVersion:
+                    type: string
+                  kind:
+                    type: string
+                  name:
+                    type: string
+                required:
+                - apiVersion
+                - kind
+                - name
+                type: object
               refreshInterval:
                 description: Used to configure store refresh interval in seconds.
                   Empty or 0 will default to the controller config.
@@ -4901,8 +4917,6 @@ spec:
                   retryInterval:
                     type: string
                 type: object
-            required:
-            - provider
             type: object
           status:
             description: SecretStoreStatus defines the observed state of the SecretStore.

+ 16 - 2
config/crds/bases/external-secrets.io_secretstores.yaml

@@ -4888,6 +4888,22 @@ spec:
                     - auth
                     type: object
                 type: object
+              providerRef:
+                description: |-
+                  Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+                  providerRef takes precedence over provider.
+                properties:
+                  apiVersion:
+                    type: string
+                  kind:
+                    type: string
+                  name:
+                    type: string
+                required:
+                - apiVersion
+                - kind
+                - name
+                type: object
               refreshInterval:
                 description: Used to configure store refresh interval in seconds.
                   Empty or 0 will default to the controller config.
@@ -4901,8 +4917,6 @@ spec:
                   retryInterval:
                     type: string
                 type: object
-            required:
-            - provider
             type: object
           status:
             description: SecretStoreStatus defines the observed state of the SecretStore.

+ 6 - 0
config/crds/bases/kustomization.yaml

@@ -16,3 +16,9 @@ resources:
   - generators.external-secrets.io_uuids.yaml
   - generators.external-secrets.io_vaultdynamicsecrets.yaml
   - generators.external-secrets.io_webhooks.yaml
+  - providers.external-secrets.io_akeylesses.yaml
+  - providers.external-secrets.io_alibabas.yaml
+  - providers.external-secrets.io_awses.yaml
+  - providers.external-secrets.io_azurekvs.yaml
+  - providers.external-secrets.io_fakes.yaml
+  - providers.external-secrets.io_gitlabs.yaml

+ 241 - 0
config/crds/bases/providers.external-secrets.io_akeylesses.yaml

@@ -0,0 +1,241 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: akeylesses.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+    - akeyless
+    kind: Akeyless
+    listKind: AkeylessList
+    plural: akeylesses
+    shortNames:
+    - akeyless
+    singular: akeyless
+  scope: Cluster
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: AkeylessSpec Configures an store to sync secrets using Akeyless
+              KV.
+            properties:
+              akeylessGWApiURL:
+                description: Akeyless GW API Url from which the secrets to be fetched
+                  from.
+                type: string
+              authSecretRef:
+                description: Auth configures how the operator authenticates with Akeyless.
+                properties:
+                  kubernetesAuth:
+                    description: |-
+                      Kubernetes authenticates with Akeyless by passing the ServiceAccount
+                      token stored in the named Secret resource.
+                    properties:
+                      accessID:
+                        description: the Akeyless Kubernetes auth-method access-id
+                        type: string
+                      k8sConfName:
+                        description: Kubernetes-auth configuration name in Akeyless-Gateway
+                        type: string
+                      secretRef:
+                        description: |-
+                          Optional secret field containing a Kubernetes ServiceAccount JWT used
+                          for authenticating with Akeyless. If a name is specified without a key,
+                          `token` is the default. If one is not specified, the one bound to
+                          the controller will be used.
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                      serviceAccountRef:
+                        description: |-
+                          Optional service account field containing the name of a kubernetes ServiceAccount.
+                          If the service account is specified, the service account secret token JWT will be used
+                          for authenticating with Akeyless. If the service account selector is not supplied,
+                          the secretRef will be used instead.
+                        properties:
+                          audiences:
+                            description: |-
+                              Audience specifies the `aud` claim for the service account token
+                              If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                              then this audiences will be appended to the list
+                            items:
+                              type: string
+                            type: array
+                          name:
+                            description: The name of the ServiceAccount resource being
+                              referred to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        required:
+                        - name
+                        type: object
+                    required:
+                    - accessID
+                    - k8sConfName
+                    type: object
+                  secretRef:
+                    description: |-
+                      Reference to a Secret that contains the details
+                      to authenticate with Akeyless.
+                    properties:
+                      accessID:
+                        description: The SecretAccessID is used for authentication
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                      accessType:
+                        description: |-
+                          A reference to a specific 'key' within a Secret resource,
+                          In some instances, `key` is a required field.
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                      accessTypeParam:
+                        description: |-
+                          A reference to a specific 'key' within a Secret resource,
+                          In some instances, `key` is a required field.
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                    type: object
+                type: object
+              caBundle:
+                description: |-
+                  PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used
+                  if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates
+                  are used to validate the TLS connection.
+                format: byte
+                type: string
+              caProvider:
+                description: The provider for the CA bundle to use to validate Akeyless
+                  Gateway certificate.
+                properties:
+                  key:
+                    description: The key where the CA certificate can be found in
+                      the Secret or ConfigMap.
+                    type: string
+                  name:
+                    description: The name of the object located at the provider type.
+                    type: string
+                  namespace:
+                    description: |-
+                      The namespace the Provider type is in.
+                      Can only be defined when used in a ClusterSecretStore.
+                    type: string
+                  type:
+                    description: The type of provider to use such as "Secret", or
+                      "ConfigMap".
+                    enum:
+                    - Secret
+                    - ConfigMap
+                    type: string
+                required:
+                - name
+                - type
+                type: object
+              controller:
+                description: |-
+                  Used to select the correct ESO controller (think: ingress.ingressClassName)
+                  The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                type: string
+              refreshInterval:
+                description: Used to configure store refresh interval in seconds.
+                  Empty or 0 will default to the controller config.
+                type: integer
+              retrySettings:
+                description: Used to configure http retries if failed
+                properties:
+                  maxRetries:
+                    format: int32
+                    type: integer
+                  retryInterval:
+                    type: string
+                type: object
+            required:
+            - akeylessGWApiURL
+            - authSecretRef
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}

+ 139 - 0
config/crds/bases/providers.external-secrets.io_alibabas.yaml

@@ -0,0 +1,139 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: alibabas.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+    - alibaba
+    kind: Alibaba
+    listKind: AlibabaList
+    plural: alibabas
+    shortNames:
+    - alibaba
+    singular: alibaba
+  scope: Cluster
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: AlibabaProvider configures a store to sync secrets using
+              the Alibaba Secret Manager provider.
+            properties:
+              auth:
+                description: AlibabaAuth contains a secretRef for credentials.
+                properties:
+                  rrsa:
+                    description: Authenticate against Alibaba using RRSA.
+                    properties:
+                      oidcProviderArn:
+                        type: string
+                      oidcTokenFilePath:
+                        type: string
+                      roleArn:
+                        type: string
+                      sessionName:
+                        type: string
+                    required:
+                    - oidcProviderArn
+                    - oidcTokenFilePath
+                    - roleArn
+                    - sessionName
+                    type: object
+                  secretRef:
+                    description: AlibabaAuthSecretRef holds secret references for
+                      Alibaba credentials.
+                    properties:
+                      accessKeyIDSecretRef:
+                        description: The AccessKeyID is used for authentication
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                      accessKeySecretSecretRef:
+                        description: The AccessKeySecret is used for authentication
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                    required:
+                    - accessKeyIDSecretRef
+                    - accessKeySecretSecretRef
+                    type: object
+                type: object
+              controller:
+                description: |-
+                  Used to select the correct ESO controller (think: ingress.ingressClassName)
+                  The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                type: string
+              refreshInterval:
+                description: Used to configure store refresh interval in seconds.
+                  Empty or 0 will default to the controller config.
+                type: integer
+              regionID:
+                description: Alibaba Region to be used for the provider
+                type: string
+              retrySettings:
+                description: Used to configure http retries if failed
+                properties:
+                  maxRetries:
+                    format: int32
+                    type: integer
+                  retryInterval:
+                    type: string
+                type: object
+            required:
+            - auth
+            - regionID
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}

+ 233 - 0
config/crds/bases/providers.external-secrets.io_awses.yaml

@@ -0,0 +1,233 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: awses.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+    - aws
+    kind: AWS
+    listKind: AWSList
+    plural: awses
+    shortNames:
+    - aws
+    singular: aws
+  scope: Cluster
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: AWSProvider configures a store to sync secrets with AWS.
+            properties:
+              additionalRoles:
+                description: AdditionalRoles is a chained list of Role ARNs which
+                  the provider will sequentially assume before assuming the Role
+                items:
+                  type: string
+                type: array
+              auth:
+                description: |-
+                  Auth defines the information necessary to authenticate against AWS
+                  if not set aws sdk will infer credentials from your environment
+                  see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials
+                properties:
+                  jwt:
+                    description: Authenticate against AWS using service account tokens.
+                    properties:
+                      serviceAccountRef:
+                        description: A reference to a ServiceAccount resource.
+                        properties:
+                          audiences:
+                            description: |-
+                              Audience specifies the `aud` claim for the service account token
+                              If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                              then this audiences will be appended to the list
+                            items:
+                              type: string
+                            type: array
+                          name:
+                            description: The name of the ServiceAccount resource being
+                              referred to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        required:
+                        - name
+                        type: object
+                    type: object
+                  secretRef:
+                    description: |-
+                      AWSAuthSecretRef holds secret references for AWS credentials
+                      both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
+                    properties:
+                      accessKeyIDSecretRef:
+                        description: The AccessKeyID is used for authentication
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                      secretAccessKeySecretRef:
+                        description: The SecretAccessKey is used for authentication
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                      sessionTokenSecretRef:
+                        description: |-
+                          The SessionToken used for authentication
+                          This must be defined if AccessKeyID and SecretAccessKey are temporary credentials
+                          see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                    type: object
+                type: object
+              controller:
+                description: |-
+                  Used to select the correct ESO controller (think: ingress.ingressClassName)
+                  The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                type: string
+              externalID:
+                description: AWS External ID set on assumed IAM roles
+                type: string
+              prefix:
+                description: Prefix adds a prefix to all retrieved values.
+                type: string
+              refreshInterval:
+                description: Used to configure store refresh interval in seconds.
+                  Empty or 0 will default to the controller config.
+                type: integer
+              region:
+                description: AWS Region to be used for the provider
+                type: string
+              retrySettings:
+                description: Used to configure http retries if failed
+                properties:
+                  maxRetries:
+                    format: int32
+                    type: integer
+                  retryInterval:
+                    type: string
+                type: object
+              role:
+                description: Role is a Role ARN which the provider will assume
+                type: string
+              secretsManager:
+                description: SecretsManager defines how the provider behaves when
+                  interacting with AWS SecretsManager
+                properties:
+                  forceDeleteWithoutRecovery:
+                    description: |-
+                      Specifies whether to delete the secret without any recovery window. You
+                      can't use both this parameter and RecoveryWindowInDays in the same call.
+                      If you don't use either, then by default Secrets Manager uses a 30 day
+                      recovery window.
+                      see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-ForceDeleteWithoutRecovery
+                    type: boolean
+                  recoveryWindowInDays:
+                    description: |-
+                      The number of days from 7 to 30 that Secrets Manager waits before
+                      permanently deleting the secret. You can't use both this parameter and
+                      ForceDeleteWithoutRecovery in the same call. If you don't use either,
+                      then by default Secrets Manager uses a 30 day recovery window.
+                      see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-RecoveryWindowInDays
+                    format: int64
+                    type: integer
+                type: object
+              service:
+                description: Service defines which service should be used to fetch
+                  the secrets
+                enum:
+                - SecretsManager
+                - ParameterStore
+                type: string
+              sessionTags:
+                description: AWS STS assume role session tags
+                items:
+                  properties:
+                    key:
+                      type: string
+                    value:
+                      type: string
+                  required:
+                  - key
+                  - value
+                  type: object
+                type: array
+              transitiveTagKeys:
+                description: AWS STS assume role transitive session tags. Required
+                  when multiple rules are used with the provider
+                items:
+                  type: string
+                type: array
+            required:
+            - region
+            - service
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}

+ 211 - 0
config/crds/bases/providers.external-secrets.io_azurekvs.yaml

@@ -0,0 +1,211 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: azurekvs.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+    - azure
+    kind: AzureKv
+    listKind: AzureKvList
+    plural: azurekvs
+    shortNames:
+    - azure
+    singular: azurekv
+  scope: Cluster
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: Configures an store to sync secrets using AzureKvKV.
+            properties:
+              authSecretRef:
+                description: Auth configures how the operator authenticates with Azure.
+                  Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
+                properties:
+                  clientCertificate:
+                    description: The AzureKvClientCertificate of the service principle
+                      used for authentication.
+                    properties:
+                      key:
+                        description: |-
+                          The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                          defaulted, in others it may be required.
+                        type: string
+                      name:
+                        description: The name of the Secret resource being referred
+                          to.
+                        type: string
+                      namespace:
+                        description: |-
+                          Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                          to the namespace of the referent.
+                        type: string
+                    type: object
+                  clientId:
+                    description: The AzureKvclientId of the service principle or managed
+                      identity used for authentication.
+                    properties:
+                      key:
+                        description: |-
+                          The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                          defaulted, in others it may be required.
+                        type: string
+                      name:
+                        description: The name of the Secret resource being referred
+                          to.
+                        type: string
+                      namespace:
+                        description: |-
+                          Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                          to the namespace of the referent.
+                        type: string
+                    type: object
+                  clientSecret:
+                    description: The AzureKvClientSecret of the service principle
+                      used for authentication.
+                    properties:
+                      key:
+                        description: |-
+                          The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                          defaulted, in others it may be required.
+                        type: string
+                      name:
+                        description: The name of the Secret resource being referred
+                          to.
+                        type: string
+                      namespace:
+                        description: |-
+                          Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                          to the namespace of the referent.
+                        type: string
+                    type: object
+                  tenantId:
+                    description: The AzureKvtenantId of the managed identity used
+                      for authentication.
+                    properties:
+                      key:
+                        description: |-
+                          The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                          defaulted, in others it may be required.
+                        type: string
+                      name:
+                        description: The name of the Secret resource being referred
+                          to.
+                        type: string
+                      namespace:
+                        description: |-
+                          Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                          to the namespace of the referent.
+                        type: string
+                    type: object
+                type: object
+              authType:
+                default: ServicePrincipal
+                description: |-
+                  Auth type defines how to authenticate to the keyvault service.
+                  Valid values are:
+                  - "ServicePrincipal" (default): Using a service principal (tenantId, clientId, clientSecret)
+                  - "ManagedIdentity": Using Managed Identity assigned to the pod (see aad-pod-identity)
+                enum:
+                - ServicePrincipal
+                - ManagedIdentity
+                - WorkloadIdentity
+                type: string
+              controller:
+                description: |-
+                  Used to select the correct ESO controller (think: ingress.ingressClassName)
+                  The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                type: string
+              environmentType:
+                default: PublicCloud
+                description: |-
+                  EnvironmentType specifies the AzureKvcloud environment endpoints to use for
+                  connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint.
+                  The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152
+                  PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
+                enum:
+                - PublicCloud
+                - USGovernmentCloud
+                - ChinaCloud
+                - GermanCloud
+                type: string
+              identityId:
+                description: If multiple Managed Identity is assigned to the pod,
+                  you can select the one to be used
+                type: string
+              refreshInterval:
+                description: Used to configure store refresh interval in seconds.
+                  Empty or 0 will default to the controller config.
+                type: integer
+              retrySettings:
+                description: Used to configure http retries if failed
+                properties:
+                  maxRetries:
+                    format: int32
+                    type: integer
+                  retryInterval:
+                    type: string
+                type: object
+              serviceAccountRef:
+                description: |-
+                  ServiceAccountRef specified the service account
+                  that should be used when authenticating with WorkloadIdentity.
+                properties:
+                  audiences:
+                    description: |-
+                      Audience specifies the `aud` claim for the service account token
+                      If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                      then this audiences will be appended to the list
+                    items:
+                      type: string
+                    type: array
+                  name:
+                    description: The name of the ServiceAccount resource being referred
+                      to.
+                    type: string
+                  namespace:
+                    description: |-
+                      Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                      to the namespace of the referent.
+                    type: string
+                required:
+                - name
+                type: object
+              tenantId:
+                description: TenantID configures the AzureKvTenant to send requests
+                  to. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
+                type: string
+              vaultUrl:
+                description: Vault Url from which the secrets to be fetched from.
+                type: string
+            required:
+            - vaultUrl
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}

+ 86 - 0
config/crds/bases/providers.external-secrets.io_fakes.yaml

@@ -0,0 +1,86 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: fakes.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+    - fake
+    kind: Fake
+    listKind: FakeList
+    plural: fakes
+    shortNames:
+    - fake
+    singular: fake
+  scope: Cluster
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: FakeSpec contains the static data.
+            properties:
+              controller:
+                description: |-
+                  Used to select the correct ESO controller (think: ingress.ingressClassName)
+                  The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                type: string
+              data:
+                items:
+                  properties:
+                    key:
+                      type: string
+                    value:
+                      type: string
+                    valueMap:
+                      additionalProperties:
+                        type: string
+                      type: object
+                    version:
+                      type: string
+                  required:
+                  - key
+                  type: object
+                type: array
+              refreshInterval:
+                description: Used to configure store refresh interval in seconds.
+                  Empty or 0 will default to the controller config.
+                type: integer
+              retrySettings:
+                description: Used to configure http retries if failed
+                properties:
+                  maxRetries:
+                    format: int32
+                    type: integer
+                  retryInterval:
+                    type: string
+                type: object
+            required:
+            - data
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}

+ 119 - 0
config/crds/bases/providers.external-secrets.io_gitlabs.yaml

@@ -0,0 +1,119 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: gitlabs.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+    - gitlab
+    kind: Gitlab
+    listKind: GitlabList
+    plural: gitlabs
+    shortNames:
+    - gitlab
+    singular: gitlab
+  scope: Cluster
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: Configures a store to sync secrets with a GitLab instance.
+            properties:
+              auth:
+                description: Auth configures how secret-manager authenticates with
+                  a GitLab instance.
+                properties:
+                  SecretRef:
+                    properties:
+                      accessToken:
+                        description: AccessToken is used for authentication.
+                        properties:
+                          key:
+                            description: |-
+                              The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                              defaulted, in others it may be required.
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                              to the namespace of the referent.
+                            type: string
+                        type: object
+                    type: object
+                required:
+                - SecretRef
+                type: object
+              controller:
+                description: |-
+                  Used to select the correct ESO controller (think: ingress.ingressClassName)
+                  The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                type: string
+              environment:
+                description: Environment environment_scope of gitlab CI/CD variables
+                  (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment
+                  on how to create environments)
+                type: string
+              groupIDs:
+                description: GroupIDs specify, which gitlab groups to pull secrets
+                  from. Group secrets are read from left to right followed by the
+                  project variables.
+                items:
+                  type: string
+                type: array
+              inheritFromGroups:
+                description: InheritFromGroups specifies whether parent groups should
+                  be discovered and checked for secrets.
+                type: boolean
+              projectID:
+                description: ProjectID specifies a project where secrets are located.
+                type: string
+              refreshInterval:
+                description: Used to configure store refresh interval in seconds.
+                  Empty or 0 will default to the controller config.
+                type: integer
+              retrySettings:
+                description: Used to configure http retries if failed
+                properties:
+                  maxRetries:
+                    format: int32
+                    type: integer
+                  retryInterval:
+                    type: string
+                type: object
+              url:
+                description: URL configures the GitLab instance URL. Defaults to https://gitlab.com/.
+                type: string
+            required:
+            - auth
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}

+ 0 - 4
deploy/charts/external-secrets/templates/crds/README.md

@@ -1,4 +0,0 @@
-# CRD Template Directory
-CRDs are autogenerated during helm packaging. To install the CRDs set `installCRDS: true` during helm install or upgrade.
-
-The latest CRDs in the repository are located [here](../../../../crds).

+ 16 - 2
deploy/charts/external-secrets/tests/__snapshot__/crds_test.yaml.snap

@@ -4545,6 +4545,22 @@ should match snapshot of default values:
                             - auth
                           type: object
                       type: object
+                    providerRef:
+                      description: |-
+                        Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+                        providerRef takes precedence over provider.
+                      properties:
+                        apiVersion:
+                          type: string
+                        kind:
+                          type: string
+                        name:
+                          type: string
+                      required:
+                        - apiVersion
+                        - kind
+                        - name
+                      type: object
                     refreshInterval:
                       description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
                       type: integer
@@ -4557,8 +4573,6 @@ should match snapshot of default values:
                         retryInterval:
                           type: string
                       type: object
-                  required:
-                    - provider
                   type: object
                 status:
                   description: SecretStoreStatus defines the observed state of the SecretStore.

+ 1 - 1
deploy/charts/external-secrets/tests/crds_test.yaml

@@ -1,6 +1,6 @@
 suite: test crds
 templates:
-  - crds/secretstore.yaml
+  - crds/secretstores_external-secrets_io.yaml
 tests:
   - it: should match snapshot of default values
     asserts:

+ 3 - 3
deploy/charts/external-secrets/tests/webhook_test.yaml

@@ -4,7 +4,7 @@ templates:
   - webhook-secret.yaml
   - webhook-certificate.yaml
   - validatingwebhook.yaml
-  - crds/externalsecret.yaml
+  - crds/externalsecrets_external-secrets_io.yaml
 tests:
   - it: should match snapshot of default values
     asserts:
@@ -148,7 +148,7 @@ tests:
           value: "NAMESPACE/RELEASE-NAME-external-secrets-webhook"
     templates:
       - validatingwebhook.yaml
-      - crds/externalsecret.yaml
+      - crds/externalsecrets_external-secrets_io.yaml
   - it: should not add annotations to the webhook
     set:
       webhook.create: true
@@ -160,7 +160,7 @@ tests:
           # value: "NAMESPACE/RELEASE-NAME-external-secrets-webhook"
     templates:
       - validatingwebhook.yaml
-      - crds/externalsecret.yaml
+      - crds/externalsecrets_external-secrets_io.yaml
   - it: should override metrics port
     set:
       webhook.metrics.listen.port: 8888

+ 1080 - 4
deploy/crds/bundle.yaml

@@ -5190,6 +5190,22 @@ spec:
                         - auth
                       type: object
                   type: object
+                providerRef:
+                  description: |-
+                    Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+                    providerRef takes precedence over provider.
+                  properties:
+                    apiVersion:
+                      type: string
+                    kind:
+                      type: string
+                    name:
+                      type: string
+                  required:
+                    - apiVersion
+                    - kind
+                    - name
+                  type: object
                 refreshInterval:
                   description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
                   type: integer
@@ -5202,8 +5218,6 @@ spec:
                     retryInterval:
                       type: string
                   type: object
-              required:
-                - provider
               type: object
             status:
               description: SecretStoreStatus defines the observed state of the SecretStore.
@@ -10970,6 +10984,22 @@ spec:
                         - auth
                       type: object
                   type: object
+                providerRef:
+                  description: |-
+                    Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+                    providerRef takes precedence over provider.
+                  properties:
+                    apiVersion:
+                      type: string
+                    kind:
+                      type: string
+                    name:
+                      type: string
+                  required:
+                    - apiVersion
+                    - kind
+                    - name
+                  type: object
                 refreshInterval:
                   description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
                   type: integer
@@ -10982,8 +11012,6 @@ spec:
                     retryInterval:
                       type: string
                   type: object
-              required:
-                - provider
               type: object
             status:
               description: SecretStoreStatus defines the observed state of the SecretStore.
@@ -12705,3 +12733,1051 @@ spec:
           name: kubernetes
           namespace: default
           path: /convert
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: akeylesses.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+      - akeyless
+    kind: Akeyless
+    listKind: AkeylessList
+    plural: akeylesses
+    shortNames:
+      - akeyless
+    singular: akeyless
+  scope: Cluster
+  versions:
+    - name: v1alpha1
+      schema:
+        openAPIV3Schema:
+          properties:
+            apiVersion:
+              description: |-
+                APIVersion defines the versioned schema of this representation of an object.
+                Servers should convert recognized schemas to the latest internal value, and
+                may reject unrecognized values.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              type: string
+            kind:
+              description: |-
+                Kind is a string value representing the REST resource this object represents.
+                Servers may infer this from the endpoint the client submits requests to.
+                Cannot be updated.
+                In CamelCase.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              type: string
+            metadata:
+              type: object
+            spec:
+              description: AkeylessSpec Configures an store to sync secrets using Akeyless KV.
+              properties:
+                akeylessGWApiURL:
+                  description: Akeyless GW API Url from which the secrets to be fetched from.
+                  type: string
+                authSecretRef:
+                  description: Auth configures how the operator authenticates with Akeyless.
+                  properties:
+                    kubernetesAuth:
+                      description: |-
+                        Kubernetes authenticates with Akeyless by passing the ServiceAccount
+                        token stored in the named Secret resource.
+                      properties:
+                        accessID:
+                          description: the Akeyless Kubernetes auth-method access-id
+                          type: string
+                        k8sConfName:
+                          description: Kubernetes-auth configuration name in Akeyless-Gateway
+                          type: string
+                        secretRef:
+                          description: |-
+                            Optional secret field containing a Kubernetes ServiceAccount JWT used
+                            for authenticating with Akeyless. If a name is specified without a key,
+                            `token` is the default. If one is not specified, the one bound to
+                            the controller will be used.
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                        serviceAccountRef:
+                          description: |-
+                            Optional service account field containing the name of a kubernetes ServiceAccount.
+                            If the service account is specified, the service account secret token JWT will be used
+                            for authenticating with Akeyless. If the service account selector is not supplied,
+                            the secretRef will be used instead.
+                          properties:
+                            audiences:
+                              description: |-
+                                Audience specifies the `aud` claim for the service account token
+                                If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                then this audiences will be appended to the list
+                              items:
+                                type: string
+                              type: array
+                            name:
+                              description: The name of the ServiceAccount resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          required:
+                            - name
+                          type: object
+                      required:
+                        - accessID
+                        - k8sConfName
+                      type: object
+                    secretRef:
+                      description: |-
+                        Reference to a Secret that contains the details
+                        to authenticate with Akeyless.
+                      properties:
+                        accessID:
+                          description: The SecretAccessID is used for authentication
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                        accessType:
+                          description: |-
+                            A reference to a specific 'key' within a Secret resource,
+                            In some instances, `key` is a required field.
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                        accessTypeParam:
+                          description: |-
+                            A reference to a specific 'key' within a Secret resource,
+                            In some instances, `key` is a required field.
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                      type: object
+                  type: object
+                caBundle:
+                  description: |-
+                    PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used
+                    if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates
+                    are used to validate the TLS connection.
+                  format: byte
+                  type: string
+                caProvider:
+                  description: The provider for the CA bundle to use to validate Akeyless Gateway certificate.
+                  properties:
+                    key:
+                      description: The key where the CA certificate can be found in the Secret or ConfigMap.
+                      type: string
+                    name:
+                      description: The name of the object located at the provider type.
+                      type: string
+                    namespace:
+                      description: |-
+                        The namespace the Provider type is in.
+                        Can only be defined when used in a ClusterSecretStore.
+                      type: string
+                    type:
+                      description: The type of provider to use such as "Secret", or "ConfigMap".
+                      enum:
+                        - Secret
+                        - ConfigMap
+                      type: string
+                  required:
+                    - name
+                    - type
+                  type: object
+                controller:
+                  description: |-
+                    Used to select the correct ESO controller (think: ingress.ingressClassName)
+                    The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                  type: string
+                refreshInterval:
+                  description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+                  type: integer
+                retrySettings:
+                  description: Used to configure http retries if failed
+                  properties:
+                    maxRetries:
+                      format: int32
+                      type: integer
+                    retryInterval:
+                      type: string
+                  type: object
+              required:
+                - akeylessGWApiURL
+                - authSecretRef
+              type: object
+          type: object
+      served: true
+      storage: true
+      subresources:
+        status: {}
+  conversion:
+    strategy: Webhook
+    webhook:
+      conversionReviewVersions:
+        - v1
+      clientConfig:
+        service:
+          name: kubernetes
+          namespace: default
+          path: /convert
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: alibabas.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+      - alibaba
+    kind: Alibaba
+    listKind: AlibabaList
+    plural: alibabas
+    shortNames:
+      - alibaba
+    singular: alibaba
+  scope: Cluster
+  versions:
+    - name: v1alpha1
+      schema:
+        openAPIV3Schema:
+          properties:
+            apiVersion:
+              description: |-
+                APIVersion defines the versioned schema of this representation of an object.
+                Servers should convert recognized schemas to the latest internal value, and
+                may reject unrecognized values.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              type: string
+            kind:
+              description: |-
+                Kind is a string value representing the REST resource this object represents.
+                Servers may infer this from the endpoint the client submits requests to.
+                Cannot be updated.
+                In CamelCase.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              type: string
+            metadata:
+              type: object
+            spec:
+              description: AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
+              properties:
+                auth:
+                  description: AlibabaAuth contains a secretRef for credentials.
+                  properties:
+                    rrsa:
+                      description: Authenticate against Alibaba using RRSA.
+                      properties:
+                        oidcProviderArn:
+                          type: string
+                        oidcTokenFilePath:
+                          type: string
+                        roleArn:
+                          type: string
+                        sessionName:
+                          type: string
+                      required:
+                        - oidcProviderArn
+                        - oidcTokenFilePath
+                        - roleArn
+                        - sessionName
+                      type: object
+                    secretRef:
+                      description: AlibabaAuthSecretRef holds secret references for Alibaba credentials.
+                      properties:
+                        accessKeyIDSecretRef:
+                          description: The AccessKeyID is used for authentication
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                        accessKeySecretSecretRef:
+                          description: The AccessKeySecret is used for authentication
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                      required:
+                        - accessKeyIDSecretRef
+                        - accessKeySecretSecretRef
+                      type: object
+                  type: object
+                controller:
+                  description: |-
+                    Used to select the correct ESO controller (think: ingress.ingressClassName)
+                    The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                  type: string
+                refreshInterval:
+                  description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+                  type: integer
+                regionID:
+                  description: Alibaba Region to be used for the provider
+                  type: string
+                retrySettings:
+                  description: Used to configure http retries if failed
+                  properties:
+                    maxRetries:
+                      format: int32
+                      type: integer
+                    retryInterval:
+                      type: string
+                  type: object
+              required:
+                - auth
+                - regionID
+              type: object
+          type: object
+      served: true
+      storage: true
+      subresources:
+        status: {}
+  conversion:
+    strategy: Webhook
+    webhook:
+      conversionReviewVersions:
+        - v1
+      clientConfig:
+        service:
+          name: kubernetes
+          namespace: default
+          path: /convert
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: awses.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+      - aws
+    kind: AWS
+    listKind: AWSList
+    plural: awses
+    shortNames:
+      - aws
+    singular: aws
+  scope: Cluster
+  versions:
+    - name: v1alpha1
+      schema:
+        openAPIV3Schema:
+          properties:
+            apiVersion:
+              description: |-
+                APIVersion defines the versioned schema of this representation of an object.
+                Servers should convert recognized schemas to the latest internal value, and
+                may reject unrecognized values.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              type: string
+            kind:
+              description: |-
+                Kind is a string value representing the REST resource this object represents.
+                Servers may infer this from the endpoint the client submits requests to.
+                Cannot be updated.
+                In CamelCase.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              type: string
+            metadata:
+              type: object
+            spec:
+              description: AWSProvider configures a store to sync secrets with AWS.
+              properties:
+                additionalRoles:
+                  description: AdditionalRoles is a chained list of Role ARNs which the provider will sequentially assume before assuming the Role
+                  items:
+                    type: string
+                  type: array
+                auth:
+                  description: |-
+                    Auth defines the information necessary to authenticate against AWS
+                    if not set aws sdk will infer credentials from your environment
+                    see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials
+                  properties:
+                    jwt:
+                      description: Authenticate against AWS using service account tokens.
+                      properties:
+                        serviceAccountRef:
+                          description: A reference to a ServiceAccount resource.
+                          properties:
+                            audiences:
+                              description: |-
+                                Audience specifies the `aud` claim for the service account token
+                                If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                then this audiences will be appended to the list
+                              items:
+                                type: string
+                              type: array
+                            name:
+                              description: The name of the ServiceAccount resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          required:
+                            - name
+                          type: object
+                      type: object
+                    secretRef:
+                      description: |-
+                        AWSAuthSecretRef holds secret references for AWS credentials
+                        both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
+                      properties:
+                        accessKeyIDSecretRef:
+                          description: The AccessKeyID is used for authentication
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                        secretAccessKeySecretRef:
+                          description: The SecretAccessKey is used for authentication
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                        sessionTokenSecretRef:
+                          description: |-
+                            The SessionToken used for authentication
+                            This must be defined if AccessKeyID and SecretAccessKey are temporary credentials
+                            see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                      type: object
+                  type: object
+                controller:
+                  description: |-
+                    Used to select the correct ESO controller (think: ingress.ingressClassName)
+                    The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                  type: string
+                externalID:
+                  description: AWS External ID set on assumed IAM roles
+                  type: string
+                prefix:
+                  description: Prefix adds a prefix to all retrieved values.
+                  type: string
+                refreshInterval:
+                  description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+                  type: integer
+                region:
+                  description: AWS Region to be used for the provider
+                  type: string
+                retrySettings:
+                  description: Used to configure http retries if failed
+                  properties:
+                    maxRetries:
+                      format: int32
+                      type: integer
+                    retryInterval:
+                      type: string
+                  type: object
+                role:
+                  description: Role is a Role ARN which the provider will assume
+                  type: string
+                secretsManager:
+                  description: SecretsManager defines how the provider behaves when interacting with AWS SecretsManager
+                  properties:
+                    forceDeleteWithoutRecovery:
+                      description: |-
+                        Specifies whether to delete the secret without any recovery window. You
+                        can't use both this parameter and RecoveryWindowInDays in the same call.
+                        If you don't use either, then by default Secrets Manager uses a 30 day
+                        recovery window.
+                        see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-ForceDeleteWithoutRecovery
+                      type: boolean
+                    recoveryWindowInDays:
+                      description: |-
+                        The number of days from 7 to 30 that Secrets Manager waits before
+                        permanently deleting the secret. You can't use both this parameter and
+                        ForceDeleteWithoutRecovery in the same call. If you don't use either,
+                        then by default Secrets Manager uses a 30 day recovery window.
+                        see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-RecoveryWindowInDays
+                      format: int64
+                      type: integer
+                  type: object
+                service:
+                  description: Service defines which service should be used to fetch the secrets
+                  enum:
+                    - SecretsManager
+                    - ParameterStore
+                  type: string
+                sessionTags:
+                  description: AWS STS assume role session tags
+                  items:
+                    properties:
+                      key:
+                        type: string
+                      value:
+                        type: string
+                    required:
+                      - key
+                      - value
+                    type: object
+                  type: array
+                transitiveTagKeys:
+                  description: AWS STS assume role transitive session tags. Required when multiple rules are used with the provider
+                  items:
+                    type: string
+                  type: array
+              required:
+                - region
+                - service
+              type: object
+          type: object
+      served: true
+      storage: true
+      subresources:
+        status: {}
+  conversion:
+    strategy: Webhook
+    webhook:
+      conversionReviewVersions:
+        - v1
+      clientConfig:
+        service:
+          name: kubernetes
+          namespace: default
+          path: /convert
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: azurekvs.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+      - azure
+    kind: AzureKv
+    listKind: AzureKvList
+    plural: azurekvs
+    shortNames:
+      - azure
+    singular: azurekv
+  scope: Cluster
+  versions:
+    - name: v1alpha1
+      schema:
+        openAPIV3Schema:
+          properties:
+            apiVersion:
+              description: |-
+                APIVersion defines the versioned schema of this representation of an object.
+                Servers should convert recognized schemas to the latest internal value, and
+                may reject unrecognized values.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              type: string
+            kind:
+              description: |-
+                Kind is a string value representing the REST resource this object represents.
+                Servers may infer this from the endpoint the client submits requests to.
+                Cannot be updated.
+                In CamelCase.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              type: string
+            metadata:
+              type: object
+            spec:
+              description: Configures an store to sync secrets using AzureKvKV.
+              properties:
+                authSecretRef:
+                  description: Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
+                  properties:
+                    clientCertificate:
+                      description: The AzureKvClientCertificate of the service principle used for authentication.
+                      properties:
+                        key:
+                          description: |-
+                            The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                            defaulted, in others it may be required.
+                          type: string
+                        name:
+                          description: The name of the Secret resource being referred to.
+                          type: string
+                        namespace:
+                          description: |-
+                            Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                            to the namespace of the referent.
+                          type: string
+                      type: object
+                    clientId:
+                      description: The AzureKvclientId of the service principle or managed identity used for authentication.
+                      properties:
+                        key:
+                          description: |-
+                            The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                            defaulted, in others it may be required.
+                          type: string
+                        name:
+                          description: The name of the Secret resource being referred to.
+                          type: string
+                        namespace:
+                          description: |-
+                            Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                            to the namespace of the referent.
+                          type: string
+                      type: object
+                    clientSecret:
+                      description: The AzureKvClientSecret of the service principle used for authentication.
+                      properties:
+                        key:
+                          description: |-
+                            The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                            defaulted, in others it may be required.
+                          type: string
+                        name:
+                          description: The name of the Secret resource being referred to.
+                          type: string
+                        namespace:
+                          description: |-
+                            Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                            to the namespace of the referent.
+                          type: string
+                      type: object
+                    tenantId:
+                      description: The AzureKvtenantId of the managed identity used for authentication.
+                      properties:
+                        key:
+                          description: |-
+                            The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                            defaulted, in others it may be required.
+                          type: string
+                        name:
+                          description: The name of the Secret resource being referred to.
+                          type: string
+                        namespace:
+                          description: |-
+                            Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                            to the namespace of the referent.
+                          type: string
+                      type: object
+                  type: object
+                authType:
+                  default: ServicePrincipal
+                  description: |-
+                    Auth type defines how to authenticate to the keyvault service.
+                    Valid values are:
+                    - "ServicePrincipal" (default): Using a service principal (tenantId, clientId, clientSecret)
+                    - "ManagedIdentity": Using Managed Identity assigned to the pod (see aad-pod-identity)
+                  enum:
+                    - ServicePrincipal
+                    - ManagedIdentity
+                    - WorkloadIdentity
+                  type: string
+                controller:
+                  description: |-
+                    Used to select the correct ESO controller (think: ingress.ingressClassName)
+                    The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                  type: string
+                environmentType:
+                  default: PublicCloud
+                  description: |-
+                    EnvironmentType specifies the AzureKvcloud environment endpoints to use for
+                    connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint.
+                    The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152
+                    PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
+                  enum:
+                    - PublicCloud
+                    - USGovernmentCloud
+                    - ChinaCloud
+                    - GermanCloud
+                  type: string
+                identityId:
+                  description: If multiple Managed Identity is assigned to the pod, you can select the one to be used
+                  type: string
+                refreshInterval:
+                  description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+                  type: integer
+                retrySettings:
+                  description: Used to configure http retries if failed
+                  properties:
+                    maxRetries:
+                      format: int32
+                      type: integer
+                    retryInterval:
+                      type: string
+                  type: object
+                serviceAccountRef:
+                  description: |-
+                    ServiceAccountRef specified the service account
+                    that should be used when authenticating with WorkloadIdentity.
+                  properties:
+                    audiences:
+                      description: |-
+                        Audience specifies the `aud` claim for the service account token
+                        If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                        then this audiences will be appended to the list
+                      items:
+                        type: string
+                      type: array
+                    name:
+                      description: The name of the ServiceAccount resource being referred to.
+                      type: string
+                    namespace:
+                      description: |-
+                        Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                        to the namespace of the referent.
+                      type: string
+                  required:
+                    - name
+                  type: object
+                tenantId:
+                  description: TenantID configures the AzureKvTenant to send requests to. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
+                  type: string
+                vaultUrl:
+                  description: Vault Url from which the secrets to be fetched from.
+                  type: string
+              required:
+                - vaultUrl
+              type: object
+          type: object
+      served: true
+      storage: true
+      subresources:
+        status: {}
+  conversion:
+    strategy: Webhook
+    webhook:
+      conversionReviewVersions:
+        - v1
+      clientConfig:
+        service:
+          name: kubernetes
+          namespace: default
+          path: /convert
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: fakes.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+      - fake
+    kind: Fake
+    listKind: FakeList
+    plural: fakes
+    shortNames:
+      - fake
+    singular: fake
+  scope: Cluster
+  versions:
+    - name: v1alpha1
+      schema:
+        openAPIV3Schema:
+          properties:
+            apiVersion:
+              description: |-
+                APIVersion defines the versioned schema of this representation of an object.
+                Servers should convert recognized schemas to the latest internal value, and
+                may reject unrecognized values.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              type: string
+            kind:
+              description: |-
+                Kind is a string value representing the REST resource this object represents.
+                Servers may infer this from the endpoint the client submits requests to.
+                Cannot be updated.
+                In CamelCase.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              type: string
+            metadata:
+              type: object
+            spec:
+              description: FakeSpec contains the static data.
+              properties:
+                controller:
+                  description: |-
+                    Used to select the correct ESO controller (think: ingress.ingressClassName)
+                    The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                  type: string
+                data:
+                  items:
+                    properties:
+                      key:
+                        type: string
+                      value:
+                        type: string
+                      valueMap:
+                        additionalProperties:
+                          type: string
+                        type: object
+                      version:
+                        type: string
+                    required:
+                      - key
+                    type: object
+                  type: array
+                refreshInterval:
+                  description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+                  type: integer
+                retrySettings:
+                  description: Used to configure http retries if failed
+                  properties:
+                    maxRetries:
+                      format: int32
+                      type: integer
+                    retryInterval:
+                      type: string
+                  type: object
+              required:
+                - data
+              type: object
+          type: object
+      served: true
+      storage: true
+      subresources:
+        status: {}
+  conversion:
+    strategy: Webhook
+    webhook:
+      conversionReviewVersions:
+        - v1
+      clientConfig:
+        service:
+          name: kubernetes
+          namespace: default
+          path: /convert
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.2
+  name: gitlabs.providers.external-secrets.io
+spec:
+  group: providers.external-secrets.io
+  names:
+    categories:
+      - gitlab
+    kind: Gitlab
+    listKind: GitlabList
+    plural: gitlabs
+    shortNames:
+      - gitlab
+    singular: gitlab
+  scope: Cluster
+  versions:
+    - name: v1alpha1
+      schema:
+        openAPIV3Schema:
+          properties:
+            apiVersion:
+              description: |-
+                APIVersion defines the versioned schema of this representation of an object.
+                Servers should convert recognized schemas to the latest internal value, and
+                may reject unrecognized values.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              type: string
+            kind:
+              description: |-
+                Kind is a string value representing the REST resource this object represents.
+                Servers may infer this from the endpoint the client submits requests to.
+                Cannot be updated.
+                In CamelCase.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              type: string
+            metadata:
+              type: object
+            spec:
+              description: Configures a store to sync secrets with a GitLab instance.
+              properties:
+                auth:
+                  description: Auth configures how secret-manager authenticates with a GitLab instance.
+                  properties:
+                    SecretRef:
+                      properties:
+                        accessToken:
+                          description: AccessToken is used for authentication.
+                          properties:
+                            key:
+                              description: |-
+                                The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be
+                                defaulted, in others it may be required.
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults
+                                to the namespace of the referent.
+                              type: string
+                          type: object
+                      type: object
+                  required:
+                    - SecretRef
+                  type: object
+                controller:
+                  description: |-
+                    Used to select the correct ESO controller (think: ingress.ingressClassName)
+                    The ESO controller is instantiated with a specific controller name and filters ES based on this property
+                  type: string
+                environment:
+                  description: Environment environment_scope of gitlab CI/CD variables (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment on how to create environments)
+                  type: string
+                groupIDs:
+                  description: GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables.
+                  items:
+                    type: string
+                  type: array
+                inheritFromGroups:
+                  description: InheritFromGroups specifies whether parent groups should be discovered and checked for secrets.
+                  type: boolean
+                projectID:
+                  description: ProjectID specifies a project where secrets are located.
+                  type: string
+                refreshInterval:
+                  description: Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
+                  type: integer
+                retrySettings:
+                  description: Used to configure http retries if failed
+                  properties:
+                    maxRetries:
+                      format: int32
+                      type: integer
+                    retryInterval:
+                      type: string
+                  type: object
+                url:
+                  description: URL configures the GitLab instance URL. Defaults to https://gitlab.com/.
+                  type: string
+              required:
+                - auth
+              type: object
+          type: object
+      served: true
+      storage: true
+      subresources:
+        status: {}
+  conversion:
+    strategy: Webhook
+    webhook:
+      conversionReviewVersions:
+        - v1
+      clientConfig:
+        service:
+          name: kubernetes
+          namespace: default
+          path: /convert

+ 61 - 148
docs/api/spec.md

@@ -560,8 +560,8 @@ are used to validate the TLS connection.</p>
 <td>
 <code>caProvider</code></br>
 <em>
-<a href="#external-secrets.io/v1beta1.CAProvider">
-CAProvider
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#CAProvider">
+External Secrets meta/v1.CAProvider
 </a>
 </em>
 </td>
@@ -1337,8 +1337,8 @@ can be performed.</p>
 <td>
 <code>caProvider</code></br>
 <em>
-<a href="#external-secrets.io/v1beta1.CAProvider">
-CAProvider
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#CAProvider">
+External Secrets meta/v1.CAProvider
 </a>
 </em>
 </td>
@@ -1417,100 +1417,6 @@ External Secrets meta/v1.SecretKeySelector
 </tr>
 </tbody>
 </table>
-<h3 id="external-secrets.io/v1beta1.CAProvider">CAProvider
-</h3>
-<p>
-(<em>Appears on:</em>
-<a href="#external-secrets.io/v1beta1.AkeylessProvider">AkeylessProvider</a>, 
-<a href="#external-secrets.io/v1beta1.BitwardenSecretsManagerProvider">BitwardenSecretsManagerProvider</a>, 
-<a href="#external-secrets.io/v1beta1.ConjurProvider">ConjurProvider</a>, 
-<a href="#external-secrets.io/v1beta1.KubernetesServer">KubernetesServer</a>, 
-<a href="#external-secrets.io/v1beta1.VaultProvider">VaultProvider</a>)
-</p>
-<p>
-<p>Used to provide custom certificate authority (CA) certificates
-for a secret store. The CAProvider points to a Secret or ConfigMap resource
-that contains a PEM-encoded certificate.</p>
-</p>
-<table>
-<thead>
-<tr>
-<th>Field</th>
-<th>Description</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td>
-<code>type</code></br>
-<em>
-<a href="#external-secrets.io/v1beta1.CAProviderType">
-CAProviderType
-</a>
-</em>
-</td>
-<td>
-<p>The type of provider to use such as &ldquo;Secret&rdquo;, or &ldquo;ConfigMap&rdquo;.</p>
-</td>
-</tr>
-<tr>
-<td>
-<code>name</code></br>
-<em>
-string
-</em>
-</td>
-<td>
-<p>The name of the object located at the provider type.</p>
-</td>
-</tr>
-<tr>
-<td>
-<code>key</code></br>
-<em>
-string
-</em>
-</td>
-<td>
-<p>The key where the CA certificate can be found in the Secret or ConfigMap.</p>
-</td>
-</tr>
-<tr>
-<td>
-<code>namespace</code></br>
-<em>
-string
-</em>
-</td>
-<td>
-<em>(Optional)</em>
-<p>The namespace the Provider type is in.
-Can only be defined when used in a ClusterSecretStore.</p>
-</td>
-</tr>
-</tbody>
-</table>
-<h3 id="external-secrets.io/v1beta1.CAProviderType">CAProviderType
-(<code>string</code> alias)</p></h3>
-<p>
-(<em>Appears on:</em>
-<a href="#external-secrets.io/v1beta1.CAProvider">CAProvider</a>)
-</p>
-<p>
-</p>
-<table>
-<thead>
-<tr>
-<th>Value</th>
-<th>Description</th>
-</tr>
-</thead>
-<tbody><tr><td><p>&#34;ConfigMap&#34;</p></td>
-<td></td>
-</tr><tr><td><p>&#34;Secret&#34;</p></td>
-<td></td>
-</tr></tbody>
-</table>
 <h3 id="external-secrets.io/v1beta1.CertAuth">CertAuth
 </h3>
 <p>
@@ -2178,15 +2084,30 @@ SecretStoreProvider
 </em>
 </td>
 <td>
+<em>(Optional)</em>
 <p>Used to configure the provider. Only one provider may be set</p>
 </td>
 </tr>
 <tr>
 <td>
+<code>providerRef</code></br>
+<em>
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#ProviderRef">
+External Secrets meta/v1.ProviderRef
+</a>
+</em>
+</td>
+<td>
+<p>Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+providerRef takes precedence over provider.</p>
+</td>
+</tr>
+<tr>
+<td>
 <code>retrySettings</code></br>
 <em>
-<a href="#external-secrets.io/v1beta1.SecretStoreRetrySettings">
-SecretStoreRetrySettings
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#RetrySettings">
+External Secrets meta/v1.RetrySettings
 </a>
 </em>
 </td>
@@ -2515,8 +2436,8 @@ string
 <td>
 <code>caProvider</code></br>
 <em>
-<a href="#external-secrets.io/v1beta1.CAProvider">
-CAProvider
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#CAProvider">
+External Secrets meta/v1.CAProvider
 </a>
 </em>
 </td>
@@ -5211,8 +5132,8 @@ string
 <td>
 <code>caProvider</code></br>
 <em>
-<a href="#external-secrets.io/v1beta1.CAProvider">
-CAProvider
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#CAProvider">
+External Secrets meta/v1.CAProvider
 </a>
 </em>
 </td>
@@ -6351,15 +6272,30 @@ SecretStoreProvider
 </em>
 </td>
 <td>
+<em>(Optional)</em>
 <p>Used to configure the provider. Only one provider may be set</p>
 </td>
 </tr>
 <tr>
 <td>
+<code>providerRef</code></br>
+<em>
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#ProviderRef">
+External Secrets meta/v1.ProviderRef
+</a>
+</em>
+</td>
+<td>
+<p>Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+providerRef takes precedence over provider.</p>
+</td>
+</tr>
+<tr>
+<td>
 <code>retrySettings</code></br>
 <em>
-<a href="#external-secrets.io/v1beta1.SecretStoreRetrySettings">
-SecretStoreRetrySettings
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#RetrySettings">
+External Secrets meta/v1.RetrySettings
 </a>
 </em>
 </td>
@@ -6966,44 +6902,6 @@ Defaults to <code>SecretStore</code></p>
 </tr>
 </tbody>
 </table>
-<h3 id="external-secrets.io/v1beta1.SecretStoreRetrySettings">SecretStoreRetrySettings
-</h3>
-<p>
-(<em>Appears on:</em>
-<a href="#external-secrets.io/v1beta1.SecretStoreSpec">SecretStoreSpec</a>)
-</p>
-<p>
-</p>
-<table>
-<thead>
-<tr>
-<th>Field</th>
-<th>Description</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td>
-<code>maxRetries</code></br>
-<em>
-int32
-</em>
-</td>
-<td>
-</td>
-</tr>
-<tr>
-<td>
-<code>retryInterval</code></br>
-<em>
-string
-</em>
-</td>
-<td>
-</td>
-</tr>
-</tbody>
-</table>
 <h3 id="external-secrets.io/v1beta1.SecretStoreSpec">SecretStoreSpec
 </h3>
 <p>
@@ -7045,15 +6943,30 @@ SecretStoreProvider
 </em>
 </td>
 <td>
+<em>(Optional)</em>
 <p>Used to configure the provider. Only one provider may be set</p>
 </td>
 </tr>
 <tr>
 <td>
+<code>providerRef</code></br>
+<em>
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#ProviderRef">
+External Secrets meta/v1.ProviderRef
+</a>
+</em>
+</td>
+<td>
+<p>Used to reference a CRD-based provider. Only one of ProviderRef or provider may be set.
+providerRef takes precedence over provider.</p>
+</td>
+</tr>
+<tr>
+<td>
 <code>retrySettings</code></br>
 <em>
-<a href="#external-secrets.io/v1beta1.SecretStoreRetrySettings">
-SecretStoreRetrySettings
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#RetrySettings">
+External Secrets meta/v1.RetrySettings
 </a>
 </em>
 </td>
@@ -8864,8 +8777,8 @@ which is available under the <code>auth.cert</code> section.</p>
 <td>
 <code>caProvider</code></br>
 <em>
-<a href="#external-secrets.io/v1beta1.CAProvider">
-CAProvider
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#CAProvider">
+External Secrets meta/v1.CAProvider
 </a>
 </em>
 </td>

+ 2 - 2
e2e/suites/provider/cases/alibaba/provider.go

@@ -105,8 +105,8 @@ func (s *alibabaProvider) BeforeEach() {
 		Spec: esv1beta1.SecretStoreSpec{
 			Provider: &esv1beta1.SecretStoreProvider{
 				Alibaba: &esv1beta1.AlibabaProvider{
-					Auth: &esv1beta1.AlibabaAuth{
-						SecretRef: esv1beta1.AlibabaAuthSecretRef{
+					Auth: esv1beta1.AlibabaAuth{
+						SecretRef: &esv1beta1.AlibabaAuthSecretRef{
 							AccessKeyID: esmeta.SecretKeySelector{
 								Name: "kms-secret",
 								Key:  "keyid",

+ 2 - 1
e2e/suites/provider/cases/azure/provider.go

@@ -35,6 +35,7 @@ import (
 	"github.com/external-secrets/external-secrets-e2e/framework"
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	esprov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	esoazkv "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
 )
 
@@ -120,7 +121,7 @@ func newFromWorkloadIdentity(f *framework.Framework) *azureProvider {
 			}
 
 			// exchange the federated token for an access token
-			aadEndpoint := esoazkv.AadEndpointForType(esv1beta1.AzureEnvironmentPublicCloud)
+			aadEndpoint := esoazkv.AadEndpointForType(esprov.AzureEnvironmentPublicCloud)
 			kvResource := strings.TrimSuffix(azure.PublicCloud.KeyVaultEndpoint, "/")
 			tokenProvider, err := esoazkv.NewTokenProvider(context.Background(), string(token), clientID, tenantID, aadEndpoint, kvResource)
 			if err != nil {

+ 2 - 2
e2e/suites/provider/cases/kubernetes/provider.go

@@ -131,8 +131,8 @@ func makeDefaultStore(suffix, namespace string) (*rbac.Role, *rbac.RoleBinding,
 			Provider: &esv1beta1.SecretStoreProvider{
 				Kubernetes: &esv1beta1.KubernetesProvider{
 					Server: esv1beta1.KubernetesServer{
-						CAProvider: &esv1beta1.CAProvider{
-							Type: esv1beta1.CAProviderTypeConfigMap,
+						CAProvider: &esmeta.CAProvider{
+							Type: esmeta.CAProviderTypeConfigMap,
 							Name: "kube-root-ca.crt",
 							Key:  "ca.crt",
 						},

+ 3 - 3
hack/helm.generate.sh

@@ -11,10 +11,10 @@ else
 fi
 
 cd "${SCRIPT_DIR}"/../
-
+mkdir -p ${HELM_DIR}/templates/crds
 # Split the generated bundle yaml file to inject control flags
-yq e -Ns "\"${HELM_DIR}/templates/crds/\" + .spec.names.singular" ${BUNDLE_DIR}/bundle.yaml
-
+yq e -Ns "\"${HELM_DIR}/templates/crds/\" + (.metadata.name | sub (\"\.\",\"_\"))" ${BUNDLE_DIR}/bundle.yaml
+ls "${HELM_DIR}/templates/crds"
 # Add helm if statement for controlling the install of CRDs
 for i in "${HELM_DIR}"/templates/crds/*.yml; do
   export CRDS_FLAG_NAME="create$(yq e '.spec.names.kind' $i)"

+ 2 - 2
pkg/common/webhook/models.go

@@ -17,7 +17,7 @@ package webhook
 import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 type Spec struct {
@@ -57,7 +57,7 @@ type Spec struct {
 
 	// The provider for the CA bundle to use to validate webhook server certificate.
 	// +optional
-	CAProvider *esv1beta1.CAProvider `json:"caProvider,omitempty"`
+	CAProvider *esmeta.CAProvider `json:"caProvider,omitempty"`
 }
 
 type Result struct {

+ 60 - 4
pkg/controllers/secretstore/client_manager.go

@@ -18,6 +18,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"reflect"
 	"regexp"
 	"strings"
 
@@ -30,6 +31,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmetav1 "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 )
 
 const (
@@ -75,8 +78,41 @@ func NewManager(ctrlClient client.Client, controllerClass string, enableFloodgat
 	}
 }
 
+func (m *Manager) getProviderSpec(ctx context.Context, ref *esmetav1.ProviderRef, _ string) (client.Object, error) {
+	p, err := prov.GetManifestByKind(ref)
+	if err != nil {
+		return nil, fmt.Errorf("could not get a provider for kind %v", ref.Kind)
+	}
+	spec := reflect.New(reflect.ValueOf(p).Elem().Type()).Interface().(client.Object) // New Copy
+	key := types.NamespacedName{Name: ref.Name}
+	err = m.client.Get(ctx, key, spec)
+	if err != nil {
+		return nil, fmt.Errorf("could not get Provider %v: %w", ref.Name, err)
+	}
+	return spec, nil
+}
+
 func (m *Manager) GetFromStore(ctx context.Context, store esv1beta1.GenericStore, namespace string) (esv1beta1.SecretsClient, error) {
-	storeProvider, err := esv1beta1.GetProvider(store)
+	var storeProvider esv1beta1.Provider
+	var err error
+	var spec client.Object
+	prov := store.GetSpec().ProviderRef
+	if prov != nil {
+		storeProvider, _ = esv1beta1.GetProviderByRef(*prov)
+		spec, err = m.getProviderSpec(ctx, store.GetSpec().ProviderRef, namespace)
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		storeProvider, err = esv1beta1.GetProvider(store)
+		if err != nil {
+			return nil, err
+		}
+		spec, err = storeProvider.Convert(store)
+		if err != nil {
+			return nil, err
+		}
+	}
 	if err != nil {
 		return nil, err
 	}
@@ -87,9 +123,29 @@ func (m *Manager) GetFromStore(ctx context.Context, store esv1beta1.GenericStore
 	m.log.V(1).Info("creating new client",
 		"provider", fmt.Sprintf("%T", storeProvider),
 		"store", fmt.Sprintf("%s/%s", store.GetNamespace(), store.GetName()))
-	// secret client is created only if we are going to refresh
-	// this skip an unnecessary check/request in the case we are not going to do anything
-	secretClient, err = storeProvider.NewClient(ctx, store, m.client, namespace)
+	// Compatibility - not break the code while methods are not implemented
+	if spec == nil {
+		secretClient, err = storeProvider.NewClient(ctx, store, m.client, namespace)
+		if err != nil {
+			return nil, err
+		}
+		idx := storeKey(storeProvider)
+		m.clientMap[idx] = &clientVal{
+			client: secretClient,
+			store:  store,
+		}
+		return secretClient, nil
+	}
+	caller := esmetav1.ReferentCallSecretStore
+	storeKind := store.GetObjectKind().GroupVersionKind().Kind
+	if storeKind == esv1beta1.ClusterSecretStoreKind {
+		caller = esmetav1.ReferentCallClusterSecretStore
+	}
+	referredSpec, err := storeProvider.ApplyReferent(spec, caller, namespace)
+	if err != nil {
+		return nil, fmt.Errorf("could not apply referrent logic to spec on %v: %w", store.GetName(), err)
+	}
+	secretClient, err = storeProvider.NewClientFromObj(ctx, referredSpec, m.client, namespace)
 	if err != nil {
 		return nil, err
 	}

+ 13 - 0
pkg/controllers/secretstore/client_manager_test.go

@@ -16,6 +16,7 @@ package secretstore
 
 import (
 	"context"
+	"fmt"
 	"testing"
 
 	"github.com/go-logr/logr"
@@ -31,6 +32,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 func TestManagerGet(t *testing.T) {
@@ -408,6 +410,17 @@ type WrapProvider struct {
 		string) (esv1beta1.SecretsClient, error)
 }
 
+func (f *WrapProvider) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
+func (f *WrapProvider) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+func (f *WrapProvider) Convert(_ esv1beta1.GenericStore) (client.Object, error) {
+	return nil, nil
+}
+
 // NewClient constructs a SecretsManager Provider.
 func (f *WrapProvider) NewClient(
 	ctx context.Context,

+ 7 - 1
pkg/controllers/secretstore/common.go

@@ -69,7 +69,13 @@ func reconcile(ctx context.Context, req ctrl.Request, ss esapi.GenericStore, cl
 		log.Error(err, "unable to validate store")
 		return ctrl.Result{}, err
 	}
-	storeProvider, err := esapi.GetProvider(ss)
+
+	var storeProvider esapi.Provider
+	if ss.GetSpec().ProviderRef != nil {
+		storeProvider, err = esapi.GetProviderByRef(*ss.GetSpec().ProviderRef)
+	} else {
+		storeProvider, err = esapi.GetProvider(ss)
+	}
 	if err != nil {
 		return ctrl.Result{}, err
 	}

+ 9 - 9
pkg/generator/acr/acr.go

@@ -38,9 +38,9 @@ import (
 	ctrlcfg "sigs.k8s.io/controller-runtime/pkg/client/config"
 	"sigs.k8s.io/yaml"
 
-	"github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	genv1alpha1 "github.com/external-secrets/external-secrets/apis/generators/v1alpha1"
 	smmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
 )
 
@@ -227,7 +227,7 @@ func fetchACRRefreshToken(aadAccessToken, tenantID, registryURL string) (string,
 	return refreshToken, nil
 }
 
-func accessTokenForWorkloadIdentity(ctx context.Context, crClient client.Client, kubeClient kcorev1.CoreV1Interface, envType v1beta1.AzureEnvironmentType, serviceAccountRef *smmeta.ServiceAccountSelector, namespace string) (string, error) {
+func accessTokenForWorkloadIdentity(ctx context.Context, crClient client.Client, kubeClient kcorev1.CoreV1Interface, envType prov.AzureEnvironmentType, serviceAccountRef *smmeta.ServiceAccountSelector, namespace string) (string, error) {
 	aadEndpoint := keyvault.AadEndpointForType(envType)
 	scope := keyvault.ServiceManagementEndpointForType(envType)
 	// if no serviceAccountRef was provided
@@ -281,7 +281,7 @@ func accessTokenForWorkloadIdentity(ctx context.Context, crClient client.Client,
 	return tp.OAuthToken(), nil
 }
 
-func accessTokenForManagedIdentity(ctx context.Context, envType v1beta1.AzureEnvironmentType, identityID string) (string, error) {
+func accessTokenForManagedIdentity(ctx context.Context, envType prov.AzureEnvironmentType, identityID string) (string, error) {
 	// handle workload identity
 	creds, err := azidentity.NewManagedIdentityCredential(
 		&azidentity.ManagedIdentityCredentialOptions{
@@ -301,7 +301,7 @@ func accessTokenForManagedIdentity(ctx context.Context, envType v1beta1.AzureEnv
 	return accessToken.Token, nil
 }
 
-func (g *Generator) accessTokenForServicePrincipal(ctx context.Context, crClient client.Client, namespace string, envType v1beta1.AzureEnvironmentType, tenantID string, idRef, secretRef smmeta.SecretKeySelector) (string, error) {
+func (g *Generator) accessTokenForServicePrincipal(ctx context.Context, crClient client.Client, namespace string, envType prov.AzureEnvironmentType, tenantID string, idRef, secretRef smmeta.SecretKeySelector) (string, error) {
 	cid, err := secretKeyRef(ctx, crClient, namespace, idRef)
 	if err != nil {
 		return "", err
@@ -350,16 +350,16 @@ func secretKeyRef(ctx context.Context, crClient client.Client, namespace string,
 	return value, nil
 }
 
-func audienceForType(t v1beta1.AzureEnvironmentType) string {
+func audienceForType(t prov.AzureEnvironmentType) string {
 	suffix := ".default"
 	switch t {
-	case v1beta1.AzureEnvironmentChinaCloud:
+	case prov.AzureEnvironmentChinaCloud:
 		return azure.ChinaCloud.TokenAudience + suffix
-	case v1beta1.AzureEnvironmentGermanCloud:
+	case prov.AzureEnvironmentGermanCloud:
 		return azure.GermanCloud.TokenAudience + suffix
-	case v1beta1.AzureEnvironmentUSGovernmentCloud:
+	case prov.AzureEnvironmentUSGovernmentCloud:
 		return azure.USGovernmentCloud.TokenAudience + suffix
-	case v1beta1.AzureEnvironmentPublicCloud, "":
+	case prov.AzureEnvironmentPublicCloud, "":
 		return azure.PublicCloud.TokenAudience + suffix
 	}
 	return azure.PublicCloud.TokenAudience + suffix

+ 67 - 13
pkg/provider/akeyless/akeyless.go

@@ -37,6 +37,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/find"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
@@ -51,12 +53,14 @@ var _ esv1beta1.SecretsClient = &Akeyless{}
 var _ esv1beta1.Provider = &Provider{}
 
 // Provider satisfies the provider interface.
-type Provider struct{}
+type Provider struct {
+	storeKind string
+}
 
 // akeylessBase satisfies the provider.SecretsClient interface.
 type akeylessBase struct {
 	kube      client.Client
-	store     esv1beta1.GenericStore
+	store     prov.AkeylessSpec
 	storeKind string
 	corev1    typedcorev1.CoreV1Interface
 	namespace string
@@ -86,6 +90,28 @@ func init() {
 	esv1beta1.Register(&Provider{}, &esv1beta1.SecretStoreProvider{
 		Akeyless: &esv1beta1.AkeylessProvider{},
 	})
+	esv1beta1.RegisterByName(&Provider{}, prov.AkeylessKind)
+	ref := esmeta.ProviderRef{
+		APIVersion: prov.Group + "/" + prov.Version,
+		Kind:       prov.AkeylessKind,
+	}
+	prov.RefRegister(&prov.Akeyless{}, ref)
+}
+
+func (p *Provider) Convert(in esv1beta1.GenericStore) (client.Object, error) {
+	out := &prov.Akeyless{}
+	tmp := map[string]interface{}{
+		"spec": in.GetSpec().Provider.Akeyless,
+	}
+	d, err := json.Marshal(tmp)
+	if err != nil {
+		return nil, err
+	}
+	err = json.Unmarshal(d, out)
+	if err != nil {
+		return nil, fmt.Errorf("could not convert %v in a valid fake provider: %w", in.GetName(), err)
+	}
+	return out, nil
 }
 
 // Capabilities return the provider supported capabilities (ReadOnly, WriteOnly, ReadWrite).
@@ -93,8 +119,35 @@ func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
 
-// NewClient constructs a new secrets client based on the provided store.
-func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
+func (p *Provider) ApplyReferent(spec client.Object, caller esmeta.ReferentCallOrigin, namespace string) (client.Object, error) {
+	converted, ok := spec.(*prov.Akeyless)
+	if !ok {
+		return nil, fmt.Errorf("could not convert source object %v into 'fake' provider type: object from type %T", spec.GetName(), spec)
+	}
+	ns := &namespace
+	out := converted.DeepCopy()
+	switch caller {
+	case esmeta.ReferentCallProvider:
+	case esmeta.ReferentCallSecretStore:
+		out.Spec.Auth.SecretRef.AccessID.Namespace = ns
+		out.Spec.Auth.SecretRef.AccessType.Namespace = ns
+		out.Spec.Auth.SecretRef.AccessTypeParam.Namespace = ns
+		out.Spec.Auth.KubernetesAuth.ServiceAccountRef.Namespace = ns
+	case esmeta.ReferentCallClusterSecretStore:
+		// compatibility with utils.SecretKeyRef
+		p.storeKind = esv1beta1.ClusterSecretStoreKind
+	default:
+	}
+
+	return spec, nil
+}
+
+func (p *Provider) NewClientFromObj(ctx context.Context, in client.Object, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
+	obj, ok := in.(*prov.Akeyless)
+	if !ok {
+		return nil, errors.New("could not load akeyless provider")
+	}
+	store := obj.Spec
 	// controller-runtime/client does not support TokenRequest or other subresource APIs
 	// so we need to construct our own client and use it to fetch tokens
 	// (for Kubernetes service account token auth)
@@ -110,6 +163,11 @@ func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore,
 	return newClient(ctx, store, kube, clientset.CoreV1(), namespace)
 }
 
+// NewClient constructs a new secrets client based on the provided store.
+func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
+	return nil, errors.New("no longer supported")
+}
+
 func (p *Provider) ValidateStore(store esv1beta1.GenericStore) (admission.Warnings, error) {
 	storeSpec := store.GetSpec()
 	akeylessSpec := storeSpec.Provider.Akeyless
@@ -178,21 +236,17 @@ func (p *Provider) ValidateStore(store esv1beta1.GenericStore) (admission.Warnin
 	return nil, nil
 }
 
-func newClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, corev1 typedcorev1.CoreV1Interface, namespace string) (esv1beta1.SecretsClient, error) {
+func newClient(ctx context.Context, store prov.AkeylessSpec, kube client.Client, corev1 typedcorev1.CoreV1Interface, namespace string) (esv1beta1.SecretsClient, error) {
 	akl := &akeylessBase{
 		kube:      kube,
 		store:     store,
 		namespace: namespace,
 		corev1:    corev1,
-		storeKind: store.GetObjectKind().GroupVersionKind().Kind,
 	}
 
-	spec, err := GetAKeylessProvider(store)
-	if err != nil {
-		return nil, err
-	}
+	spec := store
 	akeylessGwAPIURL := defaultAPIUrl
-	if spec != nil && spec.AkeylessGWApiURL != nil && *spec.AkeylessGWApiURL != "" {
+	if spec.AkeylessGWApiURL != nil && *spec.AkeylessGWApiURL != "" {
 		akeylessGwAPIURL = getV2Url(*spec.AkeylessGWApiURL)
 	}
 
@@ -200,7 +254,7 @@ func newClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Cl
 		return nil, errors.New("missing Auth in store config")
 	}
 
-	client, err := akl.getAkeylessHTTPClient(ctx, spec)
+	client, err := akl.getAkeylessHTTPClient(ctx, &spec)
 	if err != nil {
 		return nil, err
 	}
@@ -404,7 +458,7 @@ func (a *Akeyless) GetSecretMap(ctx context.Context, ref esv1beta1.ExternalSecre
 	return secretData, nil
 }
 
-func (a *akeylessBase) getAkeylessHTTPClient(ctx context.Context, provider *esv1beta1.AkeylessProvider) (*http.Client, error) {
+func (a *akeylessBase) getAkeylessHTTPClient(ctx context.Context, provider *prov.AkeylessSpec) (*http.Client, error) {
 	client := &http.Client{Timeout: 30 * time.Second}
 	if len(provider.CABundle) == 0 && provider.CAProvider == nil {
 		return client, nil

+ 3 - 2
pkg/provider/akeyless/akeyless_api.go

@@ -35,6 +35,7 @@ import (
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/constants"
 	"github.com/external-secrets/external-secrets/pkg/metrics"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
@@ -44,7 +45,7 @@ var apiErr akeyless.GenericOpenAPIError
 
 const DefServiceAccountFile = "/var/run/secrets/kubernetes.io/serviceaccount/token"
 
-func (a *akeylessBase) GetToken(accessID, accType, accTypeParam string, k8sAuth *esv1beta1.AkeylessKubernetesAuth) (string, error) {
+func (a *akeylessBase) GetToken(accessID, accType, accTypeParam string, k8sAuth *prov.AkeylessKubernetesAuth) (string, error) {
 	ctx := context.Background()
 	authBody := akeyless.NewAuthWithDefaults()
 	authBody.AccessId = akeyless.PtrString(accessID)
@@ -325,7 +326,7 @@ func (a *akeylessBase) ListSecrets(ctx context.Context, path, tag, token string)
 	return listNames, nil
 }
 
-func (a *akeylessBase) getK8SServiceAccountJWT(ctx context.Context, kubernetesAuth *esv1beta1.AkeylessKubernetesAuth) (string, error) {
+func (a *akeylessBase) getK8SServiceAccountJWT(ctx context.Context, kubernetesAuth *prov.AkeylessKubernetesAuth) (string, error) {
 	if kubernetesAuth != nil {
 		if kubernetesAuth.ServiceAccountRef != nil {
 			// Kubernetes <v1.24 fetch token via ServiceAccount.Secrets[]

+ 1 - 5
pkg/provider/akeyless/auth.go

@@ -31,11 +31,7 @@ const (
 )
 
 func (a *akeylessBase) TokenFromSecretRef(ctx context.Context) (string, error) {
-	prov, err := GetAKeylessProvider(a.store)
-	if err != nil {
-		return "", err
-	}
-
+	prov := a.store
 	if prov.Auth.KubernetesAuth != nil {
 		auth := prov.Auth.KubernetesAuth
 		return a.GetToken(auth.AccessID, "k8s", auth.K8sConfName, auth)

+ 60 - 24
pkg/provider/alibaba/kms.go

@@ -31,6 +31,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -48,8 +50,9 @@ var _ esv1beta1.SecretsClient = &KeyManagementService{}
 var _ esv1beta1.Provider = &KeyManagementService{}
 
 type KeyManagementService struct {
-	Client SMInterface
-	Config *openapi.Config
+	Client    SMInterface
+	Config    *openapi.Config
+	storeKind string
 }
 
 type SMInterface interface {
@@ -133,12 +136,29 @@ func (kms *KeyManagementService) Capabilities() esv1beta1.SecretStoreCapabilitie
 	return esv1beta1.SecretStoreReadOnly
 }
 
-// NewClient constructs a new secrets client based on the provided store.
-func (kms *KeyManagementService) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
-	storeSpec := store.GetSpec()
-	alibabaSpec := storeSpec.Provider.Alibaba
+func (kms *KeyManagementService) Convert(in esv1beta1.GenericStore) (kclient.Object, error) {
+	out := &prov.Alibaba{}
+	tmp := map[string]interface{}{
+		"spec": in.GetSpec().Provider.Alibaba,
+	}
+	d, err := json.Marshal(tmp)
+	if err != nil {
+		return nil, err
+	}
+	err = json.Unmarshal(d, out)
+	if err != nil {
+		return nil, fmt.Errorf("could not convert %v in a valid fake provider: %w", in.GetName(), err)
+	}
+	return out, nil
+}
+func (kms *KeyManagementService) NewClientFromObj(ctx context.Context, obj kclient.Object, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
+	p, ok := obj.(*prov.Alibaba)
+	if !ok {
+		return nil, errors.New("could not validate provider")
+	}
+	alibabaSpec := &p.Spec
 
-	credentials, err := newAuth(ctx, kube, store, namespace)
+	credentials, err := newAuth(ctx, kube, alibabaSpec, namespace, kms.storeKind)
 	if err != nil {
 		return nil, fmt.Errorf("failed to create Alibaba credentials: %w", err)
 	}
@@ -148,7 +168,7 @@ func (kms *KeyManagementService) NewClient(ctx context.Context, store esv1beta1.
 		Credential: credentials,
 	}
 
-	options := newOptions(store)
+	options := newOptions(alibabaSpec)
 	client, err := newClient(config, options)
 	if err != nil {
 		return nil, fmt.Errorf(errAlibabaClient, err)
@@ -159,9 +179,28 @@ func (kms *KeyManagementService) NewClient(ctx context.Context, store esv1beta1.
 	return kms, nil
 }
 
-func newOptions(store esv1beta1.GenericStore) *util.RuntimeOptions {
-	storeSpec := store.GetSpec()
+func (kms *KeyManagementService) ApplyReferent(spec kclient.Object, caller esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	converted, ok := spec.(*prov.Akeyless)
+	out := converted.DeepCopy()
+	if !ok {
+		return nil, fmt.Errorf("could not convert source object %v into 'fake' provider type: object from type %T", spec.GetName(), spec)
+	}
+	switch caller {
+	case esmeta.ReferentCallClusterSecretStore:
+		kms.storeKind = esv1beta1.ClusterSecretStoreKind
+	case esmeta.ReferentCallSecretStore:
+	case esmeta.ReferentCallProvider:
+	default:
+	}
+	return out, nil
+}
 
+// NewClient constructs a new secrets client based on the provided store.
+func (kms *KeyManagementService) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
+	return nil, errors.New("no longer supported")
+}
+
+func newOptions(storeSpec *prov.AlibabaSpec) *util.RuntimeOptions {
 	options := &util.RuntimeOptions{}
 	// Setup retry options, if present in storeSpec
 	if storeSpec.RetrySettings != nil {
@@ -180,20 +219,17 @@ func newOptions(store esv1beta1.GenericStore) *util.RuntimeOptions {
 	return options
 }
 
-func newAuth(ctx context.Context, kube kclient.Client, store esv1beta1.GenericStore, namespace string) (credential.Credential, error) {
-	storeSpec := store.GetSpec()
-	alibabaSpec := storeSpec.Provider.Alibaba
-
+func newAuth(ctx context.Context, kube kclient.Client, alibabaSpec *prov.AlibabaSpec, namespace, storeKind string) (credential.Credential, error) {
 	switch {
 	case alibabaSpec.Auth.RRSAAuth != nil:
-		credentials, err := newRRSAAuth(store)
+		credentials, err := newRRSAAuth(alibabaSpec)
 		if err != nil {
 			return nil, fmt.Errorf("failed to create Alibaba OIDC credentials: %w", err)
 		}
 
 		return credentials, nil
 	case alibabaSpec.Auth.SecretRef != nil:
-		credentials, err := newAccessKeyAuth(ctx, kube, store, namespace)
+		credentials, err := newAccessKeyAuth(ctx, kube, alibabaSpec, namespace, storeKind)
 		if err != nil {
 			return nil, fmt.Errorf("failed to create Alibaba AccessKey credentials: %w", err)
 		}
@@ -204,10 +240,7 @@ func newAuth(ctx context.Context, kube kclient.Client, store esv1beta1.GenericSt
 	}
 }
 
-func newRRSAAuth(store esv1beta1.GenericStore) (credential.Credential, error) {
-	storeSpec := store.GetSpec()
-	alibabaSpec := storeSpec.Provider.Alibaba
-
+func newRRSAAuth(alibabaSpec *prov.AlibabaSpec) (credential.Credential, error) {
 	credentialConfig := &credential.Config{
 		OIDCProviderArn:   &alibabaSpec.Auth.RRSAAuth.OIDCProviderARN,
 		OIDCTokenFilePath: &alibabaSpec.Auth.RRSAAuth.OIDCTokenFilePath,
@@ -221,10 +254,7 @@ func newRRSAAuth(store esv1beta1.GenericStore) (credential.Credential, error) {
 	return credential.NewCredential(credentialConfig)
 }
 
-func newAccessKeyAuth(ctx context.Context, kube kclient.Client, store esv1beta1.GenericStore, namespace string) (credential.Credential, error) {
-	storeSpec := store.GetSpec()
-	alibabaSpec := storeSpec.Provider.Alibaba
-	storeKind := store.GetObjectKind().GroupVersionKind().Kind
+func newAccessKeyAuth(ctx context.Context, kube kclient.Client, alibabaSpec *prov.AlibabaSpec, namespace, storeKind string) (credential.Credential, error) {
 	accessKeyID, err := resolvers.SecretKeyRef(ctx, kube, storeKind, namespace, &alibabaSpec.Auth.SecretRef.AccessKeyID)
 	if err != nil {
 		return nil, fmt.Errorf(errFetchAccessKeyID, err)
@@ -356,4 +386,10 @@ func init() {
 	esv1beta1.Register(&KeyManagementService{}, &esv1beta1.SecretStoreProvider{
 		Alibaba: &esv1beta1.AlibabaProvider{},
 	})
+	esv1beta1.RegisterByName(&KeyManagementService{}, prov.AlibabaKind)
+	ref := esmeta.ProviderRef{
+		APIVersion: prov.Group + "/" + prov.Version,
+		Kind:       prov.AlibabaKind,
+	}
+	prov.RefRegister(&prov.Alibaba{}, ref)
 }

+ 19 - 0
pkg/provider/aws/provider.go

@@ -29,6 +29,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	awsauth "github.com/external-secrets/external-secrets/pkg/provider/aws/auth"
 	"github.com/external-secrets/external-secrets/pkg/provider/aws/parameterstore"
 	"github.com/external-secrets/external-secrets/pkg/provider/aws/secretsmanager"
@@ -50,6 +51,24 @@ const (
 	errInvalidSecretsManager  = "invalid SecretsManager settings: %s"
 )
 
+// Convert converts a generic store into a provider object
+// Not Implemented.
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (client.Object, error) {
+	return nil, nil
+}
+
+// ApplyReferent applies referent logic to provider object
+// Not Implemented.
+func (p *Provider) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+
+// NewClientFromObj is the new way to get Provider from object
+// Not Implemented.
+func (p *Provider) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // Capabilities return the provider supported capabilities (ReadOnly, WriteOnly, ReadWrite).
 func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadWrite

+ 1 - 1
pkg/provider/aws/provider_test.go

@@ -503,7 +503,7 @@ func TestValidRetryInput(t *testing.T) {
 					},
 				},
 			},
-			RetrySettings: &esv1beta1.SecretStoreRetrySettings{
+			RetrySettings: &esmeta.RetrySettings{
 				RetryInterval: &invalid,
 			},
 		},

+ 87 - 41
pkg/provider/azure/keyvault/keyvault.go

@@ -49,6 +49,8 @@ import (
 	gopkcs12 "software.sslmate.com/src/go-pkcs12"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	smmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/constants"
 	"github.com/external-secrets/external-secrets/pkg/metrics"
 	"github.com/external-secrets/external-secrets/pkg/utils"
@@ -113,8 +115,8 @@ type SecretClient interface {
 type Azure struct {
 	crClient   client.Client
 	kubeClient kcorev1.CoreV1Interface
-	store      esv1beta1.GenericStore
-	provider   *esv1beta1.AzureKVProvider
+	storeKind  string
+	provider   *prov.AzureKVSpec
 	baseClient SecretClient
 	namespace  string
 }
@@ -123,6 +125,28 @@ func init() {
 	esv1beta1.Register(&Azure{}, &esv1beta1.SecretStoreProvider{
 		AzureKV: &esv1beta1.AzureKVProvider{},
 	})
+	esv1beta1.RegisterByName(&Azure{}, prov.AzureKind)
+	ref := smmeta.ProviderRef{
+		APIVersion: prov.Group + "/" + prov.Version,
+		Kind:       prov.AzureKind,
+	}
+	prov.RefRegister(&prov.AzureKv{}, ref)
+}
+
+func (a *Azure) Convert(in esv1beta1.GenericStore) (client.Object, error) {
+	out := &prov.AzureKv{}
+	tmp := map[string]interface{}{
+		"spec": in.GetSpec().Provider.AzureKV,
+	}
+	d, err := json.Marshal(tmp)
+	if err != nil {
+		return nil, err
+	}
+	err = json.Unmarshal(d, out)
+	if err != nil {
+		return nil, fmt.Errorf("could not convert %v in a valid fake provider: %w", in.GetName(), err)
+	}
+	return out, nil
 }
 
 // Capabilities return the provider supported capabilities (ReadOnly, WriteOnly, ReadWrite).
@@ -130,12 +154,36 @@ func (a *Azure) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadWrite
 }
 
+func (a *Azure) ApplyReferent(spec client.Object, caller smmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	converted, ok := spec.(*prov.AzureKv)
+	out := converted.DeepCopy()
+	if !ok {
+		return nil, fmt.Errorf("could not convert source object %v into 'fake' provider type: object from type %T", spec.GetName(), spec)
+	}
+	switch caller {
+	case smmeta.ReferentCallClusterSecretStore:
+		a.storeKind = esv1beta1.ClusterSecretStoreKind
+	case smmeta.ReferentCallSecretStore:
+	case smmeta.ReferentCallProvider:
+	default:
+	}
+	return out, nil
+}
+
+func (a *Azure) NewClientFromObj(ctx context.Context, obj client.Object, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
+	store, ok := obj.(*prov.AzureKv)
+	if !ok {
+		return nil, errors.New("could not load azure provider")
+	}
+	return newClient(ctx, store, kube, namespace, a.storeKind)
+}
+
 // NewClient constructs a new secrets client based on the provided store.
 func (a *Azure) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
-	return newClient(ctx, store, kube, namespace)
+	return nil, errors.New("no longer supported")
 }
 
-func newClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
+func newClient(ctx context.Context, store *prov.AzureKv, kube client.Client, namespace, storeKind string) (esv1beta1.SecretsClient, error) {
 	provider, err := getProvider(store)
 	if err != nil {
 		return nil, err
@@ -151,14 +199,14 @@ func newClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Cl
 	az := &Azure{
 		crClient:   kube,
 		kubeClient: kubeClient.CoreV1(),
-		store:      store,
+		storeKind:  storeKind,
 		namespace:  namespace,
 		provider:   provider,
 	}
 
 	// allow SecretStore controller validation to pass
 	// when using referent namespace.
-	if store.GetKind() == esv1beta1.ClusterSecretStoreKind &&
+	if storeKind == esv1beta1.ClusterSecretStoreKind &&
 		namespace == "" &&
 		isReferentSpec(provider) {
 		return az, nil
@@ -166,11 +214,11 @@ func newClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Cl
 
 	var authorizer autorest.Authorizer
 	switch *provider.AuthType {
-	case esv1beta1.AzureManagedIdentity:
+	case prov.AzureManagedIdentity:
 		authorizer, err = az.authorizerForManagedIdentity()
-	case esv1beta1.AzureServicePrincipal:
+	case prov.AzureServicePrincipal:
 		authorizer, err = az.authorizerForServicePrincipal(ctx)
-	case esv1beta1.AzureWorkloadIdentity:
+	case prov.AzureWorkloadIdentity:
 		authorizer, err = az.authorizerForWorkloadIdentity(ctx, NewTokenProvider)
 	default:
 		err = errors.New(errMissingAuthType)
@@ -182,14 +230,12 @@ func newClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Cl
 
 	return az, err
 }
-
-func getProvider(store esv1beta1.GenericStore) (*esv1beta1.AzureKVProvider, error) {
-	spc := store.GetSpec()
-	if spc == nil || spc.Provider.AzureKV == nil {
-		return nil, errors.New(errUnexpectedStoreSpec)
+func getProvider(store *prov.AzureKv) (*prov.AzureKVSpec, error) {
+	if store == nil {
+		return nil, errors.New("missing store")
 	}
-
-	return spc.Provider.AzureKV, nil
+	spc := store.Spec
+	return &spc, nil
 }
 
 func (a *Azure) ValidateStore(store esv1beta1.GenericStore) (admission.Warnings, error) {
@@ -835,7 +881,7 @@ func (a *Azure) authorizerForWorkloadIdentity(ctx context.Context, tokenProvider
 		return autorest.NewBearerAuthorizer(tp), nil
 	}
 	ns := a.namespace
-	if a.store.GetKind() == esv1beta1.ClusterSecretStoreKind && a.provider.ServiceAccountRef.Namespace != nil {
+	if a.storeKind == esv1beta1.ClusterSecretStoreKind && a.provider.ServiceAccountRef.Namespace != nil {
 		ns = *a.provider.ServiceAccountRef.Namespace
 	}
 	var sa corev1.ServiceAccount
@@ -856,7 +902,7 @@ func (a *Azure) authorizerForWorkloadIdentity(ctx context.Context, tokenProvider
 		clientID, err = resolvers.SecretKeyRef(
 			ctx,
 			a.crClient,
-			a.store.GetKind(),
+			a.storeKind,
 			a.namespace, a.provider.AuthSecretRef.ClientID)
 		if err != nil {
 			return nil, err
@@ -887,7 +933,7 @@ func (a *Azure) authorizerForWorkloadIdentity(ctx context.Context, tokenProvider
 			tenantID, err = resolvers.SecretKeyRef(
 				ctx,
 				a.crClient,
-				a.store.GetKind(),
+				a.storeKind,
 				a.namespace, a.provider.AuthSecretRef.TenantID)
 			if err != nil {
 				return nil, err
@@ -1010,7 +1056,7 @@ func (a *Azure) getAuthorizerFromCredentials(ctx context.Context) (autorest.Auth
 	clientID, err := resolvers.SecretKeyRef(
 		ctx,
 		a.crClient,
-		a.store.GetKind(),
+		a.storeKind,
 		a.namespace, a.provider.AuthSecretRef.ClientID,
 	)
 
@@ -1022,7 +1068,7 @@ func (a *Azure) getAuthorizerFromCredentials(ctx context.Context) (autorest.Auth
 		clientSecret, err := resolvers.SecretKeyRef(
 			ctx,
 			a.crClient,
-			a.store.GetKind(),
+			a.storeKind,
 			a.namespace, a.provider.AuthSecretRef.ClientSecret,
 		)
 
@@ -1040,7 +1086,7 @@ func (a *Azure) getAuthorizerFromCredentials(ctx context.Context) (autorest.Auth
 		clientCertificate, err := resolvers.SecretKeyRef(
 			ctx,
 			a.crClient,
-			a.store.GetKind(),
+			a.storeKind,
 			a.namespace, a.provider.AuthSecretRef.ClientCertificate,
 		)
 
@@ -1057,14 +1103,14 @@ func (a *Azure) getAuthorizerFromCredentials(ctx context.Context) (autorest.Auth
 	}
 }
 
-func getAuthorizerForClientSecret(clientID, clientSecret, tenantID string, environmentType esv1beta1.AzureEnvironmentType) (autorest.Authorizer, error) {
+func getAuthorizerForClientSecret(clientID, clientSecret, tenantID string, environmentType prov.AzureEnvironmentType) (autorest.Authorizer, error) {
 	clientCredentialsConfig := kvauth.NewClientCredentialsConfig(clientID, clientSecret, tenantID)
 	clientCredentialsConfig.Resource = kvResourceForProviderConfig(environmentType)
 	clientCredentialsConfig.AADEndpoint = AadEndpointForType(environmentType)
 	return clientCredentialsConfig.Authorizer()
 }
 
-func getAuthorizerForClientCertificate(clientID string, certificateBytes []byte, tenantID string, environmentType esv1beta1.AzureEnvironmentType) (autorest.Authorizer, error) {
+func getAuthorizerForClientCertificate(clientID string, certificateBytes []byte, tenantID string, environmentType prov.AzureEnvironmentType) (autorest.Authorizer, error) {
 	clientCertificateConfig := NewClientInMemoryCertificateConfig(clientID, certificateBytes, tenantID)
 	clientCertificateConfig.Resource = kvResourceForProviderConfig(environmentType)
 	clientCertificateConfig.AADEndpoint = AadEndpointForType(environmentType)
@@ -1076,13 +1122,13 @@ func (a *Azure) Close(_ context.Context) error {
 }
 
 func (a *Azure) Validate() (esv1beta1.ValidationResult, error) {
-	if a.store.GetKind() == esv1beta1.ClusterSecretStoreKind && isReferentSpec(a.provider) {
+	if a.storeKind == esv1beta1.ClusterSecretStoreKind && isReferentSpec(a.provider) {
 		return esv1beta1.ValidationResultUnknown, nil
 	}
 	return esv1beta1.ValidationResultReady, nil
 }
 
-func isReferentSpec(prov *esv1beta1.AzureKVProvider) bool {
+func isReferentSpec(prov *prov.AzureKVSpec) bool {
 	if prov.AuthSecretRef != nil &&
 		((prov.AuthSecretRef.ClientID != nil &&
 			prov.AuthSecretRef.ClientID.Namespace == nil) ||
@@ -1097,46 +1143,46 @@ func isReferentSpec(prov *esv1beta1.AzureKVProvider) bool {
 	return false
 }
 
-func AadEndpointForType(t esv1beta1.AzureEnvironmentType) string {
+func AadEndpointForType(t prov.AzureEnvironmentType) string {
 	switch t {
-	case esv1beta1.AzureEnvironmentPublicCloud:
+	case prov.AzureEnvironmentPublicCloud:
 		return azure.PublicCloud.ActiveDirectoryEndpoint
-	case esv1beta1.AzureEnvironmentChinaCloud:
+	case prov.AzureEnvironmentChinaCloud:
 		return azure.ChinaCloud.ActiveDirectoryEndpoint
-	case esv1beta1.AzureEnvironmentUSGovernmentCloud:
+	case prov.AzureEnvironmentUSGovernmentCloud:
 		return azure.USGovernmentCloud.ActiveDirectoryEndpoint
-	case esv1beta1.AzureEnvironmentGermanCloud:
+	case prov.AzureEnvironmentGermanCloud:
 		return azure.GermanCloud.ActiveDirectoryEndpoint
 	default:
 		return azure.PublicCloud.ActiveDirectoryEndpoint
 	}
 }
 
-func ServiceManagementEndpointForType(t esv1beta1.AzureEnvironmentType) string {
+func ServiceManagementEndpointForType(t prov.AzureEnvironmentType) string {
 	switch t {
-	case esv1beta1.AzureEnvironmentPublicCloud:
+	case prov.AzureEnvironmentPublicCloud:
 		return azure.PublicCloud.ServiceManagementEndpoint
-	case esv1beta1.AzureEnvironmentChinaCloud:
+	case prov.AzureEnvironmentChinaCloud:
 		return azure.ChinaCloud.ServiceManagementEndpoint
-	case esv1beta1.AzureEnvironmentUSGovernmentCloud:
+	case prov.AzureEnvironmentUSGovernmentCloud:
 		return azure.USGovernmentCloud.ServiceManagementEndpoint
-	case esv1beta1.AzureEnvironmentGermanCloud:
+	case prov.AzureEnvironmentGermanCloud:
 		return azure.GermanCloud.ServiceManagementEndpoint
 	default:
 		return azure.PublicCloud.ServiceManagementEndpoint
 	}
 }
 
-func kvResourceForProviderConfig(t esv1beta1.AzureEnvironmentType) string {
+func kvResourceForProviderConfig(t prov.AzureEnvironmentType) string {
 	var res string
 	switch t {
-	case esv1beta1.AzureEnvironmentPublicCloud:
+	case prov.AzureEnvironmentPublicCloud:
 		res = azure.PublicCloud.KeyVaultEndpoint
-	case esv1beta1.AzureEnvironmentChinaCloud:
+	case prov.AzureEnvironmentChinaCloud:
 		res = azure.ChinaCloud.KeyVaultEndpoint
-	case esv1beta1.AzureEnvironmentUSGovernmentCloud:
+	case prov.AzureEnvironmentUSGovernmentCloud:
 		res = azure.USGovernmentCloud.KeyVaultEndpoint
-	case esv1beta1.AzureEnvironmentGermanCloud:
+	case prov.AzureEnvironmentGermanCloud:
 		res = azure.GermanCloud.KeyVaultEndpoint
 	default:
 		res = azure.PublicCloud.KeyVaultEndpoint

+ 67 - 69
pkg/provider/azure/keyvault/keyvault_auth_test.go

@@ -32,6 +32,7 @@ import (
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	v1 "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	utilfake "github.com/external-secrets/external-secrets/pkg/provider/util/fake"
 )
 
@@ -66,23 +67,17 @@ MwIgfejiTtcR0ZsPza8Mn0EuIyuPV8VMsItQUWtSy6R/ig8CIQC86cBmNUXp+HGz
 func TestNewClientManagedIdentityNoNeedForCredentials(t *testing.T) {
 	namespace := "internal"
 	identityID := "1234"
-	authType := esv1beta1.AzureManagedIdentity
-	store := esv1beta1.SecretStore{
-		ObjectMeta: metav1.ObjectMeta{
-			Namespace: namespace,
-		},
-		Spec: esv1beta1.SecretStoreSpec{Provider: &esv1beta1.SecretStoreProvider{AzureKV: &esv1beta1.AzureKVProvider{
-			AuthType:   &authType,
-			IdentityID: &identityID,
-			VaultURL:   &vaultURL,
-		}}},
+	authType := prov.AzureManagedIdentity
+	store := prov.AzureKVSpec{
+		AuthType:   &authType,
+		IdentityID: &identityID,
+		VaultURL:   &vaultURL,
 	}
 	k8sClient := clientfake.NewClientBuilder().Build()
 	az := &Azure{
 		crClient:  k8sClient,
 		namespace: namespace,
-		provider:  store.Spec.Provider.AzureKV,
-		store:     &store,
+		provider:  &store,
 	}
 	authorizer, err := az.authorizerForManagedIdentity()
 	if err != nil {
@@ -115,9 +110,9 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 	tassert.Nil(t, err)
 	tokenFile := tf.Name()
 
-	authType := esv1beta1.AzureWorkloadIdentity
+	authType := prov.AzureWorkloadIdentity
 
-	defaultProvider := &esv1beta1.AzureKVProvider{
+	defaultProvider := &prov.AzureKVSpec{
 		VaultURL: &vaultURL,
 		AuthType: &authType,
 		ServiceAccountRef: &v1.ServiceAccountSelector{
@@ -127,7 +122,7 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 
 	type testCase struct {
 		name       string
-		provider   *esv1beta1.AzureKVProvider
+		provider   *prov.AzureKVSpec
 		k8sObjects []client.Object
 		prep       func(*testing.T)
 		expErr     string
@@ -141,12 +136,12 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 		},
 		{
 			name:     "missing webhook env vars",
-			provider: &esv1beta1.AzureKVProvider{},
+			provider: &prov.AzureKVSpec{},
 			expErr:   "missing environment variables. AZURE_CLIENT_ID, AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE must be set",
 		},
 		{
 			name:     "missing workload identity token file",
-			provider: &esv1beta1.AzureKVProvider{},
+			provider: &prov.AzureKVSpec{},
 			prep: func(t *testing.T) {
 				t.Setenv("AZURE_CLIENT_ID", clientID)
 				t.Setenv("AZURE_TENANT_ID", tenantID)
@@ -156,7 +151,7 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 		},
 		{
 			name:     "correct workload identity",
-			provider: &esv1beta1.AzureKVProvider{},
+			provider: &prov.AzureKVSpec{},
 			prep: func(t *testing.T) {
 				t.Setenv("AZURE_CLIENT_ID", clientID)
 				t.Setenv("AZURE_TENANT_ID", tenantID)
@@ -179,14 +174,14 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 		},
 		{
 			name: "duplicated clientId",
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				VaultURL: &vaultURL,
 				AuthType: &authType,
 				TenantID: pointer.To(tenantID),
 				ServiceAccountRef: &v1.ServiceAccountSelector{
 					Name: saName,
 				},
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientID: &v1.SecretKeySelector{Name: secretName, Namespace: pointer.To(namespace), Key: clientID},
 					TenantID: &v1.SecretKeySelector{Name: secretName, Namespace: pointer.To(namespace), Key: tenantID},
 				},
@@ -217,7 +212,7 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 		},
 		{
 			name: "duplicated tenantId",
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				VaultURL: &vaultURL,
 				AuthType: &authType,
 				TenantID: pointer.To(tenantID),
@@ -257,13 +252,13 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 		},
 		{
 			name: "successful case #2: ClientID, TenantID from AuthSecretRef",
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				VaultURL: &vaultURL,
 				AuthType: &authType,
 				ServiceAccountRef: &v1.ServiceAccountSelector{
 					Name: saName,
 				},
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientID: &v1.SecretKeySelector{Name: secretName, Namespace: pointer.To(namespace), Key: clientID},
 					TenantID: &v1.SecretKeySelector{Name: secretName, Namespace: pointer.To(namespace), Key: tenantID},
 				},
@@ -290,14 +285,14 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 		},
 		{
 			name: "successful case #3: ClientID from AuthSecretRef, TenantID from provider",
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				VaultURL: &vaultURL,
 				AuthType: &authType,
 				TenantID: pointer.To(tenantID),
 				ServiceAccountRef: &v1.ServiceAccountSelector{
 					Name: saName,
 				},
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientID: &v1.SecretKeySelector{Name: secretName, Namespace: pointer.To(namespace), Key: clientID},
 				},
 			},
@@ -322,20 +317,16 @@ func TestGetAuthorizorForWorkloadIdentity(t *testing.T) {
 		},
 	} {
 		t.Run(row.name, func(t *testing.T) {
-			store := esv1beta1.SecretStore{
-				Spec: esv1beta1.SecretStoreSpec{Provider: &esv1beta1.SecretStoreProvider{
-					AzureKV: row.provider,
-				}},
-			}
+			store := row.provider
 			k8sClient := clientfake.NewClientBuilder().
 				WithObjects(row.k8sObjects...).
 				Build()
 			az := &Azure{
-				store:      &store,
+				storeKind:  esv1beta1.SecretStoreKind,
 				namespace:  namespace,
 				crClient:   k8sClient,
 				kubeClient: utilfake.NewCreateTokenMock().WithToken(saToken),
-				provider:   store.Spec.Provider.AzureKV,
+				provider:   store,
 			}
 			tokenProvider := func(ctx context.Context, token, clientID, tenantID, aadEndpoint, kvResource string) (adal.OAuthTokenProvider, error) {
 				tassert.Equal(t, token, saToken)
@@ -366,72 +357,78 @@ func TestAuth(t *testing.T) {
 			Provider: &esv1beta1.SecretStoreProvider{},
 		},
 	}
-	authType := esv1beta1.AzureServicePrincipal
+	authType := prov.AzureServicePrincipal
 
 	type testCase struct {
-		name     string
-		provider *esv1beta1.AzureKVProvider
-		store    esv1beta1.GenericStore
-		objects  []client.Object
-		expErr   string
+		name      string
+		storeKind string
+		provider  *prov.AzureKVSpec
+		store     esv1beta1.GenericStore
+		objects   []client.Object
+		expErr    string
 	}
 	for _, row := range []testCase{
 		{
-			name:   "bad config",
-			expErr: "missing secretRef in provider config",
-			store:  &defaultStore,
-			provider: &esv1beta1.AzureKVProvider{
+			name:      "bad config",
+			expErr:    "missing secretRef in provider config",
+			store:     &defaultStore,
+			storeKind: esv1beta1.SecretStoreKind,
+			provider: &prov.AzureKVSpec{
 				AuthType: &authType,
 				VaultURL: &vaultURL,
 				TenantID: pointer.To("mytenant"),
 			},
 		},
 		{
-			name:   "bad config",
-			expErr: "missing accessKeyID/secretAccessKey in store config",
-			store:  &defaultStore,
-			provider: &esv1beta1.AzureKVProvider{
+			name:      "bad config",
+			expErr:    "missing accessKeyID/secretAccessKey in store config",
+			store:     &defaultStore,
+			storeKind: esv1beta1.SecretStoreKind,
+			provider: &prov.AzureKVSpec{
 				AuthType:      &authType,
 				VaultURL:      &vaultURL,
 				TenantID:      pointer.To("mytenant"),
-				AuthSecretRef: &esv1beta1.AzureKVAuth{},
+				AuthSecretRef: &prov.AzureKVAuth{},
 			},
 		},
 		{
-			name:   "bad config: missing secret",
-			expErr: "cannot get Kubernetes secret \"password\": secrets \"password\" not found",
-			store:  &defaultStore,
-			provider: &esv1beta1.AzureKVProvider{
+			name:      "bad config: missing secret",
+			expErr:    "cannot get Kubernetes secret \"password\": secrets \"password\" not found",
+			store:     &defaultStore,
+			storeKind: esv1beta1.SecretStoreKind,
+			provider: &prov.AzureKVSpec{
 				AuthType: &authType,
 				VaultURL: &vaultURL,
 				TenantID: pointer.To("mytenant"),
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientSecret: &v1.SecretKeySelector{Name: "password"},
 					ClientID:     &v1.SecretKeySelector{Name: "password"},
 				},
 			},
 		},
 		{
-			name:   "cluster secret store",
-			expErr: "cannot get Kubernetes secret \"password\": secrets \"password\" not found",
+			name:      "cluster secret store",
+			expErr:    "cannot get Kubernetes secret \"password\": secrets \"password\" not found",
+			storeKind: esv1beta1.SecretStoreKind,
 			store: &esv1beta1.ClusterSecretStore{
 				TypeMeta: metav1.TypeMeta{
 					Kind: esv1beta1.ClusterSecretStoreKind,
 				},
 				Spec: esv1beta1.SecretStoreSpec{Provider: &esv1beta1.SecretStoreProvider{}},
 			},
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				AuthType: &authType,
 				VaultURL: &vaultURL,
 				TenantID: pointer.To("mytenant"),
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientSecret: &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo")},
 					ClientID:     &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo")},
 				},
 			},
 		},
 		{
-			name: "correct cluster secret store with ClientSecret",
+			name:      "correct cluster secret store with ClientSecret",
+			storeKind: esv1beta1.ClusterSecretStoreKind,
 			objects: []client.Object{&corev1.Secret{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "password",
@@ -448,11 +445,11 @@ func TestAuth(t *testing.T) {
 				},
 				Spec: esv1beta1.SecretStoreSpec{Provider: &esv1beta1.SecretStoreProvider{}},
 			},
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				AuthType: &authType,
 				VaultURL: &vaultURL,
 				TenantID: pointer.To("mytenant"),
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientSecret: &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "secret"},
 					ClientID:     &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "id"},
 				},
@@ -472,17 +469,18 @@ func TestAuth(t *testing.T) {
 					"secret":      []byte("bar"),
 				},
 			}},
+			storeKind: esv1beta1.ClusterSecretStoreKind,
 			store: &esv1beta1.ClusterSecretStore{
 				TypeMeta: metav1.TypeMeta{
 					Kind: esv1beta1.ClusterSecretStoreKind,
 				},
 				Spec: esv1beta1.SecretStoreSpec{Provider: &esv1beta1.SecretStoreProvider{}},
 			},
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				AuthType: &authType,
 				VaultURL: &vaultURL,
 				TenantID: pointer.To("mytenant"),
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientID:          &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "id"},
 					ClientCertificate: &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "certificate"},
 					ClientSecret:      &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "secret"},
@@ -502,17 +500,18 @@ func TestAuth(t *testing.T) {
 					"certificate": []byte("bar"),
 				},
 			}},
+			storeKind: esv1beta1.ClusterSecretStoreKind,
 			store: &esv1beta1.ClusterSecretStore{
 				TypeMeta: metav1.TypeMeta{
 					Kind: esv1beta1.ClusterSecretStoreKind,
 				},
 				Spec: esv1beta1.SecretStoreSpec{Provider: &esv1beta1.SecretStoreProvider{}},
 			},
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				AuthType: &authType,
 				VaultURL: &vaultURL,
 				TenantID: pointer.To("mytenant"),
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientID:          &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "id"},
 					ClientCertificate: &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "certificate"},
 				},
@@ -530,17 +529,18 @@ func TestAuth(t *testing.T) {
 					"certificate": []byte(mockCertificate),
 				},
 			}},
+			storeKind: esv1beta1.ClusterSecretStoreKind,
 			store: &esv1beta1.ClusterSecretStore{
 				TypeMeta: metav1.TypeMeta{
 					Kind: esv1beta1.ClusterSecretStoreKind,
 				},
 				Spec: esv1beta1.SecretStoreSpec{Provider: &esv1beta1.SecretStoreProvider{}},
 			},
-			provider: &esv1beta1.AzureKVProvider{
+			provider: &prov.AzureKVSpec{
 				AuthType: &authType,
 				VaultURL: &vaultURL,
 				TenantID: pointer.To("mytenant"),
-				AuthSecretRef: &esv1beta1.AzureKVAuth{
+				AuthSecretRef: &prov.AzureKVAuth{
 					ClientID:          &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "id"},
 					ClientCertificate: &v1.SecretKeySelector{Name: "password", Namespace: pointer.To("foo"), Key: "certificate"},
 				},
@@ -549,13 +549,11 @@ func TestAuth(t *testing.T) {
 	} {
 		t.Run(row.name, func(t *testing.T) {
 			k8sClient := clientfake.NewClientBuilder().WithObjects(row.objects...).Build()
-			spec := row.store.GetSpec()
-			spec.Provider.AzureKV = row.provider
 			az := &Azure{
 				crClient:  k8sClient,
 				namespace: "default",
-				provider:  spec.Provider.AzureKV,
-				store:     row.store,
+				provider:  row.provider,
+				storeKind: row.storeKind,
 			}
 			authorizer, err := az.authorizerForServicePrincipal(context.Background())
 			if row.expErr == "" {

+ 7 - 6
pkg/provider/azure/keyvault/keyvault_test.go

@@ -30,6 +30,7 @@ import (
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	v1 "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault/fake"
 	testingfake "github.com/external-secrets/external-secrets/pkg/provider/testing/fake"
 	"github.com/external-secrets/external-secrets/pkg/utils"
@@ -362,7 +363,7 @@ func TestAzureKeyVaultDeleteSecret(t *testing.T) {
 	}
 
 	sm := Azure{
-		provider: &esv1beta1.AzureKVProvider{VaultURL: pointer.To(fakeURL)},
+		provider: &prov.AzureKVSpec{VaultURL: pointer.To(fakeURL)},
 	}
 	for k, v := range successCases {
 		sm.baseClient = v.mockClient
@@ -825,7 +826,7 @@ func TestAzureKeyVaultPushSecret(t *testing.T) {
 	}
 
 	sm := Azure{
-		provider: &esv1beta1.AzureKVProvider{VaultURL: pointer.To(fakeURL)},
+		provider: &prov.AzureKVSpec{VaultURL: pointer.To(fakeURL)},
 	}
 	for k, v := range successCases {
 		sm.baseClient = v.mockClient
@@ -1218,7 +1219,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
 	}
 
 	sm := Azure{
-		provider: &esv1beta1.AzureKVProvider{VaultURL: pointer.To(fakeURL)},
+		provider: &prov.AzureKVSpec{VaultURL: pointer.To(fakeURL)},
 	}
 	for k, v := range successCases {
 		sm.baseClient = v.mockClient
@@ -1377,7 +1378,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
 	}
 
 	sm := Azure{
-		provider: &esv1beta1.AzureKVProvider{VaultURL: pointer.To(fakeURL)},
+		provider: &prov.AzureKVSpec{VaultURL: pointer.To(fakeURL)},
 	}
 	for k, v := range successCases {
 		sm.baseClient = v.mockClient
@@ -1532,7 +1533,7 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
 	}
 
 	sm := Azure{
-		provider: &esv1beta1.AzureKVProvider{VaultURL: pointer.To(fakeURL)},
+		provider: &prov.AzureKVSpec{VaultURL: pointer.To(fakeURL)},
 	}
 	for k, v := range successCases {
 		sm.baseClient = v.mockClient
@@ -1735,7 +1736,7 @@ func TestAzureKeyVaultSecretExists(t *testing.T) {
 	}
 
 	sm := Azure{
-		provider: &esv1beta1.AzureKVProvider{VaultURL: pointer.To(fakeURL)},
+		provider: &prov.AzureKVSpec{VaultURL: pointer.To(fakeURL)},
 	}
 
 	for k, tc := range testCases {

+ 13 - 0
pkg/provider/beyondtrust/provider.go

@@ -34,6 +34,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	esoClient "github.com/external-secrets/external-secrets/pkg/utils"
 )
 
@@ -65,6 +66,18 @@ type Provider struct {
 	separator     string
 }
 
+func (p *Provider) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (client.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // Capabilities implements v1beta1.Provider.
 func (*Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly

+ 13 - 0
pkg/provider/bitwarden/provider.go

@@ -27,6 +27,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -42,6 +43,18 @@ func init() {
 	esv1beta1.Register(&Provider{}, &esv1beta1.SecretStoreProvider{BitwardenSecretsManager: &esv1beta1.BitwardenSecretsManagerProvider{}})
 }
 
+func (p *Provider) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (client.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // NewClient creates a new Bitwarden Secret Manager client.
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	storeSpec := store.GetSpec()

+ 13 - 0
pkg/provider/chef/chef.go

@@ -33,6 +33,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	"github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/metrics"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
@@ -96,6 +97,18 @@ func init() {
 	})
 }
 
+func (providerchef *Providerchef) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (providerchef *Providerchef) Convert(_ v1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (providerchef *Providerchef) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (v1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (providerchef *Providerchef) NewClient(ctx context.Context, store v1beta1.GenericStore, kube kclient.Client, namespace string) (v1beta1.SecretsClient, error) {
 	chefProvider, err := getChefProvider(store)
 	if err != nil {

+ 14 - 0
pkg/provider/conjur/provider.go

@@ -17,6 +17,7 @@ package conjur
 
 import (
 	"context"
+	"fmt"
 
 	"k8s.io/client-go/kubernetes"
 	typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -24,12 +25,25 @@ import (
 	ctrlcfg "sigs.k8s.io/controller-runtime/pkg/client/config"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 type Provider struct {
 	NewConjurProvider func(context context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string, corev1 typedcorev1.CoreV1Interface, clientApi SecretsClientFactory) (esv1beta1.SecretsClient, error)
 }
 
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (client.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // NewClient creates a new Conjur client.
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	// controller-runtime/client does not support TokenRequest or other subresource APIs

+ 4 - 4
pkg/provider/conjur/provider_test.go

@@ -611,14 +611,14 @@ func makeJWTSecretStore(svcURL, serviceAccountName, secretName, jwtServiceID, jw
 func makeStoreWithCA(caSource, caData string) *esv1beta1.SecretStore {
 	store := makeJWTSecretStore(svcURL, "conjur", "", jwtAuthnService, "", "myconjuraccount")
 	if caSource == "secret" {
-		store.Spec.Provider.Conjur.CAProvider = &esv1beta1.CAProvider{
-			Type: esv1beta1.CAProviderTypeSecret,
+		store.Spec.Provider.Conjur.CAProvider = &esmeta.CAProvider{
+			Type: esmeta.CAProviderTypeSecret,
 			Name: "conjur-cert",
 			Key:  "ca",
 		}
 	} else if caSource == "configmap" {
-		store.Spec.Provider.Conjur.CAProvider = &esv1beta1.CAProvider{
-			Type: esv1beta1.CAProviderTypeConfigMap,
+		store.Spec.Provider.Conjur.CAProvider = &esmeta.CAProvider{
+			Type: esmeta.CAProviderTypeConfigMap,
 			Name: "conjur-cert",
 			Key:  "ca",
 		}

+ 13 - 0
pkg/provider/delinea/provider.go

@@ -17,12 +17,14 @@ package delinea
 import (
 	"context"
 	"errors"
+	"fmt"
 
 	"github.com/DelineaXPM/dsv-sdk-go/v2/vault"
 	kubeClient "sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -184,6 +186,17 @@ func (p *Provider) ValidateStore(store esv1beta1.GenericStore) (admission.Warnin
 	return nil, err
 }
 
+func (p *Provider) ApplyReferent(spec kubeClient.Object, _ esmeta.ReferentCallOrigin, _ string) (kubeClient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kubeClient.Object, _ kubeClient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kubeClient.Object, error) {
+	return nil, nil
+}
+
 func init() {
 	esv1beta1.Register(&Provider{}, &esv1beta1.SecretStoreProvider{
 		Delinea: &esv1beta1.DelineaProvider{},

+ 13 - 0
pkg/provider/device42/device42.go

@@ -26,6 +26,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
@@ -47,6 +48,18 @@ type Device42 struct {
 	client Client
 }
 
+func (p *Device42) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (p *Device42) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Device42) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (p *Device42) ValidateStore(esv1beta1.GenericStore) (admission.Warnings, error) {
 	return nil, nil
 }

+ 12 - 0
pkg/provider/doppler/provider.go

@@ -25,6 +25,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	dClient "github.com/external-secrets/external-secrets/pkg/provider/doppler/client"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
@@ -52,6 +53,17 @@ func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
 
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+func (p *Provider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	storeSpec := store.GetSpec()
 

+ 79 - 0
pkg/provider/fake/fake.go

@@ -27,6 +27,8 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/find"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
@@ -62,6 +64,77 @@ func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadWrite
 }
 
+func (p *Provider) ApplyReferent(spec client.Object, caller esmeta.ReferentCallOrigin, ns string) (client.Object, error) {
+	converted, ok := spec.(*prov.Fake)
+	out := converted.DeepCopy()
+	if !ok {
+		return nil, fmt.Errorf("could not convert source object %v into 'fake' provider type: object from type %T", spec.GetName(), spec)
+	}
+	switch caller {
+	case esmeta.ReferentCallSecretStore:
+		// Logic to update 'namespace' fields from provider original spec.
+		fmt.Printf("i would do something here if I was a legit implementation updating all ns references to %v\n", ns)
+	case esmeta.ReferentCallProvider:
+		// Logic to update 'namespace' fields from provider original spec.
+		fmt.Printf("i would do something here if I was a legit implementation updating all ns references to %v\n", ns)
+
+	case esmeta.ReferentCallClusterSecretStore:
+	default:
+		// Logic to not update 'namespace' and use provider configuration as is. (if nil, keep nil as this means referent)
+		fmt.Println("I wouldn't do anything here")
+	}
+	return out, nil
+}
+
+func (p *Provider) Convert(in esv1beta1.GenericStore) (client.Object, error) {
+	out := &prov.Fake{}
+	tmp := map[string]interface{}{
+		"spec": in.GetSpec().Provider.Fake,
+	}
+	d, err := json.Marshal(tmp)
+	if err != nil {
+		return nil, err
+	}
+	err = json.Unmarshal(d, out)
+	if err != nil {
+		return nil, fmt.Errorf("could not convert %v in a valid fake provider: %w", in.GetName(), err)
+	}
+	return out, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, obj client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	if p.database == nil {
+		p.database = make(map[string]Config)
+	}
+	f, ok := obj.(*prov.Fake)
+	if !ok {
+		return nil, fmt.Errorf("could not open Provider Spec for obj '%v': expected 'Fake' type, got '%T'", obj.GetName(), obj)
+	}
+	cfg := p.database[f.GetName()]
+	if cfg == nil {
+		cfg = Config{}
+	}
+	for key, data := range cfg {
+		if data.Origin == FakeSecretStore {
+			delete(cfg, key)
+		}
+	}
+	for _, data := range f.Spec.Data {
+		mapKey := fmt.Sprintf("%v%v", data.Key, data.Version)
+		cfg[mapKey] = &Data{
+			Value:   data.Value,
+			Version: data.Version,
+			Origin:  FakeSecretStore,
+		}
+		if data.ValueMap != nil {
+			cfg[mapKey].ValueMap = data.ValueMap
+		}
+	}
+	p.database[f.GetName()] = cfg
+	return &Provider{
+		config: cfg,
+	}, nil
+}
 func (p *Provider) NewClient(_ context.Context, store esv1beta1.GenericStore, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
 	if p.database == nil {
 		p.database = make(map[string]Config)
@@ -269,4 +342,10 @@ func init() {
 	esv1beta1.Register(&Provider{}, &esv1beta1.SecretStoreProvider{
 		Fake: &esv1beta1.FakeProvider{},
 	})
+	esv1beta1.RegisterByName(&Provider{}, prov.FakeKind)
+	ref := esmeta.ProviderRef{
+		APIVersion: prov.Group + "/" + prov.Version,
+		Kind:       prov.FakeKind,
+	}
+	prov.RefRegister(&prov.Fake{}, ref)
 }

+ 12 - 0
pkg/provider/fortanix/provider.go

@@ -24,6 +24,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -47,6 +48,17 @@ func init() {
 		Fortanix: &esv1beta1.FortanixProvider{},
 	})
 }
+func (p *Provider) ApplyReferent(spec kubeclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kubeclient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kubeclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kubeclient.Object, _ kubeclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
 
 func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly

+ 12 - 0
pkg/provider/gcp/secretmanager/provider.go

@@ -27,6 +27,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
@@ -53,10 +54,21 @@ A Mutex was implemented to make sure only one connection can be in place at a ti
 */
 var useMu = sync.Mutex{}
 
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
 func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadWrite
 }
 
+func (p Provider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+func (p *Provider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // NewClient constructs a GCP Provider.
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	storeSpec := store.GetSpec()

+ 22 - 25
pkg/provider/gitlab/gitlab_test.go

@@ -35,6 +35,7 @@ import (
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esv1meta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	fakegitlab "github.com/external-secrets/external-secrets/pkg/provider/gitlab/fake"
 )
 
@@ -315,51 +316,47 @@ func TestNewClient(t *testing.T) {
 	ctx := context.Background()
 	const namespace = "namespace"
 
-	store := &esv1beta1.SecretStore{
+	store := &prov.Gitlab{
 		ObjectMeta: metav1.ObjectMeta{
 			Namespace: namespace,
 		},
-		Spec: esv1beta1.SecretStoreSpec{
-			Provider: &esv1beta1.SecretStoreProvider{
-				Gitlab: &esv1beta1.GitlabProvider{},
-			},
-		},
+		Spec: prov.GitlabSpec{},
 	}
-	provider, err := esv1beta1.GetProvider(store)
-	tassert.Nil(t, err)
+	provider, ok := esv1beta1.GetProviderByName("gitlab")
+	tassert.True(t, ok)
 
 	k8sClient := clientfake.NewClientBuilder().Build()
-	secretClient, err := provider.NewClient(context.Background(), store, k8sClient, namespace)
+	secretClient, err := provider.NewClientFromObj(context.Background(), store, k8sClient, namespace)
 	tassert.EqualError(t, err, errMissingCredentials)
 	tassert.Nil(t, secretClient)
 
-	store.Spec.Provider.Gitlab.Auth = esv1beta1.GitlabAuth{}
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
+	store.Spec.Auth = prov.GitlabAuth{}
+	secretClient, err = provider.NewClientFromObj(context.Background(), store, k8sClient, namespace)
 	tassert.EqualError(t, err, errMissingCredentials)
 	tassert.Nil(t, secretClient)
 
-	store.Spec.Provider.Gitlab.Auth.SecretRef = esv1beta1.GitlabSecretRef{}
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
+	store.Spec.Auth.SecretRef = prov.GitlabSecretRef{}
+	secretClient, err = provider.NewClientFromObj(context.Background(), store, k8sClient, namespace)
 	tassert.EqualError(t, err, errMissingCredentials)
 	tassert.Nil(t, secretClient)
 
-	store.Spec.Provider.Gitlab.Auth.SecretRef.AccessToken = esv1meta.SecretKeySelector{}
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
+	store.Spec.Auth.SecretRef.AccessToken = esv1meta.SecretKeySelector{}
+	secretClient, err = provider.NewClientFromObj(context.Background(), store, k8sClient, namespace)
 	tassert.EqualError(t, err, errMissingCredentials)
 	tassert.Nil(t, secretClient)
 
 	const authorizedKeySecretName = "authorizedKeySecretName"
 	const authorizedKeySecretKey = "authorizedKeySecretKey"
-	store.Spec.Provider.Gitlab.Auth.SecretRef.AccessToken.Name = authorizedKeySecretName
-	store.Spec.Provider.Gitlab.Auth.SecretRef.AccessToken.Key = authorizedKeySecretKey
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
+	store.Spec.Auth.SecretRef.AccessToken.Name = authorizedKeySecretName
+	store.Spec.Auth.SecretRef.AccessToken.Key = authorizedKeySecretKey
+	secretClient, err = provider.NewClientFromObj(context.Background(), store, k8sClient, namespace)
 	tassert.EqualError(t, err, "cannot get Kubernetes secret \"authorizedKeySecretName\": secrets \"authorizedKeySecretName\" not found")
 	tassert.Nil(t, secretClient)
 
 	err = createK8sSecret(ctx, t, k8sClient, namespace, authorizedKeySecretName, authorizedKeySecretKey, toJSON(t, newFakeAuthorizedKey()))
 	tassert.Nil(t, err)
 
-	secretClient, err = provider.NewClient(context.Background(), store, k8sClient, namespace)
+	secretClient, err = provider.NewClientFromObj(context.Background(), store, k8sClient, namespace)
 	tassert.Nil(t, err)
 	tassert.NotNil(t, secretClient)
 }
@@ -435,7 +432,7 @@ func TestGetSecret(t *testing.T) {
 	}
 
 	sm := gitlabBase{}
-	sm.store = &esv1beta1.GitlabProvider{}
+	sm.store = &prov.GitlabSpec{}
 	for k, v := range successCases {
 		sm.projectVariablesClient = v.mockProjectVarClient
 		sm.groupVariablesClient = v.mockGroupVarClient
@@ -455,7 +452,7 @@ func TestGetSecret(t *testing.T) {
 func TestResolveGroupIds(t *testing.T) {
 	v := makeValidSecretManagerTestCaseCustom()
 	sm := gitlabBase{}
-	sm.store = &esv1beta1.GitlabProvider{}
+	sm.store = &prov.GitlabSpec{}
 	sm.projectsClient = v.mockProjectsClient
 	sm.store.ProjectID = v.projectID
 	sm.store.InheritFromGroups = true
@@ -647,7 +644,7 @@ func TestGetAllSecrets(t *testing.T) {
 	}
 
 	sm := gitlabBase{}
-	sm.store = &esv1beta1.GitlabProvider{}
+	sm.store = &prov.GitlabSpec{}
 	for k, v := range cases {
 		sm.projectVariablesClient = v.mockProjectVarClient
 		sm.groupVariablesClient = v.mockGroupVarClient
@@ -707,7 +704,7 @@ func TestGetAllSecretsWithGroups(t *testing.T) {
 	}
 
 	sm := gitlabBase{}
-	sm.store = &esv1beta1.GitlabProvider{}
+	sm.store = &prov.GitlabSpec{}
 	sm.store.Environment = environment
 	for k, v := range cases {
 		sm.projectVariablesClient = v.mockProjectVarClient
@@ -742,7 +739,7 @@ func TestValidate(t *testing.T) {
 		makeValidSecretManagerTestCaseCustom(setGroupListAPIRespBadCode),
 	}
 	sm := gitlabBase{}
-	sm.store = &esv1beta1.GitlabProvider{}
+	sm.store = &prov.GitlabSpec{}
 	for k, v := range successCases {
 		sm.projectsClient = v.mockProjectsClient
 		sm.projectVariablesClient = v.mockProjectVarClient
@@ -785,7 +782,7 @@ func TestGetSecretMap(t *testing.T) {
 	}
 
 	sm := gitlabBase{}
-	sm.store = &esv1beta1.GitlabProvider{}
+	sm.store = &prov.GitlabSpec{}
 	for k, v := range successCases {
 		sm.projectVariablesClient = v.mockProjectVarClient
 		sm.groupVariablesClient = v.mockGroupVarClient

+ 62 - 14
pkg/provider/gitlab/provider.go

@@ -16,23 +16,29 @@ package gitlab
 
 import (
 	"context"
+	"encoding/json"
 	"errors"
+	"fmt"
 
 	"github.com/xanzy/go-gitlab"
 	kclient "sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	prov "github.com/external-secrets/external-secrets/apis/providers/v1alpha1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
 // Provider satisfies the provider interface.
-type Provider struct{}
+type Provider struct {
+	storeKind string
+}
 
 // gitlabBase satisfies the provider.SecretsClient interface.
 type gitlabBase struct {
 	kube      kclient.Client
-	store     *esv1beta1.GitlabProvider
+	store     *prov.GitlabSpec
 	storeKind string
 	namespace string
 
@@ -46,33 +52,69 @@ func (g *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
 
-// Method on GitLab Provider to set up projectVariablesClient with credentials, populate projectID and environment.
-func (g *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
-	storeSpec := store.GetSpec()
-	if storeSpec == nil || storeSpec.Provider == nil || storeSpec.Provider.Gitlab == nil {
-		return nil, errors.New("no store type or wrong store type")
+func (g *Provider) ApplyReferent(spec kclient.Object, caller esmeta.ReferentCallOrigin, namespace string) (kclient.Object, error) {
+	converted, ok := spec.(*prov.Gitlab)
+	if !ok {
+		return nil, fmt.Errorf("could not convert source object %v into 'fake' provider type: object from type %T", spec.GetName(), spec)
+	}
+	ns := &namespace
+	out := converted.DeepCopy()
+	switch caller {
+	case esmeta.ReferentCallProvider:
+	case esmeta.ReferentCallSecretStore:
+		out.Spec.Auth.SecretRef.AccessToken.Namespace = ns
+	case esmeta.ReferentCallClusterSecretStore:
+		// compatibility with utils.SecretKeyRef
+		g.storeKind = esv1beta1.ClusterSecretStoreKind
+	default:
+	}
+
+	return spec, nil
+}
+
+func (g *Provider) Convert(in esv1beta1.GenericStore) (kclient.Object, error) {
+	out := &prov.Gitlab{}
+	tmp := map[string]interface{}{
+		"spec": in.GetSpec().Provider.Gitlab,
+	}
+	d, err := json.Marshal(tmp)
+	if err != nil {
+		return nil, err
+	}
+	err = json.Unmarshal(d, out)
+	if err != nil {
+		return nil, fmt.Errorf("could not convert %v in a valid fake provider: %w", in.GetName(), err)
 	}
-	storeSpecGitlab := storeSpec.Provider.Gitlab
+	return out, nil
+}
 
+func (g *Provider) NewClientFromObj(ctx context.Context, obj kclient.Object, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
+	spec, ok := obj.(*prov.Gitlab)
+	if !ok {
+		return nil, errors.New("no store type or wrong store type")
+	}
 	gl := &gitlabBase{
 		kube:      kube,
-		store:     storeSpecGitlab,
+		store:     &spec.Spec,
+		storeKind: g.storeKind,
 		namespace: namespace,
-		storeKind: store.GetObjectKind().GroupVersionKind().Kind,
 	}
-
-	client, err := gl.getClient(ctx, storeSpecGitlab)
+	client, err := gl.getClient(ctx, &spec.Spec)
 	if err != nil {
 		return nil, err
 	}
 	gl.projectsClient = client.Projects
 	gl.projectVariablesClient = client.ProjectVariables
 	gl.groupVariablesClient = client.GroupVariables
-
 	return gl, nil
 }
 
-func (g *gitlabBase) getClient(ctx context.Context, provider *esv1beta1.GitlabProvider) (*gitlab.Client, error) {
+// Method on GitLab Provider to set up projectVariablesClient with credentials, populate projectID and environment.
+func (g *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
+	return nil, errors.New("method no longer supported")
+}
+
+func (g *gitlabBase) getClient(ctx context.Context, provider *prov.GitlabSpec) (*gitlab.Client, error) {
 	credentials, err := g.getAuth(ctx)
 	if err != nil {
 		return nil, err
@@ -128,4 +170,10 @@ func init() {
 	esv1beta1.Register(&Provider{}, &esv1beta1.SecretStoreProvider{
 		Gitlab: &esv1beta1.GitlabProvider{},
 	})
+	esv1beta1.RegisterByName(&Provider{}, prov.GitlabKind)
+	ref := esmeta.ProviderRef{
+		APIVersion: prov.Group + "/" + prov.Version,
+		Kind:       prov.GitlabKind,
+	}
+	prov.RefRegister(&prov.Gitlab{}, ref)
 }

+ 13 - 0
pkg/provider/ibm/provider.go

@@ -32,6 +32,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/constants"
 	"github.com/external-secrets/external-secrets/pkg/metrics"
 	"github.com/external-secrets/external-secrets/pkg/utils"
@@ -600,6 +601,18 @@ func (ibm *providerIBM) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
 
+func (ibm *providerIBM) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (ibm *providerIBM) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (ibm *providerIBM) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (ibm *providerIBM) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	storeSpec := store.GetSpec()
 	ibmSpec := storeSpec.Provider.IBM

+ 1 - 1
pkg/provider/ibm/provider_test.go

@@ -1194,7 +1194,7 @@ func TestValidRetryInput(t *testing.T) {
 					ServiceURL: &serviceURL,
 				},
 			},
-			RetrySettings: &esv1beta1.SecretStoreRetrySettings{
+			RetrySettings: &v1.RetrySettings{
 				RetryInterval: &invalid,
 			},
 		},

+ 11 - 0
pkg/provider/infisical/provider.go

@@ -59,6 +59,17 @@ func init() {
 func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
+func (p *Provider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
 
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	storeSpec := store.GetSpec()

+ 13 - 0
pkg/provider/keepersecurity/provider.go

@@ -25,6 +25,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -56,6 +57,18 @@ func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadWrite
 }
 
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // NewClient constructs a GCP Provider.
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	storeSpec := store.GetSpec()

+ 4 - 4
pkg/provider/kubernetes/auth_test.go

@@ -123,8 +123,8 @@ func TestSetAuth(t *testing.T) {
 				store: &esv1beta1.KubernetesProvider{
 					Server: esv1beta1.KubernetesServer{
 						URL: "https://my.test.tld",
-						CAProvider: &esv1beta1.CAProvider{
-							Type: esv1beta1.CAProviderTypeSecret,
+						CAProvider: &v1.CAProvider{
+							Type: v1.CAProviderTypeSecret,
 							Name: "foobar",
 							Key:  "cert",
 						},
@@ -173,8 +173,8 @@ func TestSetAuth(t *testing.T) {
 				store: &esv1beta1.KubernetesProvider{
 					Server: esv1beta1.KubernetesServer{
 						URL: "https://my.test.tld",
-						CAProvider: &esv1beta1.CAProvider{
-							Type: esv1beta1.CAProviderTypeConfigMap,
+						CAProvider: &v1.CAProvider{
+							Type: v1.CAProviderTypeConfigMap,
 							Name: "foobar",
 							Key:  "cert",
 						},

+ 12 - 0
pkg/provider/kubernetes/provider.go

@@ -28,6 +28,7 @@ import (
 	ctrlcfg "sigs.k8s.io/controller-runtime/pkg/client/config"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 // https://github.com/external-secrets/external-secrets/issues/644
@@ -85,6 +86,17 @@ func init() {
 func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadWrite
 }
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
 
 // NewClient constructs a Kubernetes Provider.
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {

+ 13 - 0
pkg/provider/onboardbase/provider.go

@@ -23,6 +23,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	oClient "github.com/external-secrets/external-secrets/pkg/provider/onboardbase/client"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
@@ -46,6 +47,18 @@ func init() {
 	})
 }
 
+func (p *Provider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }

+ 13 - 0
pkg/provider/onepassword/onepassword.go

@@ -29,6 +29,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/find"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
@@ -94,6 +95,18 @@ func (provider *ProviderOnePassword) Capabilities() esv1beta1.SecretStoreCapabil
 	return esv1beta1.SecretStoreReadOnly
 }
 
+func (provider *ProviderOnePassword) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (provider *ProviderOnePassword) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
+func (provider *ProviderOnePassword) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
 // NewClient constructs a 1Password Provider.
 func (provider *ProviderOnePassword) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	config := store.GetSpec().Provider.OnePassword

+ 12 - 0
pkg/provider/oracle/oracle.go

@@ -260,6 +260,18 @@ func (vms *VaultManagementService) Capabilities() esv1beta1.SecretStoreCapabilit
 	return esv1beta1.SecretStoreReadOnly
 }
 
+func (vms *VaultManagementService) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (vms *VaultManagementService) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (vms *VaultManagementService) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // NewClient constructs a new secrets client based on the provided store.
 func (vms *VaultManagementService) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	storeSpec := store.GetSpec()

+ 5 - 5
pkg/provider/oracle/oracle_test.go

@@ -372,7 +372,7 @@ func TestVaultManagementService_NewClient(t *testing.T) {
 							Auth:   auth,
 						},
 					},
-					RetrySettings: &esv1beta1.SecretStoreRetrySettings{
+					RetrySettings: &esmeta.RetrySettings{
 						RetryInterval: ptr.To("1s"),
 						MaxRetries:    ptr.To(int32(5)),
 					},
@@ -390,7 +390,7 @@ func TestVaultManagementService_NewClient(t *testing.T) {
 							Auth:   auth,
 						},
 					},
-					RetrySettings: &esv1beta1.SecretStoreRetrySettings{
+					RetrySettings: &esmeta.RetrySettings{
 						RetryInterval: ptr.To("1s"),
 					},
 				},
@@ -407,7 +407,7 @@ func TestVaultManagementService_NewClient(t *testing.T) {
 							Auth:   auth,
 						},
 					},
-					RetrySettings: &esv1beta1.SecretStoreRetrySettings{
+					RetrySettings: &esmeta.RetrySettings{
 						MaxRetries: ptr.To(int32(5)),
 					},
 				},
@@ -437,7 +437,7 @@ func TestVaultManagementService_NewClient(t *testing.T) {
 							},
 						},
 					},
-					RetrySettings: &esv1beta1.SecretStoreRetrySettings{
+					RetrySettings: &esmeta.RetrySettings{
 						RetryInterval: ptr.To("invalid"),
 					},
 				},
@@ -455,7 +455,7 @@ func TestVaultManagementService_NewClient(t *testing.T) {
 							Auth:   auth,
 						},
 					},
-					RetrySettings: &esv1beta1.SecretStoreRetrySettings{
+					RetrySettings: &esmeta.RetrySettings{
 						RetryInterval: ptr.To("invalid"),
 					},
 				},

+ 13 - 0
pkg/provider/passbolt/passbolt.go

@@ -28,6 +28,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -63,6 +64,18 @@ type Client interface {
 	GetSecret(ctx context.Context, resourceID string) (*api.Secret, error)
 }
 
+func (provider *ProviderPassbolt) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (provider *ProviderPassbolt) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (provider *ProviderPassbolt) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (provider *ProviderPassbolt) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	config := store.GetSpec().Provider.Passbolt
 

+ 13 - 0
pkg/provider/passworddepot/passworddepot.go

@@ -24,6 +24,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
@@ -52,6 +53,18 @@ func (p *PasswordDepot) ValidateStore(esv1beta1.GenericStore) (admission.Warning
 	return nil, nil
 }
 
+func (p *PasswordDepot) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (p *PasswordDepot) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *PasswordDepot) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (p *PasswordDepot) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }

+ 12 - 0
pkg/provider/pulumi/provider.go

@@ -24,6 +24,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -73,6 +74,17 @@ func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore,
 		organization: cfg.Organization,
 	}, nil
 }
+func (p *Provider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
 
 func loadAccessTokenSecret(ctx context.Context, ref *esv1beta1.PulumiProviderSecretRef, kube kclient.Client, storeKind, namespace string) (string, error) {
 	acctoken, err := resolvers.SecretKeyRef(ctx, kube, storeKind, namespace, ref.SecretRef)

+ 12 - 0
pkg/provider/scaleway/provider.go

@@ -27,6 +27,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -43,6 +44,17 @@ func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadWrite
 }
 
+func (p *Provider) ApplyReferent(spec kubeClient.Object, _ esmeta.ReferentCallOrigin, _ string) (kubeClient.Object, error) {
+	return spec, nil
+}
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kubeClient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kubeClient.Object, _ kubeClient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kubeClient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	cfg, err := getConfig(store)
 	if err != nil {

+ 13 - 0
pkg/provider/secretserver/provider.go

@@ -17,12 +17,14 @@ package secretserver
 import (
 	"context"
 	"errors"
+	"fmt"
 
 	"github.com/DelineaXPM/tss-sdk-go/v2/server"
 	kubeClient "sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 	"github.com/external-secrets/external-secrets/pkg/utils/resolvers"
 )
@@ -49,6 +51,17 @@ var _ esv1beta1.Provider = &Provider{}
 func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
+func (p *Provider) ApplyReferent(spec kubeClient.Object, _ esmeta.ReferentCallOrigin, _ string) (kubeClient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kubeClient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kubeClient.Object, _ kubeClient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
 
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kubeClient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	cfg, err := getConfig(store)

+ 13 - 0
pkg/provider/senhasegura/provider.go

@@ -24,6 +24,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	senhaseguraAuth "github.com/external-secrets/external-secrets/pkg/provider/senhasegura/auth"
 	"github.com/external-secrets/external-secrets/pkg/provider/senhasegura/dsm"
 )
@@ -50,6 +51,18 @@ func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
 
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (client.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 /*
 Construct a new secrets client based on provided store.
 */

+ 13 - 0
pkg/provider/testing/fake/fake.go

@@ -22,6 +22,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 var _ esv1beta1.Provider = &Client{}
@@ -175,6 +176,18 @@ func (v *Client) NewClient(ctx context.Context, store esv1beta1.GenericStore, ku
 	return c, nil
 }
 
+func (v *Client) Convert(_ esv1beta1.GenericStore) (client.Object, error) {
+	return nil, nil
+}
+
+func (v *Client) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+
+func (v *Client) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, nil
+}
+
 func (v *Client) Reset() {
 	v.WithNew(func(context.Context, esv1beta1.GenericStore, client.Client,
 		string) (esv1beta1.SecretsClient, error) {

+ 14 - 1
pkg/provider/vault/provider.go

@@ -29,6 +29,7 @@ import (
 	ctrlcfg "sigs.k8s.io/controller-runtime/pkg/client/config"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/cache"
 	"github.com/external-secrets/external-secrets/pkg/feature"
 	"github.com/external-secrets/external-secrets/pkg/provider/vault/util"
@@ -80,6 +81,18 @@ func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadWrite
 }
 
+func (p *Provider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // NewClient implements the Client interface.
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	// controller-runtime/client does not support TokenRequest or other subresource APIs
@@ -174,7 +187,7 @@ func (p *Provider) initClient(ctx context.Context, c *client, client util.Client
 	return c, nil
 }
 
-func (p *Provider) prepareConfig(ctx context.Context, kube kclient.Client, corev1 typedcorev1.CoreV1Interface, vaultSpec *esv1beta1.VaultProvider, retrySettings *esv1beta1.SecretStoreRetrySettings, namespace, storeKind string) (*client, *vault.Config, error) {
+func (p *Provider) prepareConfig(ctx context.Context, kube kclient.Client, corev1 typedcorev1.CoreV1Interface, vaultSpec *esv1beta1.VaultProvider, retrySettings *esmeta.RetrySettings, namespace, storeKind string) (*client, *vault.Config, error) {
 	c := &client{
 		kube:      kube,
 		corev1:    corev1,

+ 4 - 4
pkg/provider/vault/provider_test.go

@@ -111,7 +111,7 @@ func makeValidSecretStoreWithCerts() *esv1beta1.SecretStore {
 
 func makeValidSecretStoreWithK8sCerts(isSecret bool) *esv1beta1.SecretStore {
 	store := makeSecretStore()
-	caProvider := &esv1beta1.CAProvider{
+	caProvider := &esmeta.CAProvider{
 		Name: vaultCert,
 		Key:  "cert",
 	}
@@ -150,7 +150,7 @@ func makeInvalidClusterSecretStoreWithK8sCerts() *esv1beta1.ClusterSecretStore {
 							},
 						},
 					},
-					CAProvider: &esv1beta1.CAProvider{
+					CAProvider: &esmeta.CAProvider{
 						Name: vaultCert,
 						Key:  "cert",
 						Type: "Secret",
@@ -270,7 +270,7 @@ MIIFkTCCA3mgAwIBAgIUBEUg3m/WqAsWHG4Q/II3IePFfuowDQYJKoZIhvcNAQELBQAwWDELMAkGA1UE
 			reason: "Should return error if given an invalid Retry Interval.",
 			args: args{
 				store: makeSecretStore(func(s *esv1beta1.SecretStore) {
-					s.Spec.RetrySettings = &esv1beta1.SecretStoreRetrySettings{
+					s.Spec.RetrySettings = &esmeta.RetrySettings{
 						MaxRetries:    ptr.To(int32(3)),
 						RetryInterval: ptr.To("not-an-interval"),
 					}
@@ -284,7 +284,7 @@ MIIFkTCCA3mgAwIBAgIUBEUg3m/WqAsWHG4Q/II3IePFfuowDQYJKoZIhvcNAQELBQAwWDELMAkGA1UE
 			reason: "Should return a Vault provider with custom retry settings",
 			args: args{
 				store: makeSecretStore(func(s *esv1beta1.SecretStore) {
-					s.Spec.RetrySettings = &esv1beta1.SecretStoreRetrySettings{
+					s.Spec.RetrySettings = &esmeta.RetrySettings{
 						MaxRetries:    ptr.To(int32(3)),
 						RetryInterval: ptr.To("10m"),
 					}

+ 13 - 0
pkg/provider/webhook/webhook.go

@@ -28,6 +28,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	"github.com/external-secrets/external-secrets/pkg/common/webhook"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
@@ -61,6 +62,18 @@ func (p *Provider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
 
+func (p *Provider) ApplyReferent(spec client.Object, _ esmeta.ReferentCallOrigin, _ string) (client.Object, error) {
+	return spec, nil
+}
+
+func (p *Provider) Convert(_ esv1beta1.GenericStore) (client.Object, error) {
+	return nil, nil
+}
+
+func (p *Provider) NewClientFromObj(_ context.Context, _ client.Object, _ client.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 func (p *Provider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube client.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	wh := webhook.Webhook{
 		Kube:      kube,

+ 12 - 0
pkg/provider/yandex/common/provider.go

@@ -109,6 +109,18 @@ func (p *YandexCloudProvider) Capabilities() esv1beta1.SecretStoreCapabilities {
 	return esv1beta1.SecretStoreReadOnly
 }
 
+func (p *YandexCloudProvider) Convert(_ esv1beta1.GenericStore) (kclient.Object, error) {
+	// Makes default to normal SecretStore approach
+	return nil, nil
+}
+
+func (p *YandexCloudProvider) ApplyReferent(spec kclient.Object, _ esmeta.ReferentCallOrigin, _ string) (kclient.Object, error) {
+	return spec, nil
+}
+func (p *YandexCloudProvider) NewClientFromObj(_ context.Context, _ kclient.Object, _ kclient.Client, _ string) (esv1beta1.SecretsClient, error) {
+	return nil, fmt.Errorf("not implemented")
+}
+
 // NewClient constructs a Yandex.Cloud Provider.
 func (p *YandexCloudProvider) NewClient(ctx context.Context, store esv1beta1.GenericStore, kube kclient.Client, namespace string) (esv1beta1.SecretsClient, error) {
 	input, err := p.adaptInputFunc(store)

+ 5 - 5
pkg/utils/utils.go

@@ -525,7 +525,7 @@ func CompareStringAndByteSlices(valueString *string, valueByte []byte) bool {
 // CreateCertOpts contains options for a cert pool creation.
 type CreateCertOpts struct {
 	CABundle   []byte
-	CAProvider *esv1beta1.CAProvider
+	CAProvider *esmeta.CAProvider
 	StoreKind  string
 	Namespace  string
 	Client     client.Client
@@ -554,14 +554,14 @@ func FetchCACertFromSource(ctx context.Context, opts CreateCertOpts) ([]byte, er
 	}
 
 	switch opts.CAProvider.Type {
-	case esv1beta1.CAProviderTypeSecret:
+	case esmeta.CAProviderTypeSecret:
 		cert, err := getCertFromSecret(ctx, opts.Client, opts.CAProvider, opts.StoreKind, opts.Namespace)
 		if err != nil {
 			return nil, fmt.Errorf("failed to get cert from secret: %w", err)
 		}
 
 		return cert, nil
-	case esv1beta1.CAProviderTypeConfigMap:
+	case esmeta.CAProviderTypeConfigMap:
 		cert, err := getCertFromConfigMap(ctx, opts.Namespace, opts.Client, opts.CAProvider)
 		if err != nil {
 			return nil, fmt.Errorf("failed to get cert from configmap: %w", err)
@@ -600,7 +600,7 @@ func parseCertificateBytes(certBytes []byte) ([]byte, error) {
 	return certBytes, nil
 }
 
-func getCertFromSecret(ctx context.Context, c client.Client, provider *esv1beta1.CAProvider, storeKind, namespace string) ([]byte, error) {
+func getCertFromSecret(ctx context.Context, c client.Client, provider *esmeta.CAProvider, storeKind, namespace string) ([]byte, error) {
 	secretRef := esmeta.SecretKeySelector{
 		Name: provider.Name,
 		Key:  provider.Key,
@@ -618,7 +618,7 @@ func getCertFromSecret(ctx context.Context, c client.Client, provider *esv1beta1
 	return []byte(cert), nil
 }
 
-func getCertFromConfigMap(ctx context.Context, namespace string, c client.Client, provider *esv1beta1.CAProvider) ([]byte, error) {
+func getCertFromConfigMap(ctx context.Context, namespace string, c client.Client, provider *esmeta.CAProvider) ([]byte, error) {
 	objKey := client.ObjectKey{
 		Name:      provider.Name,
 		Namespace: namespace,