Browse Source

:sparkles: Add Alibaba RRSA auth support (#1752)

support alibaba oidc assume role

---------

Signed-off-by: Maxim Rubchinsky <maxim.rubchinsky@wiz.io>
Co-authored-by: Moritz Johner <beller.moritz@googlemail.com>
Maxim Rubchinsky 3 years ago
parent
commit
59f5759106

+ 13 - 4
apis/externalsecrets/v1alpha1/secretstore_alibaba_types.go

@@ -20,7 +20,18 @@ import (
 
 // AlibabaAuth contains a secretRef for credentials.
 type AlibabaAuth struct {
-	SecretRef AlibabaAuthSecretRef `json:"secretRef"`
+	// +optional
+	SecretRef *AlibabaAuthSecretRef `json:"secretRef,omitempty"`
+	// +optional
+	RRSAAuth *AlibabaRRSAAuth `json:"rrsa,omitempty"`
+}
+
+// Authenticate against Alibaba using RRSA.
+type AlibabaRRSAAuth struct {
+	OIDCProviderARN   string `json:"oidcProviderArn"`
+	OIDCTokenFilePath string `json:"oidcTokenFilePath"`
+	RoleARN           string `json:"roleArn"`
+	SessionName       string `json:"sessionName"`
 }
 
 // AlibabaAuthSecretRef holds secret references for Alibaba credentials.
@@ -33,9 +44,7 @@ type AlibabaAuthSecretRef struct {
 
 // AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
 type AlibabaProvider struct {
-	Auth *AlibabaAuth `json:"auth"`
-	// +optional
-	Endpoint string `json:"endpoint"`
+	Auth AlibabaAuth `json:"auth"`
 	// Alibaba Region to be used for the provider
 	RegionID string `json:"regionID"`
 }

+ 26 - 6
apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go

@@ -205,7 +205,16 @@ func (in *AkeylessProvider) DeepCopy() *AkeylessProvider {
 // 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
-	in.SecretRef.DeepCopyInto(&out.SecretRef)
+	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.
@@ -238,11 +247,7 @@ func (in *AlibabaAuthSecretRef) DeepCopy() *AlibabaAuthSecretRef {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *AlibabaProvider) DeepCopyInto(out *AlibabaProvider) {
 	*out = *in
-	if in.Auth != nil {
-		in, out := &in.Auth, &out.Auth
-		*out = new(AlibabaAuth)
-		(*in).DeepCopyInto(*out)
-	}
+	in.Auth.DeepCopyInto(&out.Auth)
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaProvider.
@@ -256,6 +261,21 @@ func (in *AlibabaProvider) DeepCopy() *AlibabaProvider {
 }
 
 // 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 *AzureKVAuth) DeepCopyInto(out *AzureKVAuth) {
 	*out = *in
 	if in.ClientID != nil {

+ 13 - 4
apis/externalsecrets/v1beta1/secretstore_alibaba_types.go

@@ -20,7 +20,10 @@ import (
 
 // AlibabaAuth contains a secretRef for credentials.
 type AlibabaAuth struct {
-	SecretRef AlibabaAuthSecretRef `json:"secretRef"`
+	// +optional
+	SecretRef *AlibabaAuthSecretRef `json:"secretRef,omitempty"`
+	// +optional
+	RRSAAuth *AlibabaRRSAAuth `json:"rrsa,omitempty"`
 }
 
 // AlibabaAuthSecretRef holds secret references for Alibaba credentials.
@@ -31,11 +34,17 @@ type AlibabaAuthSecretRef struct {
 	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 AlibabaProvider struct {
-	Auth *AlibabaAuth `json:"auth"`
-	// +optional
-	Endpoint string `json:"endpoint"`
+	Auth AlibabaAuth `json:"auth"`
 	// Alibaba Region to be used for the provider
 	RegionID string `json:"regionID"`
 }

+ 26 - 6
apis/externalsecrets/v1beta1/zz_generated.deepcopy.go

@@ -215,7 +215,16 @@ func (in *AkeylessProvider) DeepCopy() *AkeylessProvider {
 // 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
-	in.SecretRef.DeepCopyInto(&out.SecretRef)
+	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.
@@ -248,11 +257,7 @@ func (in *AlibabaAuthSecretRef) DeepCopy() *AlibabaAuthSecretRef {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *AlibabaProvider) DeepCopyInto(out *AlibabaProvider) {
 	*out = *in
-	if in.Auth != nil {
-		in, out := &in.Auth, &out.Auth
-		*out = new(AlibabaAuth)
-		(*in).DeepCopyInto(*out)
-	}
+	in.Auth.DeepCopyInto(&out.Auth)
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaProvider.
@@ -266,6 +271,21 @@ func (in *AlibabaProvider) DeepCopy() *AlibabaProvider {
 }
 
 // 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 *AzureKVAuth) DeepCopyInto(out *AzureKVAuth) {
 	*out = *in
 	if in.ClientID != nil {

+ 34 - 8
config/crds/bases/external-secrets.io_clustersecretstores.yaml

@@ -254,6 +254,23 @@ spec:
                       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.
@@ -302,11 +319,7 @@ spec:
                             - accessKeyIDSecretRef
                             - accessKeySecretSecretRef
                             type: object
-                        required:
-                        - secretRef
                         type: object
-                      endpoint:
-                        type: string
                       regionID:
                         description: Alibaba Region to be used for the provider
                         type: string
@@ -1840,6 +1853,23 @@ spec:
                       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.
@@ -1888,11 +1918,7 @@ spec:
                             - accessKeyIDSecretRef
                             - accessKeySecretSecretRef
                             type: object
-                        required:
-                        - secretRef
                         type: object
-                      endpoint:
-                        type: string
                       regionID:
                         description: Alibaba Region to be used for the provider
                         type: string

+ 34 - 8
config/crds/bases/external-secrets.io_secretstores.yaml

@@ -254,6 +254,23 @@ spec:
                       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.
@@ -302,11 +319,7 @@ spec:
                             - accessKeyIDSecretRef
                             - accessKeySecretSecretRef
                             type: object
-                        required:
-                        - secretRef
                         type: object
-                      endpoint:
-                        type: string
                       regionID:
                         description: Alibaba Region to be used for the provider
                         type: string
@@ -1840,6 +1853,23 @@ spec:
                       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.
@@ -1888,11 +1918,7 @@ spec:
                             - accessKeyIDSecretRef
                             - accessKeySecretSecretRef
                             type: object
-                        required:
-                        - secretRef
                         type: object
-                      endpoint:
-                        type: string
                       regionID:
                         description: Alibaba Region to be used for the provider
                         type: string

+ 68 - 16
deploy/crds/bundle.yaml

@@ -639,6 +639,23 @@ spec:
                         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:
@@ -672,11 +689,7 @@ spec:
                                 - accessKeyIDSecretRef
                                 - accessKeySecretSecretRef
                               type: object
-                          required:
-                            - secretRef
                           type: object
-                        endpoint:
-                          type: string
                         regionID:
                           description: Alibaba Region to be used for the provider
                           type: string
@@ -1788,6 +1801,23 @@ spec:
                         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:
@@ -1821,11 +1851,7 @@ spec:
                                 - accessKeyIDSecretRef
                                 - accessKeySecretSecretRef
                               type: object
-                          required:
-                            - secretRef
                           type: object
-                        endpoint:
-                          type: string
                         regionID:
                           description: Alibaba Region to be used for the provider
                           type: string
@@ -4070,6 +4096,23 @@ spec:
                         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:
@@ -4103,11 +4146,7 @@ spec:
                                 - accessKeyIDSecretRef
                                 - accessKeySecretSecretRef
                               type: object
-                          required:
-                            - secretRef
                           type: object
-                        endpoint:
-                          type: string
                         regionID:
                           description: Alibaba Region to be used for the provider
                           type: string
@@ -5219,6 +5258,23 @@ spec:
                         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:
@@ -5252,11 +5308,7 @@ spec:
                                 - accessKeyIDSecretRef
                                 - accessKeySecretSecretRef
                               type: object
-                          required:
-                            - secretRef
                           type: object
-                        endpoint:
-                          type: string
                         regionID:
                           description: Alibaba Region to be used for the provider
                           type: string

+ 66 - 4
docs/api/spec.md

@@ -547,6 +547,20 @@ AlibabaAuthSecretRef
 </em>
 </td>
 <td>
+<em>(Optional)</em>
+</td>
+</tr>
+<tr>
+<td>
+<code>rrsa</code></br>
+<em>
+<a href="#external-secrets.io/v1beta1.AlibabaRRSAAuth">
+AlibabaRRSAAuth
+</a>
+</em>
+</td>
+<td>
+<em>(Optional)</em>
 </td>
 </tr>
 </tbody>
@@ -627,24 +641,72 @@ AlibabaAuth
 </tr>
 <tr>
 <td>
-<code>endpoint</code></br>
+<code>regionID</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+<p>Alibaba Region to be used for the provider</p>
+</td>
+</tr>
+</tbody>
+</table>
+<h3 id="external-secrets.io/v1beta1.AlibabaRRSAAuth">AlibabaRRSAAuth
+</h3>
+<p>
+(<em>Appears on:</em>
+<a href="#external-secrets.io/v1beta1.AlibabaAuth">AlibabaAuth</a>)
+</p>
+<p>
+<p>Authenticate against Alibaba using RRSA.</p>
+</p>
+<table>
+<thead>
+<tr>
+<th>Field</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>
+<code>oidcProviderArn</code></br>
 <em>
 string
 </em>
 </td>
 <td>
-<em>(Optional)</em>
 </td>
 </tr>
 <tr>
 <td>
-<code>regionID</code></br>
+<code>oidcTokenFilePath</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
+<tr>
+<td>
+<code>roleArn</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
+<tr>
+<td>
+<code>sessionName</code></br>
 <em>
 string
 </em>
 </td>
 <td>
-<p>Alibaba Region to be used for the provider</p>
 </td>
 </tr>
 </tbody>

+ 70 - 0
docs/provider/alibaba.md

@@ -0,0 +1,70 @@
+
+## Alibaba Cloud Secrets Manager
+
+External Secrets Operator integrates with [Alibaba Cloud Key Management Service](https://www.alibabacloud.com/help/en/key-management-service/latest/kms-what-is-key-management-service/) for secrets and Keys management.
+
+### Authentication
+
+We support Access key and RRSA authentication.
+
+To use RRSA authentication, you should follow [Use RRSA to authorize pods to access different cloud services](https://www.alibabacloud.com/help/en/container-service-for-kubernetes/latest/use-rrsa-to-enforce-access-control/) to assign the RAM role to external-secrets operator.
+
+#### RRSA authentication
+
+When using RRSA authentication we manually project the OIDC token file to pod as volume
+
+```yaml
+extraVolumes:
+  - name: oidc-token
+    projected:
+      sources:
+      - serviceAccountToken:
+          path: oidc-token
+          expirationSeconds: 7200    # The validity period of the OIDC token in seconds.
+          audience: "sts.aliyuncs.com"
+
+extraVolumeMounts:
+  - name: oidc-token
+    mountPath: /var/run/secrets/tokens
+```
+
+and provide the RAM role ARN and OIDC volume path to the secret store
+```yaml
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+  name: secretstore-sample
+spec:
+  provider:
+    alibaba:
+      regionID: ap-southeast-1
+      auth:
+        rrsa:
+          oidcProviderArn: acs:ram::1234:oidc-provider/ack-rrsa-ce123456
+          oidcTokenFilePath: /var/run/secrets/tokens/oidc-token
+          roleArn: acs:ram::1234:role/test-role
+          sessionName: secrets
+```
+
+### Creating external secret
+
+To create a kubernetes secret from the Alibaba Cloud Key Management Service secret a `Kind=ExternalSecret` is needed.
+
+```yaml
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+  name: example
+spec:
+  refreshInterval: 1h
+  secretStoreRef:
+    name: secretstore-sample
+    kind: SecretStore
+  target:
+    name: example-secret
+    creationPolicy: Owner
+  data:
+    - secretKey: secret-key
+      remoteRef:
+        key: ext-secret
+```

+ 15 - 2
go.mod

@@ -17,7 +17,6 @@ require (
 	github.com/PaesslerAG/jsonpath v0.1.1
 	github.com/ahmetb/gen-crd-api-reference-docs v0.3.0
 	github.com/akeylesslabs/akeyless-go-cloud-id v0.3.4
-	github.com/aliyun/alibaba-cloud-sdk-go v1.62.271
 	github.com/aws/aws-sdk-go v1.44.236
 	github.com/go-logr/logr v1.2.4
 	github.com/go-test/deep v1.0.4 // indirect
@@ -65,6 +64,13 @@ require (
 	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0
 	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.2
 	github.com/akeylesslabs/akeyless-go/v3 v3.3.0
+	github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4
+	github.com/alibabacloud-go/kms-20160120/v3 v3.0.1
+	github.com/alibabacloud-go/openapi-util v0.1.0
+	github.com/alibabacloud-go/tea v1.1.20
+	github.com/alibabacloud-go/tea-utils/v2 v2.0.1
+	github.com/aliyun/credentials-go v1.2.7
+	github.com/avast/retry-go/v4 v4.3.3
 	github.com/hashicorp/golang-lru v0.5.4
 	github.com/keeper-security/secrets-manager-go/core v1.5.0
 	github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1
@@ -76,8 +82,15 @@ require (
 
 require (
 	cloud.google.com/go/compute/metadata v0.2.3 // indirect
+	github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
+	github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect
+	github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
+	github.com/alibabacloud-go/tea-utils v1.3.1 // indirect
+	github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
+	github.com/clbanning/mxj/v2 v2.5.5 // indirect
 	github.com/go-playground/validator/v10 v10.12.0 // indirect
 	github.com/rogpeppe/go-internal v1.9.0 // indirect
+	github.com/tjfoc/gmsm v1.3.2 // indirect
 )
 
 require (
@@ -129,7 +142,7 @@ require (
 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
 	github.com/hashicorp/go-hclog v1.4.0 // indirect
 	github.com/hashicorp/go-multierror v1.1.1 // indirect
-	github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
+	github.com/hashicorp/go-retryablehttp v0.7.2
 	github.com/hashicorp/go-rootcerts v1.0.2 // indirect
 	github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 // indirect
 	github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect

+ 53 - 6
go.sum

@@ -112,12 +112,43 @@ github.com/akeylesslabs/akeyless-go-cloud-id v0.3.4 h1:vTckjyBhHOBiOWSC/oaEU2Oo4
 github.com/akeylesslabs/akeyless-go-cloud-id v0.3.4/go.mod h1:As/RomC2w/fa3y+yHRlVHPmkbP+zrKBFRow41y5dk+E=
 github.com/akeylesslabs/akeyless-go/v3 v3.3.0 h1:prmWbmCmGEgwfcePZoYuQC58TBv7KgA92ikuXu8Y1Hs=
 github.com/akeylesslabs/akeyless-go/v3 v3.3.0/go.mod h1:XtPdOYw+rrG9bxyBzuQ5zAGCUTd364R2grs7GsZ5nos=
-github.com/aliyun/alibaba-cloud-sdk-go v1.62.271 h1:0QmSDMovuCyUbYp70MZHoTi/GYnHb/wYEIIBqoVsCjs=
-github.com/aliyun/alibaba-cloud-sdk-go v1.62.271/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs=
+github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo=
+github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc=
+github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.2/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
+github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4 h1:7Q2FEyqxeZeIkwYMwRC3uphxV4i7O2eV4ETe21d6lS4=
+github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
+github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 h1:NqugFkGxx1TXSh/pBcU00Y6bljgDPaFdh5MUSeJ7e50=
+github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
+github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
+github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
+github.com/alibabacloud-go/kms-20160120/v3 v3.0.1 h1:bfwJOM7JN3fMUZyE3dLFvUkSAtDrfC0KGc4YGaZPHqI=
+github.com/alibabacloud-go/kms-20160120/v3 v3.0.1/go.mod h1:xriQJPqZz/LJgDEwljqOvCOP7X4x2jYdJq2HVOc+VG8=
+github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
+github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY=
+github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws=
+github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg=
+github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
+github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4=
+github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
+github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
+github.com/alibabacloud-go/tea v1.1.20 h1:wFK4xEbvGYMtzTyHhIju9D7ecWxvSUdoLO6y4vDLFik=
+github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A=
+github.com/alibabacloud-go/tea-utils v1.3.1 h1:iWQeRzRheqCMuiF3+XkfybB3kTgUXkXX+JMrqfLeB2I=
+github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
+github.com/alibabacloud-go/tea-utils/v2 v2.0.0/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
+github.com/alibabacloud-go/tea-utils/v2 v2.0.1 h1:K6kwgo+UiYx+/kr6CO0PN5ACZDzE3nnn9d77215AkTs=
+github.com/alibabacloud-go/tea-utils/v2 v2.0.1/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
+github.com/alibabacloud-go/tea-xml v1.1.2 h1:oLxa7JUXm2EDFzMg+7oRsYc+kutgCVwm+bZlhhmvW5M=
+github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
+github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
+github.com/aliyun/credentials-go v1.2.7 h1:gLtFylxLZ1TWi1pStIt1O6a53GFU1zkNwjtJir2B4ow=
+github.com/aliyun/credentials-go v1.2.7/go.mod h1:/KowD1cfGSLrLsH28Jr8W+xwoId0ywIy5lNzDz6O1vw=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
+github.com/avast/retry-go/v4 v4.3.3 h1:G56Bp6mU0b5HE1SkaoVjscZjlQb0oy4mezwY/cGH19w=
+github.com/avast/retry-go/v4 v4.3.3/go.mod h1:rg6XFaiuFYII0Xu3RDbZQkxCofFwruZKW8oEF1jpWiU=
 github.com/aws/aws-sdk-go v1.41.13/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
 github.com/aws/aws-sdk-go v1.44.236 h1:Ilbq/9B617BNjviTPjZrSbMxUkCb/1M7DqHO6sXOJTc=
 github.com/aws/aws-sdk-go v1.44.236/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
@@ -139,6 +170,8 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
+github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -225,7 +258,6 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
 github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
 github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
 github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
 github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
@@ -317,6 +349,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/gax-go/v2 v2.8.0 h1:UBtEZqx1bjXtOQ5BVTkuYghXrr3N4V123VKJK67vJZc=
 github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
@@ -370,18 +404,18 @@ github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+h
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
-github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
 github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
 github.com/keeper-security/secrets-manager-go/core v1.5.0 h1:8cPzRWjIXNvhw9VC/1lZL26apmZYPtwUuUtKLV0Tw/c=
 github.com/keeper-security/secrets-manager-go/core v1.5.0/go.mod h1:dtlaeeds9+SZsbDAZnQRsDSqEAK9a62SYtqhNql+VgQ=
@@ -455,6 +489,7 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
@@ -511,6 +546,9 @@ github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR
 github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
 github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
 github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
 github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg=
 github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
@@ -524,6 +562,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -547,6 +586,8 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV
 github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
 github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
 github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
+github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM=
+github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
 github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
 github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
 github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
@@ -568,6 +609,7 @@ github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqTosly
 github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
@@ -599,7 +641,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@@ -749,6 +793,7 @@ golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -819,6 +864,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
@@ -849,6 +895,7 @@ golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjs
 golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
 golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -1001,7 +1048,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=

+ 1 - 0
hack/api-docs/mkdocs.yml

@@ -89,6 +89,7 @@ nav:
     - HashiCorp Vault: provider/hashicorp-vault.md
     - Yandex Certificate Manager: provider/yandex-certificate-manager.md
     - Yandex Lockbox: provider/yandex-lockbox.md
+    - Alibaba Cloud: provider/alibaba.md
     - Gitlab Variables: provider/gitlab-variables.md
     - Oracle Vault: provider/oracle-vault.md
     - 1Password Secrets Automation: provider/1password-automation.md

+ 276 - 0
pkg/provider/alibaba/client.go

@@ -0,0 +1,276 @@
+/*
+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 alibaba
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/url"
+	"runtime"
+	"strings"
+	"time"
+
+	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
+	kms "github.com/alibabacloud-go/kms-20160120/v3/client"
+	openapiutil "github.com/alibabacloud-go/openapi-util/service"
+	util "github.com/alibabacloud-go/tea-utils/v2/service"
+	"github.com/alibabacloud-go/tea/tea"
+	"github.com/hashicorp/go-retryablehttp"
+
+	"github.com/external-secrets/external-secrets/pkg/utils"
+)
+
+const (
+	kmsAPIVersion = "2016-01-20"
+)
+
+type SecretsManagerClient interface {
+	GetSecretValue(
+		ctx context.Context,
+		request *kms.GetSecretValueRequest,
+	) (*kms.GetSecretValueResponseBody, error)
+	Endpoint() string
+}
+
+type secretsManagerClient struct {
+	config   *openapi.Config
+	options  *util.RuntimeOptions
+	endpoint string
+	client   *http.Client
+}
+
+var _ SecretsManagerClient = (*secretsManagerClient)(nil)
+
+func newClient(config *openapi.Config, options *util.RuntimeOptions) (*secretsManagerClient, error) {
+	kmsClient, err := kms.NewClient(config)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create Alibaba KMS client: %w", err)
+	}
+
+	endpoint, err := kmsClient.GetEndpoint(tea.String("kms"), kmsClient.RegionId, kmsClient.EndpointRule, kmsClient.Network, kmsClient.Suffix, kmsClient.EndpointMap, kmsClient.Endpoint)
+	if err != nil {
+		return nil, fmt.Errorf("failed to get KMS endpoint: %w", err)
+	}
+
+	if utils.Deref(endpoint) == "" {
+		return nil, fmt.Errorf("error KMS endpoint is missing")
+	}
+
+	const (
+		connectTimeoutSec   = 30
+		readWriteTimeoutSec = 60
+	)
+
+	retryClient := retryablehttp.NewClient()
+	retryClient.CheckRetry = retryablehttp.ErrorPropagatedRetryPolicy
+	retryClient.Backoff = retryablehttp.DefaultBackoff
+	retryClient.Logger = log
+	retryClient.HTTPClient = &http.Client{
+		Timeout: time.Second * time.Duration(readWriteTimeoutSec),
+	}
+
+	const defaultRetryAttempts = 3
+	if utils.Deref(options.Autoretry) {
+		if options.MaxAttempts != nil {
+			retryClient.RetryMax = utils.Deref(options.MaxAttempts)
+		} else {
+			retryClient.RetryMax = defaultRetryAttempts
+		}
+	}
+
+	return &secretsManagerClient{
+		config:   config,
+		options:  options,
+		endpoint: utils.Deref(endpoint),
+		client:   retryClient.StandardClient(),
+	}, nil
+}
+
+func (s *secretsManagerClient) Endpoint() string {
+	return s.endpoint
+}
+
+func (s *secretsManagerClient) GetSecretValue(
+	ctx context.Context,
+	request *kms.GetSecretValueRequest,
+) (*kms.GetSecretValueResponseBody, error) {
+	resp, err := s.doAPICall(ctx, "GetSecretValue", request)
+	if err != nil {
+		return nil, fmt.Errorf("error getting secret [%s] latest value: %w", utils.Deref(request.SecretName), err)
+	}
+
+	body, err := utils.ConvertToType[kms.GetSecretValueResponseBody](resp)
+	if err != nil {
+		return nil, fmt.Errorf("error converting body: %w", err)
+	}
+
+	return &body, nil
+}
+
+func (s *secretsManagerClient) doAPICall(ctx context.Context,
+	action string,
+	request any) (any, error) {
+	accessKeyID, err := s.config.Credential.GetAccessKeyId()
+	if err != nil {
+		return nil, fmt.Errorf("error getting AccessKeyId: %w", err)
+	}
+
+	accessKeySecret, err := s.config.Credential.GetAccessKeySecret()
+	if err != nil {
+		return nil, fmt.Errorf("error getting AccessKeySecret: %w", err)
+	}
+
+	securityToken, err := s.config.Credential.GetSecurityToken()
+	if err != nil {
+		return nil, fmt.Errorf("error getting SecurityToken: %w", err)
+	}
+
+	apiRequest := newOpenAPIRequest(s.endpoint, action, methodTypeGET, request)
+	apiRequest.query["AccessKeyId"] = accessKeyID
+
+	if utils.Deref(securityToken) != "" {
+		apiRequest.query["SecurityToken"] = securityToken
+	}
+
+	apiRequest.query["Signature"] = openapiutil.GetRPCSignature(apiRequest.query, utils.Ptr(apiRequest.method.String()), accessKeySecret)
+
+	httpReq, err := newHTTPRequestWithContext(ctx, apiRequest)
+	if err != nil {
+		return nil, fmt.Errorf("error creating http request: %w", err)
+	}
+
+	resp, err := s.client.Do(httpReq)
+	if err != nil {
+		return nil, fmt.Errorf("error invoking http request: %w", err)
+	}
+	defer resp.Body.Close()
+
+	return s.parseResponse(resp)
+}
+
+func (s *secretsManagerClient) parseResponse(resp *http.Response) (map[string]interface{}, error) {
+	statusCode := utils.Ptr(resp.StatusCode)
+	if utils.Deref(util.Is4xx(statusCode)) || utils.Deref(util.Is5xx(statusCode)) {
+		return nil, s.parseErrorResponse(resp)
+	}
+
+	obj, err := util.ReadAsJSON(resp.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	res, err := util.AssertAsMap(obj)
+	if err != nil {
+		return nil, err
+	}
+
+	return res, nil
+}
+
+func (s *secretsManagerClient) parseErrorResponse(resp *http.Response) error {
+	res, err := util.ReadAsJSON(resp.Body)
+	if err != nil {
+		return err
+	}
+
+	errorMap, err := util.AssertAsMap(res)
+	if err != nil {
+		return err
+	}
+
+	errorMap["statusCode"] = utils.Ptr(resp.StatusCode)
+	err = tea.NewSDKError(map[string]interface{}{
+		"code":               tea.ToString(defaultAny(errorMap["Code"], errorMap["code"])),
+		"message":            fmt.Sprintf("code: %s, %s", tea.ToString(resp.StatusCode), tea.ToString(defaultAny(errorMap["Message"], errorMap["message"]))),
+		"data":               errorMap,
+		"description":        tea.ToString(defaultAny(errorMap["Description"], errorMap["description"])),
+		"accessDeniedDetail": errorMap["AccessDeniedDetail"],
+	})
+	return err
+}
+
+type methodType string
+
+const (
+	methodTypeGET = "GET"
+)
+
+func (m methodType) String() string {
+	return string(m)
+}
+
+type openAPIRequest struct {
+	endpoint string
+	method   methodType
+	headers  map[string]*string
+	query    map[string]*string
+}
+
+func newOpenAPIRequest(endpoint string,
+	action string,
+	method methodType,
+	request interface{},
+) *openAPIRequest {
+	req := &openAPIRequest{
+		endpoint: endpoint,
+		method:   method,
+		headers: map[string]*string{
+			"host":          &endpoint,
+			"x-acs-version": utils.Ptr(kmsAPIVersion),
+			"x-acs-action":  &action,
+			"user-agent":    utils.Ptr(fmt.Sprintf("AlibabaCloud (%s; %s) Golang/%s Core/%s TeaDSL/1", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), "0.01")),
+		},
+		query: map[string]*string{
+			"Action":           &action,
+			"Format":           utils.Ptr("json"),
+			"Version":          utils.Ptr(kmsAPIVersion),
+			"Timestamp":        openapiutil.GetTimestamp(),
+			"SignatureNonce":   util.GetNonce(),
+			"SignatureMethod":  utils.Ptr("HMAC-SHA1"),
+			"SignatureVersion": utils.Ptr("1.0"),
+		},
+	}
+
+	req.query = tea.Merge(req.query, openapiutil.Query(request))
+	return req
+}
+
+func newHTTPRequestWithContext(ctx context.Context,
+	req *openAPIRequest) (*http.Request, error) {
+	query := url.Values{}
+	for k, v := range req.query {
+		query.Add(k, utils.Deref(v))
+	}
+
+	httpReq, err := http.NewRequestWithContext(ctx, req.method.String(), fmt.Sprintf("https://%s/?%s", url.PathEscape(req.endpoint), query.Encode()), http.NoBody)
+	if err != nil {
+		return nil, fmt.Errorf("error converting OpenAPI request to http request: %w", err)
+	}
+
+	for k, v := range req.headers {
+		httpReq.Header.Add(k, utils.Deref(v))
+	}
+
+	return httpReq, nil
+}
+
+func defaultAny(inputValue, defaultValue any) any {
+	if utils.Deref(util.IsUnset(inputValue)) {
+		return defaultValue
+	}
+
+	return inputValue
+}

+ 11 - 5
pkg/provider/alibaba/fake/fake.go

@@ -15,21 +15,27 @@ limitations under the License.
 package fake
 
 import (
-	kmssdk "github.com/aliyun/alibaba-cloud-sdk-go/services/kms"
+	"context"
+
+	kmssdk "github.com/alibabacloud-go/kms-20160120/v3/client"
 )
 
 type AlibabaMockClient struct {
-	getSecretValue func(request *kmssdk.GetSecretValueRequest) (response *kmssdk.GetSecretValueResponse, err error)
+	getSecretValue func(request *kmssdk.GetSecretValueRequest) (response *kmssdk.GetSecretValueResponseBody, err error)
 }
 
-func (mc *AlibabaMockClient) GetSecretValue(*kmssdk.GetSecretValueRequest) (result *kmssdk.GetSecretValueResponse, err error) {
+func (mc *AlibabaMockClient) GetSecretValue(context.Context, *kmssdk.GetSecretValueRequest) (result *kmssdk.GetSecretValueResponseBody, err error) {
 	return mc.getSecretValue(&kmssdk.GetSecretValueRequest{})
 }
 
-func (mc *AlibabaMockClient) WithValue(in *kmssdk.GetSecretValueRequest, val *kmssdk.GetSecretValueResponse, err error) {
+func (mc *AlibabaMockClient) WithValue(in *kmssdk.GetSecretValueRequest, val *kmssdk.GetSecretValueResponseBody, err error) {
 	if mc != nil {
-		mc.getSecretValue = func(paramIn *kmssdk.GetSecretValueRequest) (*kmssdk.GetSecretValueResponse, error) {
+		mc.getSecretValue = func(paramIn *kmssdk.GetSecretValueRequest) (*kmssdk.GetSecretValueResponseBody, error) {
 			return val, err
 		}
 	}
 }
+
+func (mc *AlibabaMockClient) Endpoint() string {
+	return ""
+}

+ 218 - 93
pkg/provider/alibaba/kms.go

@@ -3,7 +3,7 @@ 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
+	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,
@@ -18,16 +18,18 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"time"
 
-	kmssdk "github.com/aliyun/alibaba-cloud-sdk-go/services/kms"
+	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
+	kmssdk "github.com/alibabacloud-go/kms-20160120/v3/client"
+	util "github.com/alibabacloud-go/tea-utils/v2/service"
+	credential "github.com/aliyun/credentials-go/credentials"
+	"github.com/avast/retry-go/v4"
 	"github.com/tidwall/gjson"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 	kclient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
-	"github.com/external-secrets/external-secrets/pkg/provider/aws/util"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
@@ -42,76 +44,18 @@ const (
 	errMissingAKID                             = "missing AccessKeyID"
 )
 
-type Client struct {
-	kube      kclient.Client
-	store     *esv1beta1.AlibabaProvider
-	namespace string
-	storeKind string
-	regionID  string
-	keyID     []byte
-	accessKey []byte
-}
-
 // https://github.com/external-secrets/external-secrets/issues/644
 var _ esv1beta1.SecretsClient = &KeyManagementService{}
 var _ esv1beta1.Provider = &KeyManagementService{}
 
 type KeyManagementService struct {
 	Client SMInterface
-	url    string
+	Config *openapi.Config
 }
 
 type SMInterface interface {
-	GetSecretValue(request *kmssdk.GetSecretValueRequest) (response *kmssdk.GetSecretValueResponse, err error)
-}
-
-// setAuth creates a new Alibaba session based on a store.
-func (c *Client) setAuth(ctx context.Context) error {
-	credentialsSecret := &corev1.Secret{}
-	credentialsSecretName := c.store.Auth.SecretRef.AccessKeyID.Name
-	if credentialsSecretName == "" {
-		return fmt.Errorf(errAlibabaCredSecretName)
-	}
-	objectKey := types.NamespacedName{
-		Name:      credentialsSecretName,
-		Namespace: c.namespace,
-	}
-
-	// only ClusterStore is allowed to set namespace (and then it's required)
-	if c.storeKind == esv1beta1.ClusterSecretStoreKind {
-		if c.store.Auth.SecretRef.AccessKeyID.Namespace == nil {
-			return fmt.Errorf(errInvalidClusterStoreMissingAKIDNamespace)
-		}
-		objectKey.Namespace = *c.store.Auth.SecretRef.AccessKeyID.Namespace
-	}
-
-	err := c.kube.Get(ctx, objectKey, credentialsSecret)
-	if err != nil {
-		return fmt.Errorf(errFetchAKIDSecret, err)
-	}
-
-	objectKey = types.NamespacedName{
-		Name:      c.store.Auth.SecretRef.AccessKeySecret.Name,
-		Namespace: c.namespace,
-	}
-	if c.storeKind == esv1beta1.ClusterSecretStoreKind {
-		if c.store.Auth.SecretRef.AccessKeySecret.Namespace == nil {
-			return fmt.Errorf(errInvalidClusterStoreMissingSKNamespace)
-		}
-		objectKey.Namespace = *c.store.Auth.SecretRef.AccessKeySecret.Namespace
-	}
-	c.keyID = credentialsSecret.Data[c.store.Auth.SecretRef.AccessKeyID.Key]
-	fmt.Println(c.keyID)
-	fmt.Println(c.accessKey)
-	if (c.keyID == nil) || (len(c.keyID) == 0) {
-		return fmt.Errorf(errMissingAKID)
-	}
-	c.accessKey = credentialsSecret.Data[c.store.Auth.SecretRef.AccessKeySecret.Key]
-	if (c.accessKey == nil) || (len(c.accessKey) == 0) {
-		return fmt.Errorf(errMissingSAK)
-	}
-	c.regionID = c.store.RegionID
-	return nil
+	GetSecretValue(ctx context.Context, request *kmssdk.GetSecretValueRequest) (*kmssdk.GetSecretValueResponseBody, error)
+	Endpoint() string
 }
 
 func (kms *KeyManagementService) PushSecret(ctx context.Context, value []byte, remoteRef esv1beta1.PushRemoteRef) error {
@@ -133,23 +77,28 @@ func (kms *KeyManagementService) GetSecret(ctx context.Context, ref esv1beta1.Ex
 	if utils.IsNil(kms.Client) {
 		return nil, fmt.Errorf(errUninitalizedAlibabaProvider)
 	}
-	kmsRequest := kmssdk.CreateGetSecretValueRequest()
-	kmsRequest.VersionId = ref.Version
-	kmsRequest.SecretName = ref.Key
-	kmsRequest.SetScheme("https")
-	secretOut, err := kms.Client.GetSecretValue(kmsRequest)
+
+	request := &kmssdk.GetSecretValueRequest{
+		SecretName: &ref.Key,
+	}
+
+	if ref.Version != "" {
+		request.VersionId = &ref.Version
+	}
+
+	secretOut, err := kms.Client.GetSecretValue(ctx, request)
 	if err != nil {
-		return nil, util.SanitizeErr(err)
+		return nil, SanitizeErr(err)
 	}
 	if ref.Property == "" {
-		if secretOut.SecretData != "" {
-			return []byte(secretOut.SecretData), nil
+		if utils.Deref(secretOut.SecretData) != "" {
+			return []byte(utils.Deref(secretOut.SecretData)), nil
 		}
 		return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Key)
 	}
 	var payload string
-	if secretOut.SecretData != "" {
-		payload = secretOut.SecretData
+	if utils.Deref(secretOut.SecretData) != "" {
+		payload = utils.Deref(secretOut.SecretData)
 	}
 	val := gjson.Get(payload, ref.Property)
 	if !val.Exists() {
@@ -185,38 +134,170 @@ func (kms *KeyManagementService) Capabilities() esv1beta1.SecretStoreCapabilitie
 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
-	iStore := &Client{
-		kube:      kube,
-		store:     alibabaSpec,
-		namespace: namespace,
-		storeKind: store.GetObjectKind().GroupVersionKind().Kind,
+
+	credentials, err := newAuth(ctx, kube, store, namespace)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create Alibaba credentials: %w", err)
 	}
-	if err := iStore.setAuth(ctx); err != nil {
-		return nil, err
+
+	config := &openapi.Config{
+		RegionId:   utils.Ptr(alibabaSpec.RegionID),
+		Credential: credentials,
 	}
-	alibabaRegion := iStore.regionID
-	alibabaKeyID := iStore.keyID
-	alibabaSecretKey := iStore.accessKey
-	keyManagementService, err := kmssdk.NewClientWithAccessKey(alibabaRegion, string(alibabaKeyID), string(alibabaSecretKey))
+
+	options := newOptions(store)
+	client, err := newClient(config, options)
 	if err != nil {
 		return nil, fmt.Errorf(errAlibabaClient, err)
 	}
-	kms.Client = keyManagementService
-	kms.url = alibabaSpec.Endpoint
+
+	kms.Client = client
+	kms.Config = config
 	return kms, nil
 }
 
+func newOptions(store esv1beta1.GenericStore) *util.RuntimeOptions {
+	storeSpec := store.GetSpec()
+
+	options := &util.RuntimeOptions{}
+	// Setup retry options, if present in storeSpec
+	if storeSpec.RetrySettings != nil {
+		var retryAmount int
+
+		if storeSpec.RetrySettings.MaxRetries != nil {
+			retryAmount = int(*storeSpec.RetrySettings.MaxRetries)
+		} else {
+			retryAmount = 3
+		}
+
+		options.Autoretry = utils.Ptr(true)
+		options.MaxAttempts = utils.Ptr(retryAmount)
+	}
+
+	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
+
+	switch {
+	case alibabaSpec.Auth.RRSAAuth != nil:
+		credentials, err := newRRSAAuth(store)
+		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)
+		if err != nil {
+			return nil, fmt.Errorf("failed to create Alibaba AccessKey credentials: %w", err)
+		}
+
+		return credentials, nil
+	default:
+		return nil, fmt.Errorf("alibaba authentication methods wasn't provided")
+	}
+}
+
+func newRRSAAuth(store esv1beta1.GenericStore) (credential.Credential, error) {
+	storeSpec := store.GetSpec()
+	alibabaSpec := storeSpec.Provider.Alibaba
+
+	credentialConfig := &credential.Config{
+		OIDCProviderArn:   &alibabaSpec.Auth.RRSAAuth.OIDCProviderARN,
+		OIDCTokenFilePath: &alibabaSpec.Auth.RRSAAuth.OIDCTokenFilePath,
+		RoleArn:           &alibabaSpec.Auth.RRSAAuth.RoleARN,
+		RoleSessionName:   &alibabaSpec.Auth.RRSAAuth.SessionName,
+		Type:              utils.Ptr("oidc_role_arn"),
+		ConnectTimeout:    utils.Ptr(30),
+		Timeout:           utils.Ptr(60),
+	}
+
+	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
+
+	credentialsSecret := &corev1.Secret{}
+	credentialsSecretName := alibabaSpec.Auth.SecretRef.AccessKeyID.Name
+	if credentialsSecretName == "" {
+		return nil, fmt.Errorf(errAlibabaCredSecretName)
+	}
+	objectKey := types.NamespacedName{
+		Name:      credentialsSecretName,
+		Namespace: namespace,
+	}
+
+	// only ClusterStore is allowed to set namespace (and then it's required)
+	if storeKind == esv1beta1.ClusterSecretStoreKind {
+		if alibabaSpec.Auth.SecretRef.AccessKeyID.Namespace == nil {
+			return nil, fmt.Errorf(errInvalidClusterStoreMissingAKIDNamespace)
+		}
+		objectKey.Namespace = *alibabaSpec.Auth.SecretRef.AccessKeyID.Namespace
+	}
+
+	err := kube.Get(ctx, objectKey, credentialsSecret)
+	if err != nil {
+		return nil, fmt.Errorf(errFetchAKIDSecret, err)
+	}
+
+	objectKey = types.NamespacedName{
+		Name:      alibabaSpec.Auth.SecretRef.AccessKeySecret.Name,
+		Namespace: namespace,
+	}
+	if storeKind == esv1beta1.ClusterSecretStoreKind {
+		if alibabaSpec.Auth.SecretRef.AccessKeySecret.Namespace == nil {
+			return nil, fmt.Errorf(errInvalidClusterStoreMissingSKNamespace)
+		}
+		objectKey.Namespace = *alibabaSpec.Auth.SecretRef.AccessKeySecret.Namespace
+	}
+
+	accessKeyID := credentialsSecret.Data[alibabaSpec.Auth.SecretRef.AccessKeyID.Key]
+	if (accessKeyID == nil) || (len(accessKeyID) == 0) {
+		return nil, fmt.Errorf(errMissingAKID)
+	}
+
+	accessKeySecret := credentialsSecret.Data[alibabaSpec.Auth.SecretRef.AccessKeySecret.Key]
+	if (accessKeySecret == nil) || (len(accessKeySecret) == 0) {
+		return nil, fmt.Errorf(errMissingSAK)
+	}
+
+	credentialConfig := &credential.Config{
+		AccessKeyId:     utils.Ptr(string(accessKeyID)),
+		AccessKeySecret: utils.Ptr(string(accessKeySecret)),
+		Type:            utils.Ptr("access_key"),
+		ConnectTimeout:  utils.Ptr(30),
+		Timeout:         utils.Ptr(60),
+	}
+
+	return credential.NewCredential(credentialConfig)
+}
+
 func (kms *KeyManagementService) Close(ctx context.Context) error {
 	return nil
 }
 
 func (kms *KeyManagementService) Validate() (esv1beta1.ValidationResult, error) {
-	timeout := 15 * time.Second
-	url := kms.url
-
-	if err := utils.NetworkValidate(url, timeout); err != nil {
-		return esv1beta1.ValidationResultError, err
+	err := retry.Do(
+		func() error {
+			_, err := kms.Config.Credential.GetSecurityToken()
+			if err != nil {
+				return err
+			}
+
+			return nil
+		},
+		retry.Attempts(5),
+	)
+	if err != nil {
+		return esv1beta1.ValidationResultError, SanitizeErr(err)
 	}
+
 	return esv1beta1.ValidationResultReady, nil
 }
 
@@ -230,6 +311,50 @@ func (kms *KeyManagementService) ValidateStore(store esv1beta1.GenericStore) err
 		return fmt.Errorf("missing alibaba region")
 	}
 
+	return kms.validateStoreAuth(store)
+}
+
+func (kms *KeyManagementService) validateStoreAuth(store esv1beta1.GenericStore) error {
+	storeSpec := store.GetSpec()
+	alibabaSpec := storeSpec.Provider.Alibaba
+
+	switch {
+	case alibabaSpec.Auth.RRSAAuth != nil:
+		return kms.validateStoreRRSAAuth(store)
+	case alibabaSpec.Auth.SecretRef != nil:
+		return kms.validateStoreAccessKeyAuth(store)
+	default:
+		return fmt.Errorf("missing alibaba auth provider")
+	}
+}
+
+func (kms *KeyManagementService) validateStoreRRSAAuth(store esv1beta1.GenericStore) error {
+	storeSpec := store.GetSpec()
+	alibabaSpec := storeSpec.Provider.Alibaba
+
+	if alibabaSpec.Auth.RRSAAuth.OIDCProviderARN == "" {
+		return fmt.Errorf("missing alibaba OIDC proivder ARN")
+	}
+
+	if alibabaSpec.Auth.RRSAAuth.OIDCTokenFilePath == "" {
+		return fmt.Errorf("missing alibaba OIDC token file path")
+	}
+
+	if alibabaSpec.Auth.RRSAAuth.RoleARN == "" {
+		return fmt.Errorf("missing alibaba Assume Role ARN")
+	}
+
+	if alibabaSpec.Auth.RRSAAuth.SessionName == "" {
+		return fmt.Errorf("missing alibaba session name")
+	}
+
+	return nil
+}
+
+func (kms *KeyManagementService) validateStoreAccessKeyAuth(store esv1beta1.GenericStore) error {
+	storeSpec := store.GetSpec()
+	alibabaSpec := storeSpec.Provider.Alibaba
+
 	accessKeyID := alibabaSpec.Auth.SecretRef.AccessKeyID
 	err := utils.ValidateSecretSelector(store, accessKeyID)
 	if err != nil {

+ 49 - 33
pkg/provider/alibaba/kms_test.go

@@ -3,7 +3,7 @@ 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
+	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,
@@ -21,12 +21,12 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
-	kmssdk "github.com/aliyun/alibaba-cloud-sdk-go/services/kms"
+	kmssdk "github.com/alibabacloud-go/kms-20160120/v3/client"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	fakesm "github.com/external-secrets/external-secrets/pkg/provider/alibaba/fake"
+	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
 const (
@@ -37,7 +37,7 @@ const (
 type keyManagementServiceTestCase struct {
 	mockClient     *fakesm.AlibabaMockClient
 	apiInput       *kmssdk.GetSecretValueRequest
-	apiOutput      *kmssdk.GetSecretValueResponse
+	apiOutput      *kmssdk.GetSecretValueResponseBody
 	ref            *esv1beta1.ExternalSecretDataRemoteRef
 	apiErr         error
 	expectError    string
@@ -69,28 +69,17 @@ func makeValidRef() *esv1beta1.ExternalSecretDataRemoteRef {
 
 func makeValidAPIInput() *kmssdk.GetSecretValueRequest {
 	return &kmssdk.GetSecretValueRequest{
-		SecretName: secretName,
+		SecretName: utils.Ptr(secretName),
 	}
 }
 
-func makeValidAPIOutput() *kmssdk.GetSecretValueResponse {
-	kmsresponse := &kmssdk.GetSecretValueResponse{
-		BaseResponse:      &responses.BaseResponse{},
-		RequestId:         "",
-		SecretName:        secretName,
-		VersionId:         "",
-		CreateTime:        "",
-		SecretData:        secretValue,
-		SecretDataType:    "",
-		AutomaticRotation: "",
-		RotationInterval:  "",
-		NextRotationDate:  "",
-		ExtendedConfig:    "",
-		LastRotationDate:  "",
-		SecretType:        "",
-		VersionStages:     kmssdk.VersionStagesInGetSecretValue{},
-	}
-	return kmsresponse
+func makeValidAPIOutput() *kmssdk.GetSecretValueResponseBody {
+	response := &kmssdk.GetSecretValueResponseBody{
+		SecretName:    utils.Ptr(secretName),
+		SecretData:    utils.Ptr(secretValue),
+		VersionStages: &kmssdk.GetSecretValueResponseBodyVersionStages{},
+	}
+	return response
 }
 
 func makeValidKMSTestCaseCustom(tweaks ...func(kmstc *keyManagementServiceTestCase)) *keyManagementServiceTestCase {
@@ -120,16 +109,16 @@ func TestAlibabaKMSGetSecret(t *testing.T) {
 	// good case: default version is set
 	// key is passed in, output is sent back
 	setSecretString := func(kmstc *keyManagementServiceTestCase) {
-		kmstc.apiOutput.SecretName = secretName
-		kmstc.apiOutput.SecretData = secretValue
+		kmstc.apiOutput.SecretName = utils.Ptr(secretName)
+		kmstc.apiOutput.SecretData = utils.Ptr(secretValue)
 		kmstc.expectedSecret = secretValue
 	}
 
 	// good case: custom version set
 	setCustomKey := func(kmstc *keyManagementServiceTestCase) {
-		kmstc.apiOutput.SecretName = "test-example-other"
+		kmstc.apiOutput.SecretName = utils.Ptr("test-example-other")
 		kmstc.ref.Key = "test-example-other"
-		kmstc.apiOutput.SecretData = secretValue
+		kmstc.apiOutput.SecretData = utils.Ptr(secretValue)
 		kmstc.expectedSecret = secretValue
 	}
 
@@ -156,14 +145,14 @@ func TestAlibabaKMSGetSecret(t *testing.T) {
 func TestGetSecretMap(t *testing.T) {
 	// good case: default version & deserialization
 	setDeserialization := func(kmstc *keyManagementServiceTestCase) {
-		kmstc.apiOutput.SecretName = "foo"
+		kmstc.apiOutput.SecretName = utils.Ptr("foo")
 		kmstc.expectedData["foo"] = []byte("bar")
-		kmstc.apiOutput.SecretData = `{"foo":"bar"}`
+		kmstc.apiOutput.SecretData = utils.Ptr(`{"foo":"bar"}`)
 	}
 
 	// bad case: invalid json
 	setInvalidJSON := func(kmstc *keyManagementServiceTestCase) {
-		kmstc.apiOutput.SecretData = "-----------------"
+		kmstc.apiOutput.SecretData = utils.Ptr("-----------------")
 		kmstc.expectError = "unable to unmarshal secret"
 	}
 
@@ -187,7 +176,7 @@ func TestGetSecretMap(t *testing.T) {
 	}
 }
 
-func TestValidateStore(t *testing.T) {
+func TestValidateAccessKeyStore(t *testing.T) {
 	kms := KeyManagementService{}
 
 	store := &esv1beta1.SecretStore{
@@ -195,8 +184,8 @@ func TestValidateStore(t *testing.T) {
 			Provider: &esv1beta1.SecretStoreProvider{
 				Alibaba: &esv1beta1.AlibabaProvider{
 					RegionID: "region-1",
-					Auth: &esv1beta1.AlibabaAuth{
-						SecretRef: esv1beta1.AlibabaAuthSecretRef{
+					Auth: esv1beta1.AlibabaAuth{
+						SecretRef: &esv1beta1.AlibabaAuthSecretRef{
 							AccessKeyID: esmeta.SecretKeySelector{
 								Name: "accessKeyID",
 								Key:  "key-1",
@@ -218,6 +207,33 @@ func TestValidateStore(t *testing.T) {
 	}
 }
 
+func TestValidateRRSAStore(t *testing.T) {
+	kms := KeyManagementService{}
+
+	store := &esv1beta1.SecretStore{
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Alibaba: &esv1beta1.AlibabaProvider{
+					RegionID: "region-1",
+					Auth: esv1beta1.AlibabaAuth{
+						RRSAAuth: &esv1beta1.AlibabaRRSAAuth{
+							OIDCProviderARN:   "acs:ram::1234:oidc-provider/ack-rrsa-ce123456",
+							OIDCTokenFilePath: "/var/run/secrets/tokens/oidc-token",
+							RoleARN:           "acs:ram::1234:role/test-role",
+							SessionName:       "secrets",
+						},
+					},
+				},
+			},
+		},
+	}
+
+	err := kms.ValidateStore(store)
+	if err != nil {
+		t.Errorf(err.Error())
+	}
+}
+
 func ErrorContains(out error, want string) bool {
 	if out == nil {
 		return want == ""

+ 82 - 0
pkg/provider/alibaba/logger.go

@@ -0,0 +1,82 @@
+/*
+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 alibaba
+
+import (
+	"github.com/go-logr/logr"
+	"github.com/hashicorp/go-retryablehttp"
+	ctrl "sigs.k8s.io/controller-runtime"
+)
+
+var log = newLogger()
+
+type logLevel int
+
+const (
+	logLevelWarn  logLevel = iota
+	logLevelInfo  logLevel = iota
+	logLevelDebug logLevel = iota
+)
+
+type logger struct {
+	logr.Logger
+}
+
+func (l logLevel) Level() int {
+	return int(l)
+}
+
+func newLogger() *logger {
+	return &logger{
+		Logger: ctrl.Log.WithName("provider").WithName("alibaba").WithName("kms"),
+	}
+}
+
+var _ retryablehttp.LeveledLogger = (*logger)(nil)
+var _ retryablehttp.Logger = (*logger)(nil)
+
+func (l *logger) WithField(key string, value interface{}) *logger {
+	return l.WithFields(key, value)
+}
+
+func (l *logger) WithError(err error) *logger {
+	return l.WithFields("error", err)
+}
+
+func (l *logger) WithFields(keysAndValues ...interface{}) *logger {
+	newLogger := *l
+	newLogger.Logger = l.Logger.WithValues(keysAndValues...)
+	return &newLogger
+}
+
+func (l *logger) Error(msg string, keysAndValues ...interface{}) {
+	l.Logger.Error(nil, msg, keysAndValues...)
+}
+
+func (l *logger) Info(msg string, keysAndValues ...interface{}) {
+	l.Logger.V(logLevelInfo.Level()).Info(msg, keysAndValues...)
+}
+
+func (l *logger) Debug(msg string, keysAndValues ...interface{}) {
+	l.Logger.V(logLevelDebug.Level()).Info(msg, keysAndValues...)
+}
+
+func (l *logger) Warn(msg string, keysAndValues ...interface{}) {
+	l.Logger.V(logLevelWarn.Level()).Info(msg, keysAndValues...)
+}
+
+func (l *logger) Printf(msg string, keysAndValues ...interface{}) {
+	l.Logger.Info(msg, keysAndValues...)
+}

+ 37 - 0
pkg/provider/alibaba/utils.go

@@ -0,0 +1,37 @@
+/*
+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 alibaba
+
+import (
+	"errors"
+	"regexp"
+)
+
+var regexReqIDs = []*regexp.Regexp{
+	regexp.MustCompile(`request id: (\S+)`),
+	regexp.MustCompile(`"RequestId":"(\S+)",`),
+}
+
+// SanitizeErr sanitizes the error string
+// because the requestID must not be included in the error.
+// otherwise the secrets keeps syncing.
+func SanitizeErr(err error) error {
+	msg := ""
+	for _, regex := range regexReqIDs {
+		msg = string(regex.ReplaceAll([]byte(err.Error()), nil))
+	}
+
+	return errors.New(msg)
+}

+ 29 - 0
pkg/utils/utils.go

@@ -17,6 +17,7 @@ package utils
 import (
 	"crypto/md5" //nolint:gosec
 	"encoding/base64"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"net"
@@ -283,3 +284,31 @@ func NetworkValidate(endpoint string, timeout time.Duration) error {
 	defer conn.Close()
 	return nil
 }
+
+func Deref[V any](v *V) V {
+	if v == nil {
+		// Create zero value
+		var res V
+		return res
+	}
+	return *v
+}
+
+func Ptr[T any](i T) *T {
+	return &i
+}
+
+func ConvertToType[T any](obj interface{}) (T, error) {
+	var v T
+
+	data, err := json.Marshal(obj)
+	if err != nil {
+		return v, fmt.Errorf("failed to marshal object: %w", err)
+	}
+
+	if err = json.Unmarshal(data, &v); err != nil {
+		return v, fmt.Errorf("failed to unmarshal object: %w", err)
+	}
+
+	return v, nil
+}