Browse Source

:sparkles: Add CABundle/CAProvider to Akeyless provider (#2092)

* support adding CA Cert in Akeyless provider

Signed-off-by: Docs <renana@akeyless.io>

* update akeyless-go to v3

Signed-off-by: Docs <renana@akeyless.io>

* update description

Signed-off-by: Docs <renana@akeyless.io>

* update description

Signed-off-by: Docs <renana@akeyless.io>

* update description

Signed-off-by: Docs <renana@akeyless.io>

* update description

Signed-off-by: Docs <renana@akeyless.io>

* fix comments

Signed-off-by: Docs <renana@akeyless.io>

---------

Signed-off-by: Docs <renana@akeyless.io>
renanaAkeyless 3 years ago
parent
commit
7e5fbb124b

+ 10 - 0
apis/externalsecrets/v1alpha1/secretstore_akeyless_types.go

@@ -26,6 +26,16 @@ type AkeylessProvider struct {
 
 	// 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 *CAProvider `json:"caProvider,omitempty"`
 }
 
 type AkeylessAuth struct {

+ 10 - 0
apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go

@@ -180,6 +180,16 @@ func (in *AkeylessProvider) DeepCopyInto(out *AkeylessProvider) {
 		*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(CAProvider)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AkeylessProvider.

+ 10 - 0
apis/externalsecrets/v1beta1/secretstore_akeyless_types.go

@@ -26,6 +26,16 @@ type AkeylessProvider struct {
 
 	// 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 *CAProvider `json:"caProvider,omitempty"`
 }
 
 type AkeylessAuth struct {

+ 10 - 0
apis/externalsecrets/v1beta1/zz_generated.deepcopy.go

@@ -190,6 +190,16 @@ func (in *AkeylessProvider) DeepCopyInto(out *AkeylessProvider) {
 		*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(CAProvider)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AkeylessProvider.

+ 67 - 0
config/crds/bases/external-secrets.io_clustersecretstores.yaml

@@ -210,6 +210,39 @@ spec:
                                 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 the value inside of the provider
+                              type to use, only used with "Secret" type
+                            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.
+                            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
                     required:
                     - akeylessGWApiURL
                     - authSecretRef
@@ -1762,6 +1795,40 @@ spec:
                                 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
                     required:
                     - akeylessGWApiURL
                     - authSecretRef

+ 67 - 0
config/crds/bases/external-secrets.io_secretstores.yaml

@@ -210,6 +210,39 @@ spec:
                                 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 the value inside of the provider
+                              type to use, only used with "Secret" type
+                            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.
+                            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
                     required:
                     - akeylessGWApiURL
                     - authSecretRef
@@ -1762,6 +1795,40 @@ spec:
                                 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
                     required:
                     - akeylessGWApiURL
                     - authSecretRef

+ 104 - 0
deploy/crds/bundle.yaml

@@ -600,6 +600,32 @@ spec:
                                   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 the value inside of the provider type to use, only used with "Secret" type
+                              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.
+                              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
                       required:
                         - akeylessGWApiURL
                         - authSecretRef
@@ -1723,6 +1749,32 @@ spec:
                                   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
                       required:
                         - akeylessGWApiURL
                         - authSecretRef
@@ -3915,6 +3967,32 @@ spec:
                                   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 the value inside of the provider type to use, only used with "Secret" type
+                              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.
+                              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
                       required:
                         - akeylessGWApiURL
                         - authSecretRef
@@ -5038,6 +5116,32 @@ spec:
                                   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
                       required:
                         - akeylessGWApiURL
                         - authSecretRef

+ 29 - 0
docs/api/spec.md

@@ -479,6 +479,34 @@ AkeylessAuth
 <p>Auth configures how the operator authenticates with Akeyless.</p>
 </td>
 </tr>
+<tr>
+<td>
+<code>caBundle</code></br>
+<em>
+[]byte
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>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.</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>caProvider</code></br>
+<em>
+<a href="#external-secrets.io/v1beta1.CAProvider">
+CAProvider
+</a>
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>The provider for the CA bundle to use to validate Akeyless Gateway certificate.</p>
+</td>
+</tr>
 </tbody>
 </table>
 <h3 id="external-secrets.io/v1beta1.AlibabaAuth">AlibabaAuth
@@ -836,6 +864,7 @@ string
 </h3>
 <p>
 (<em>Appears on:</em>
+<a href="#external-secrets.io/v1beta1.AkeylessProvider">AkeylessProvider</a>, 
 <a href="#external-secrets.io/v1beta1.KubernetesServer">KubernetesServer</a>, 
 <a href="#external-secrets.io/v1beta1.VaultProvider">VaultProvider</a>)
 </p>

+ 2 - 2
docs/introduction/stability-support.md

@@ -45,7 +45,7 @@ The following table describes the stability level of each provider and who's res
 The following table show the support for features across different providers.
 
 | Provider                  | find by name | find by tags | metadataPolicy Fetch | referent authentication | store validation | push secret | DeletionPolicy Merge/Delete |
-|---------------------------|:------------:|:------------:| :------------------: | :---------------------: | :--------------: | :---------: | :-------------------------: 
+|---------------------------|:------------:|:------------:| :------------------: | :---------------------: | :--------------: | :---------: | :-------------------------:
 | AWS Secrets Manager       |      x       |      x       |                      |            x            |        x         |     x       |            x                |
 | AWS Parameter Store       |      x       |      x       |                      |            x            |        x         |     x       |            x                |
 | Hashicorp Vault           |      x       |      x       |                      |            x            |        x         |     x       |            x                |
@@ -57,7 +57,7 @@ The following table show the support for features across different providers.
 | Gitlab Variables          |      x       |      x       |                      |                         |        x         |             |                             |
 | Alibaba Cloud KMS         |              |              |                      |                         |        x         |             |                             |
 | Oracle Vault              |              |              |                      |                         |        x         |             |                             |
-| Akeyless                  |              |              |                      |                         |        x         |             |                             |
+| Akeyless                  |      x       |      x       |                      |                         |        x         |             |                             |
 | 1Password                 |      x       |              |                      |                         |        x         |             |                             |
 | Generic Webhook           |              |              |                      |                         |                  |             |            x                |
 | senhasegura DSM           |              |              |                      |                         |        x         |             |                             |

+ 54 - 25
docs/provider/akeyless.md

@@ -1,24 +1,46 @@
-## Akeyless Vault
+## Akeyless Secrets Management Platform
 
-External Secrets Operator integrates with the [Akeyless API](https://docs.akeyless.io/reference#v2).
+External Secrets Operator integrates with the [Akeyless Secrets Management Platform](https://www.akeyless.io/).
+### Create Secret Store:
+SecretStore resource specifies how to access Akeyless. This resource is namespaced.
 
-### Authentication
+**NOTE:** Make sure the Akeyless provider is listed in the Kind=SecretStore.
+If you use a customer fragment, define the value of akeylessGWApiURL as the URL of your Akeyless Gateway in the following format: https://your.akeyless.gw:8080/v2.
 
-To operate the API first define an access-id, access-type and access-Type-param.
+Akeyelss provide several Authentication Methods:
+
+### Authentication with Kubernetes:
+
+Options for obtaining Kubernetes credentials include:
+
+1. Using a service account jwt referenced in serviceAccountRef
+2. Using the jwt from a Kind=Secret referenced by the secretRef
+3. Using transient credentials from the mounted service account token within the external-secrets operator
+
+#### Create the Akeyless Secret Store Provider with Kubernetes Auth-Method
+```yaml
+{% include 'akeyless-secret-store-k8s-auth.yaml' %}
+```
+**NOTE:** In case of a `ClusterSecretStore`, Be sure to provide `namespace` for `serviceAccountRef` and `secretRef` according to  the namespaces where the secrets reside.
+
+
+### Authentication With Cloud-Identity or Api-Access-Key
+
+Akeyless providers require an access-id, access-type and access-Type-param
+To set your SecretStore with an authentication method from Akeyless.
 
 The supported auth-methods and their parameters are:
 
 | accessType  | accessTypeParam                                                                                                                                                                                                                      |
 | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `api_key`      | The access key.                                                                                                                                     |
-| `k8s`         | The k8s configuration name |
 | `aws_iam` |   -                                                         |
 | `gcp` |      The gcp audience                                                      |
 | `azure_ad` |  azure object id  (optional)                                                          |
-
+| `api_key`      | The access key.                                                                                                                                     |
+| `k8s`         | The k8s configuration name |
 For more information see [Akeyless Authentication Methods](https://docs.akeyless.io/docs/access-and-authentication-methods)
 
-### Creating an Akeyless Ccredentials Secret
+#### Creating an Akeyless Credentials Secret
 
 Create a secret containing your credentials using the following example as a guide:
 
@@ -30,31 +52,38 @@ metadata:
 type: Opaque
 stringData:
   accessId: "p-XXXX"
-  accessType:  # k8s/aws_iam/gcp/azure_ad/api_key
-  accessTypeParam:  # can be one of the following: k8s-conf-name/gcp-audience/azure-obj-id/access-key
+  accessType:  # gcp/azure_ad/api_key/k8s/aws_iam
+  accessTypeParam:  # optional: can be one of the following: gcp-audience/azure-obj-id/access-key/k8s-conf-name
 ```
 
-### Update Secret Store
-Be sure the `akeyless` provider is listed in the `Kind=SecretStore` and the `akeylessGWApiURL` is set (def: "https://api.akeless.io").
+#### Create the Akeyless Secret Store Provider with the Credentials Secret
 
 ```yaml
 {% include 'akeyless-secret-store.yaml' %}
 ```
 **NOTE:** In case of a `ClusterSecretStore`, be sure to provide `namespace` for `accessID`, `accessType` and `accessTypeParam`  according to the namespaces where the secrets reside.
 
-### Authentication with Kubernetes
-
-Options for obtaining Kubernetes credentials include:
-
-1. Using a service account jwt referenced in serviceAccountRef
-2. Using the jwt from a Kind=Secret referenced by the secretRef
-3. Using transient credentials from the mounted service account token within the external-secrets operator
-
+#### Create the Akeyless Secret Store With CAs for TLS handshake
 ```yaml
-{% include 'akeyless-secret-store-k8s-auth.yaml' %}
+....
+spec:
+  provider:
+    akeyless:
+      akeylessGWApiURL: "https://your.akeyless.gw:8080/v2"
+
+      # Optional caBundle - PEM/base64 encoded CA certificate
+      caBundle: "<base64 encoded cabundle>"
+      # Optional caProvider:
+      # Instead of caBundle you can also specify a caProvider
+      # this will retrieve the cert from a Secret or ConfigMap
+      caProvider:
+        type: "Secret/ConfigMap" # Can be Secret or ConfigMap
+        name: "<name of secret or configmap>"
+        key: "<key inside secret>"
+        # namespace is mandatory for ClusterSecretStore and not relevant for SecretStore
+        namespace: "my-cert-secret-namespace"
+  ....
 ```
-**NOTE:** In case of a `ClusterSecretStore`, Be sure to provide `namespace` for `serviceAccountRef` and `secretRef` according to  the namespaces where the secrets reside.
-
 
 ### Creating an external secret
 
@@ -76,9 +105,9 @@ DataFrom can be used to get a secret as a JSON string and attempt to parse it.
 ### Getting the Kubernetes Secret
 The operator will fetch the secret and inject it as a `Kind=Secret`.
 ```
-kubectl get secret akeyless-secret-to-create -o jsonpath='{.data.secretKey}' | base64 -d
+kubectl get secret database-credentials -o jsonpath='{.data.db-password}' | base64 -d
 ```
 
 ```
-kubectl get secret akeyless-secret-to-create-json -o jsonpath='{.data}'
+kubectl get secret database-credentials-json -o jsonpath='{.data}'
 ```

+ 1 - 1
docs/snippets/akeyless-external-secret-json.yaml

@@ -10,7 +10,7 @@ spec:
     name: akeyless-secret-store # Must match SecretStore on the cluster
 
   target:
-    name: database-credentials # Name for the secret to be created on the cluster
+    name: database-credentials-json # Name for the secret to be created on the cluster
     creationPolicy: Owner
 
   # for json formatted secrets: each key in the json will be used as the secret key in the SECRET k8s target object

+ 1 - 1
docs/snippets/full-cluster-secret-store.yaml

@@ -53,7 +53,7 @@ spec:
       caProvider:
         # Can be Secret or ConfigMap
         type: "Secret"
-        # This is mandatory for ClusterSecretStore and not relevant for SecretStore
+        # namespace is mandatory for ClusterSecretStore and not relevant for SecretStore
         namespace: "my-cert-secret-namespace"
         name: "my-cert-secret"
         key: "cert-key"

+ 1 - 1
e2e/go.mod

@@ -42,7 +42,7 @@ require (
 	github.com/Azure/azure-sdk-for-go v68.0.0+incompatible
 	github.com/Azure/go-autorest/autorest/azure/auth v0.5.12
 	github.com/akeylesslabs/akeyless-go-cloud-id v0.3.4
-	github.com/akeylesslabs/akeyless-go/v2 v2.20.3
+	github.com/akeylesslabs/akeyless-go/v3 v3.2.6
 	github.com/aliyun/alibaba-cloud-sdk-go v1.62.217
 	github.com/argoproj/argo-cd/v2 v2.4.8
 	github.com/aws/aws-sdk-go v1.44.214

+ 2 - 2
e2e/go.sum

@@ -115,8 +115,8 @@ github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia
 github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
 github.com/akeylesslabs/akeyless-go-cloud-id v0.3.4 h1:vTckjyBhHOBiOWSC/oaEU2Oo4OH5eAlQiwKu2RMxsFg=
 github.com/akeylesslabs/akeyless-go-cloud-id v0.3.4/go.mod h1:As/RomC2w/fa3y+yHRlVHPmkbP+zrKBFRow41y5dk+E=
-github.com/akeylesslabs/akeyless-go/v2 v2.20.3 h1:NIRMynmpQbfgQyRLf5DMQC8p5iLgaUu1MXBB4ijLCxM=
-github.com/akeylesslabs/akeyless-go/v2 v2.20.3/go.mod h1:uOdXD49NCCe4rexeSc2aBU5Qv4KZgJE6YlbtYalvb+I=
+github.com/akeylesslabs/akeyless-go/v3 v3.2.6 h1:7Z5m/oANHvRWKKWhOuTNX26OalNX20qSqxR7qVyOcLU=
+github.com/akeylesslabs/akeyless-go/v3 v3.2.6/go.mod h1:XtPdOYw+rrG9bxyBzuQ5zAGCUTd364R2grs7GsZ5nos=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=

+ 1 - 1
e2e/suites/provider/cases/akeyless/provider.go

@@ -26,7 +26,7 @@ import (
 	aws_cloud_id "github.com/akeylesslabs/akeyless-go-cloud-id/cloudprovider/aws"
 	azure_cloud_id "github.com/akeylesslabs/akeyless-go-cloud-id/cloudprovider/azure"
 	gcp_cloud_id "github.com/akeylesslabs/akeyless-go-cloud-id/cloudprovider/gcp"
-	"github.com/akeylesslabs/akeyless-go/v2"
+	"github.com/akeylesslabs/akeyless-go/v3"
 
 	//nolint
 	. "github.com/onsi/ginkgo/v2"

+ 1 - 1
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/akeylesslabs/akeyless-go/v2 v2.20.3
 	github.com/aliyun/alibaba-cloud-sdk-go v1.62.217
 	github.com/aws/aws-sdk-go v1.44.214
 	github.com/go-logr/logr v1.2.3
@@ -65,6 +64,7 @@ require github.com/1Password/connect-sdk-go v1.5.0
 require (
 	github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0
 	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.1
+	github.com/akeylesslabs/akeyless-go/v3 v3.2.6
 	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

+ 2 - 2
go.sum

@@ -110,8 +110,8 @@ github.com/ahmetb/gen-crd-api-reference-docs v0.3.0/go.mod h1:TdjdkYhlOifCQWPs1U
 github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
 github.com/akeylesslabs/akeyless-go-cloud-id v0.3.4 h1:vTckjyBhHOBiOWSC/oaEU2Oo4OH5eAlQiwKu2RMxsFg=
 github.com/akeylesslabs/akeyless-go-cloud-id v0.3.4/go.mod h1:As/RomC2w/fa3y+yHRlVHPmkbP+zrKBFRow41y5dk+E=
-github.com/akeylesslabs/akeyless-go/v2 v2.20.3 h1:NIRMynmpQbfgQyRLf5DMQC8p5iLgaUu1MXBB4ijLCxM=
-github.com/akeylesslabs/akeyless-go/v2 v2.20.3/go.mod h1:uOdXD49NCCe4rexeSc2aBU5Qv4KZgJE6YlbtYalvb+I=
+github.com/akeylesslabs/akeyless-go/v3 v3.2.6 h1:7Z5m/oANHvRWKKWhOuTNX26OalNX20qSqxR7qVyOcLU=
+github.com/akeylesslabs/akeyless-go/v3 v3.2.6/go.mod h1:XtPdOYw+rrG9bxyBzuQ5zAGCUTd364R2grs7GsZ5nos=
 github.com/aliyun/alibaba-cloud-sdk-go v1.62.217 h1:YZPv3FMTEP9s5u547eY3E+7s8FothzjWvITtqwhljSE=
 github.com/aliyun/alibaba-cloud-sdk-go v1.62.217/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=

+ 210 - 6
pkg/provider/akeyless/akeyless.go

@@ -16,19 +16,27 @@ package akeyless
 
 import (
 	"context"
+	"crypto/tls"
+	"crypto/x509"
 	"encoding/json"
+	"errors"
 	"fmt"
+	"net/http"
 	"net/url"
 	"strconv"
+	"strings"
 	"time"
 
-	"github.com/akeylesslabs/akeyless-go/v2"
+	"github.com/akeylesslabs/akeyless-go/v3"
+	corev1 "k8s.io/api/core/v1"
 	"k8s.io/client-go/kubernetes"
 	typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	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/find"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
@@ -47,6 +55,7 @@ type Provider struct{}
 type akeylessBase struct {
 	kube      client.Client
 	store     esv1beta1.GenericStore
+	storeKind string
 	corev1    typedcorev1.CoreV1Interface
 	namespace string
 
@@ -60,8 +69,9 @@ type Akeyless struct {
 }
 
 type akeylessVaultInterface interface {
-	GetSecretByType(secretName, token string, version int32) (string, error)
+	GetSecretByType(ctx context.Context, secretName, token string, version int32) (string, error)
 	TokenFromSecretRef(ctx context.Context) (string, error)
+	ListSecrets(ctx context.Context, path, tag, token string) ([]string, error)
 }
 
 func init() {
@@ -166,6 +176,7 @@ func newClient(_ context.Context, store esv1beta1.GenericStore, kube client.Clie
 		store:     store,
 		namespace: namespace,
 		corev1:    corev1,
+		storeKind: store.GetObjectKind().GroupVersionKind().Kind,
 	}
 
 	spec, err := GetAKeylessProvider(store)
@@ -181,7 +192,13 @@ func newClient(_ context.Context, store esv1beta1.GenericStore, kube client.Clie
 		return nil, fmt.Errorf("missing Auth in store config")
 	}
 
+	client, err := akl.getAkeylessHTTPClient(spec)
+	if err != nil {
+		return nil, err
+	}
+
 	RestAPIClient := akeyless.NewAPIClient(&akeyless.Configuration{
+		HTTPClient: client,
 		Servers: []akeyless.ServerConfiguration{
 			{
 				URL: akeylessGwAPIURL,
@@ -235,17 +252,98 @@ func (a *Akeyless) GetSecret(ctx context.Context, ref esv1beta1.ExternalSecretDa
 			version = int32(i)
 		}
 	}
-	value, err := a.Client.GetSecretByType(ref.Key, token, version)
+	value, err := a.Client.GetSecretByType(ctx, ref.Key, token, version)
 	if err != nil {
 		return nil, err
 	}
 	return []byte(value), nil
 }
 
-// Empty GetAllSecrets.
+// Implements store.Client.GetAllSecrets Interface.
+// Retrieves a all secrets with defined in ref.Name or tags.
 func (a *Akeyless) GetAllSecrets(ctx context.Context, ref esv1beta1.ExternalSecretFind) (map[string][]byte, error) {
-	// TO be implemented
-	return nil, fmt.Errorf("GetAllSecrets not implemented")
+	if utils.IsNil(a.Client) {
+		return nil, fmt.Errorf(errUninitalizedAkeylessProvider)
+	}
+
+	searchPath := ""
+	if ref.Path != nil {
+		searchPath = *ref.Path
+		if !strings.HasPrefix(searchPath, "/") {
+			searchPath = "/" + searchPath
+		}
+		if !strings.HasSuffix(searchPath, "/") {
+			searchPath += "/"
+		}
+	}
+	token, err := a.Client.TokenFromSecretRef(ctx)
+	if err != nil {
+		return nil, err
+	}
+
+	if ref.Name != nil {
+		potentialSecrets, err := a.Client.ListSecrets(ctx, searchPath, "", token)
+		if err != nil {
+			return nil, err
+		}
+		if len(potentialSecrets) == 0 {
+			return nil, nil
+		}
+		return a.findSecretsFromName(ctx, potentialSecrets, *ref.Name, token)
+	}
+	if len(ref.Tags) > 0 {
+		var potentialSecretsName []string
+		for _, v := range ref.Tags {
+			potentialSecrets, err := a.Client.ListSecrets(ctx, searchPath, v, token)
+			if err != nil {
+				return nil, err
+			}
+			if len(potentialSecrets) > 0 {
+				potentialSecretsName = append(potentialSecretsName, potentialSecrets...)
+			}
+		}
+		if len(potentialSecretsName) == 0 {
+			return nil, nil
+		}
+		return a.getSecrets(ctx, potentialSecretsName, token)
+	}
+
+	return nil, errors.New("unexpected find operator")
+}
+
+func (a *Akeyless) getSecrets(ctx context.Context, candidates []string, token string) (map[string][]byte, error) {
+	secrets := make(map[string][]byte)
+	for _, name := range candidates {
+		secretValue, err := a.Client.GetSecretByType(ctx, name, token, 0)
+		if err != nil {
+			return nil, err
+		}
+		if secretValue != "" {
+			secrets[name] = []byte(secretValue)
+		}
+	}
+	return secrets, nil
+}
+
+func (a *Akeyless) findSecretsFromName(ctx context.Context, candidates []string, ref esv1beta1.FindName, token string) (map[string][]byte, error) {
+	secrets := make(map[string][]byte)
+	matcher, err := find.New(ref)
+	if err != nil {
+		return nil, err
+	}
+	for _, name := range candidates {
+		ok := matcher.MatchName(name)
+		if ok {
+			secretValue, err := a.Client.GetSecretByType(ctx, name, token, 0)
+			if err != nil {
+				return nil, err
+			}
+			if secretValue != "" {
+				secrets[name] = []byte(secretValue)
+			}
+		}
+	}
+	return secrets, nil
 }
 
 // Implements store.Client.GetSecretMap Interface.
@@ -273,3 +371,109 @@ func (a *Akeyless) GetSecretMap(ctx context.Context, ref esv1beta1.ExternalSecre
 	}
 	return secretData, nil
 }
+
+func (a *akeylessBase) getAkeylessHTTPClient(provider *esv1beta1.AkeylessProvider) (*http.Client, error) {
+	client := &http.Client{Timeout: 30 * time.Second}
+	if len(provider.CABundle) == 0 && provider.CAProvider == nil {
+		return client, nil
+	}
+	caCertPool, err := a.getCACertPool(provider)
+	if err != nil {
+		return nil, err
+	}
+
+	tlsConf := &tls.Config{
+		RootCAs:    caCertPool,
+		MinVersion: tls.VersionTLS12,
+	}
+	client.Transport = &http.Transport{TLSClientConfig: tlsConf}
+	return client, nil
+}
+
+func (a *akeylessBase) getCACertPool(provider *esv1beta1.AkeylessProvider) (*x509.CertPool, error) {
+	caCertPool := x509.NewCertPool()
+	if len(provider.CABundle) > 0 {
+		pem, err := base64decode(provider.CABundle)
+		if err != nil {
+			pem = provider.CABundle
+		}
+		ok := caCertPool.AppendCertsFromPEM(pem)
+		if !ok {
+			return nil, fmt.Errorf("failed to append cabundle")
+		}
+	}
+
+	if provider.CAProvider != nil && a.storeKind == esv1beta1.ClusterSecretStoreKind && provider.CAProvider.Namespace == nil {
+		return nil, fmt.Errorf("missing namespace on CAProvider secret")
+	}
+
+	if provider.CAProvider != nil {
+		var cert []byte
+		var err error
+
+		switch provider.CAProvider.Type {
+		case esv1beta1.CAProviderTypeSecret:
+			cert, err = a.getCertFromSecret(provider)
+		case esv1beta1.CAProviderTypeConfigMap:
+			cert, err = a.getCertFromConfigMap(provider)
+		default:
+			err = fmt.Errorf("unknown caprovider type: %s", provider.CAProvider.Type)
+		}
+
+		if err != nil {
+			return nil, err
+		}
+		pem, err := base64decode(cert)
+		if err != nil {
+			pem = cert
+		}
+		ok := caCertPool.AppendCertsFromPEM(pem)
+		if !ok {
+			return nil, fmt.Errorf("failed to append cabundle")
+		}
+	}
+	return caCertPool, nil
+}
+
+func (a *akeylessBase) getCertFromSecret(provider *esv1beta1.AkeylessProvider) ([]byte, error) {
+	secretRef := esmeta.SecretKeySelector{
+		Name: provider.CAProvider.Name,
+		Key:  provider.CAProvider.Key,
+	}
+
+	if provider.CAProvider.Namespace != nil {
+		secretRef.Namespace = provider.CAProvider.Namespace
+	}
+
+	ctx := context.Background()
+	res, err := a.secretKeyRef(ctx, &secretRef)
+	if err != nil {
+		return nil, err
+	}
+
+	return []byte(res), nil
+}
+
+func (a *akeylessBase) getCertFromConfigMap(provider *esv1beta1.AkeylessProvider) ([]byte, error) {
+	objKey := client.ObjectKey{
+		Name: provider.CAProvider.Name,
+	}
+
+	if provider.CAProvider.Namespace != nil {
+		objKey.Namespace = *provider.CAProvider.Namespace
+	}
+
+	configMapRef := &corev1.ConfigMap{}
+	ctx := context.Background()
+	err := a.kube.Get(ctx, objKey, configMapRef)
+	if err != nil {
+		return nil, fmt.Errorf("failed to get caprovider secret %s: %w", objKey.Name, err)
+	}
+
+	val, ok := configMapRef.Data[provider.CAProvider.Key]
+	if !ok {
+		return nil, fmt.Errorf("failed to get caprovider configmap %s -> %s", objKey.Name, provider.CAProvider.Key)
+	}
+
+	return []byte(val), nil
+}

+ 80 - 46
pkg/provider/akeyless/akeyless_api.go

@@ -27,7 +27,7 @@ import (
 	aws_cloud_id "github.com/akeylesslabs/akeyless-go-cloud-id/cloudprovider/aws"
 	azure_cloud_id "github.com/akeylesslabs/akeyless-go-cloud-id/cloudprovider/azure"
 	gcp_cloud_id "github.com/akeylesslabs/akeyless-go-cloud-id/cloudprovider/gcp"
-	"github.com/akeylesslabs/akeyless-go/v2"
+	"github.com/akeylesslabs/akeyless-go/v3"
 	authenticationv1 "k8s.io/api/authentication/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -79,8 +79,8 @@ func (a *akeylessBase) GetToken(accessID, accType, accTypeParam string, k8sAuth
 	return token, nil
 }
 
-func (a *akeylessBase) GetSecretByType(secretName, token string, version int32) (string, error) {
-	item, err := a.DescribeItem(secretName, token)
+func (a *akeylessBase) GetSecretByType(ctx context.Context, secretName, token string, version int32) (string, error) {
+	item, err := a.DescribeItem(ctx, secretName, token)
 	if err != nil {
 		return "", err
 	}
@@ -88,19 +88,17 @@ func (a *akeylessBase) GetSecretByType(secretName, token string, version int32)
 
 	switch secretType {
 	case "STATIC_SECRET":
-		return a.GetStaticSecret(secretName, token, version)
+		return a.GetStaticSecret(ctx, secretName, token, version)
 	case "DYNAMIC_SECRET":
-		return a.GetDynamicSecrets(secretName, token)
+		return a.GetDynamicSecrets(ctx, secretName, token)
 	case "ROTATED_SECRET":
-		return a.GetRotatedSecrets(secretName, token, version)
+		return a.GetRotatedSecrets(ctx, secretName, token, version)
 	default:
 		return "", fmt.Errorf("invalid item type: %v", secretType)
 	}
 }
 
-func (a *akeylessBase) DescribeItem(itemName, token string) (*akeyless.Item, error) {
-	ctx := context.Background()
-
+func (a *akeylessBase) DescribeItem(ctx context.Context, itemName, token string) (*akeyless.Item, error) {
 	body := akeyless.DescribeItem{
 		Name: itemName,
 	}
@@ -116,14 +114,12 @@ func (a *akeylessBase) DescribeItem(itemName, token string) (*akeyless.Item, err
 		}
 		return nil, fmt.Errorf("can't describe item: %w", err)
 	}
-	res.Body.Close()
+	defer res.Body.Close()
 
 	return &gsvOut, nil
 }
 
-func (a *akeylessBase) GetRotatedSecrets(secretName, token string, version int32) (string, error) {
-	ctx := context.Background()
-
+func (a *akeylessBase) GetRotatedSecrets(ctx context.Context, secretName, token string, version int32) (string, error) {
 	body := akeyless.GetRotatedSecretValue{
 		Names:   secretName,
 		Version: &version,
@@ -141,7 +137,7 @@ func (a *akeylessBase) GetRotatedSecrets(secretName, token string, version int32
 		}
 		return "", fmt.Errorf("can't get rotated secret value: %w", err)
 	}
-	res.Body.Close()
+	defer res.Body.Close()
 
 	valI, ok := gsvOut["value"]
 	if ok {
@@ -172,9 +168,7 @@ func (a *akeylessBase) GetRotatedSecrets(secretName, token string, version int32
 	return string(out), nil
 }
 
-func (a *akeylessBase) GetDynamicSecrets(secretName, token string) (string, error) {
-	ctx := context.Background()
-
+func (a *akeylessBase) GetDynamicSecrets(ctx context.Context, secretName, token string) (string, error) {
 	body := akeyless.GetDynamicSecretValue{
 		Name: secretName,
 	}
@@ -191,7 +185,7 @@ func (a *akeylessBase) GetDynamicSecrets(secretName, token string) (string, erro
 		}
 		return "", fmt.Errorf("can't get dynamic secret value: %w", err)
 	}
-	res.Body.Close()
+	defer res.Body.Close()
 
 	out, err := json.Marshal(gsvOut)
 	if err != nil {
@@ -201,9 +195,7 @@ func (a *akeylessBase) GetDynamicSecrets(secretName, token string) (string, erro
 	return string(out), nil
 }
 
-func (a *akeylessBase) GetStaticSecret(secretName, token string, version int32) (string, error) {
-	ctx := context.Background()
-
+func (a *akeylessBase) GetStaticSecret(ctx context.Context, secretName, token string, version int32) (string, error) {
 	gsvBody := akeyless.GetSecretValue{
 		Names:   []string{secretName},
 		Version: &version,
@@ -222,7 +214,7 @@ func (a *akeylessBase) GetStaticSecret(secretName, token string, version int32)
 		}
 		return "", fmt.Errorf("can't get secret value: %w", err)
 	}
-	res.Body.Close()
+	defer res.Body.Close()
 	val, ok := gsvOut[secretName]
 	if !ok {
 		return "", fmt.Errorf("can't get secret: %v", secretName)
@@ -248,30 +240,72 @@ func (a *akeylessBase) getCloudID(provider, accTypeParam string) (string, error)
 	return cloudID, err
 }
 
-func (a *akeylessBase) getK8SServiceAccountJWT(ctx context.Context, kubernetesAuth *esv1beta1.AkeylessKubernetesAuth) (string, error) {
-	if kubernetesAuth != nil && kubernetesAuth.ServiceAccountRef != nil {
-		// Kubernetes <v1.24 fetch token via ServiceAccount.Secrets[]
-		jwt, err := a.getJWTFromServiceAccount(ctx, kubernetesAuth.ServiceAccountRef)
-		if jwt != "" {
-			return jwt, err
-		}
-		// Kubernetes >=v1.24: fetch token via TokenRequest API
-		jwt, err = a.getJWTfromServiceAccountToken(ctx, *kubernetesAuth.ServiceAccountRef, nil, 600)
-		if err != nil {
-			return "", err
+func (a *akeylessBase) ListSecrets(ctx context.Context, path, tag, token string) ([]string, error) {
+	secretTypes := &[]string{"static-secret", "dynamic-secret", "rotated-secret"}
+	MinimalView := true
+	if tag != "" {
+		MinimalView = false
+	}
+	gsvBody := akeyless.ListItems{
+		Filter:      &path,
+		Type:        secretTypes,
+		MinimalView: &MinimalView,
+		Tag:         &tag,
+	}
+
+	if strings.HasPrefix(token, "u-") {
+		gsvBody.UidToken = &token
+	} else {
+		gsvBody.Token = &token
+	}
+
+	lipOut, res, err := a.RestAPI.ListItems(ctx).Body(gsvBody).Execute()
+	if err != nil {
+		if errors.As(err, &apiErr) {
+			return nil, fmt.Errorf("can't get secrets list: %v", string(apiErr.Body()))
 		}
-		return jwt, nil
-	} else if kubernetesAuth != nil && kubernetesAuth.SecretRef != nil {
-		tokenRef := kubernetesAuth.SecretRef
-		if tokenRef.Key == "" {
-			tokenRef = kubernetesAuth.SecretRef.DeepCopy()
-			tokenRef.Key = "token"
+		return nil, fmt.Errorf("error on get secrets list: %w", err)
+	}
+	defer res.Body.Close()
+	if lipOut.Items == nil {
+		return nil, nil
+	}
+
+	listNames := make([]string, 0)
+	for _, v := range *lipOut.Items {
+		if path == "" || strings.HasPrefix(*v.ItemName, path) {
+			listNames = append(listNames, *v.ItemName)
 		}
-		jwt, err := a.secretKeyRef(ctx, tokenRef)
-		if err != nil {
-			return "", err
+	}
+	return listNames, nil
+}
+
+func (a *akeylessBase) getK8SServiceAccountJWT(ctx context.Context, kubernetesAuth *esv1beta1.AkeylessKubernetesAuth) (string, error) {
+	if kubernetesAuth != nil {
+		if kubernetesAuth.ServiceAccountRef != nil {
+			// Kubernetes <v1.24 fetch token via ServiceAccount.Secrets[]
+			jwt, err := a.getJWTFromServiceAccount(ctx, kubernetesAuth.ServiceAccountRef)
+			if jwt != "" {
+				return jwt, err
+			}
+			// Kubernetes >=v1.24: fetch token via TokenRequest API
+			jwt, err = a.getJWTfromServiceAccountToken(ctx, *kubernetesAuth.ServiceAccountRef, nil, 600)
+			if err != nil {
+				return "", err
+			}
+			return jwt, nil
+		} else if kubernetesAuth.SecretRef != nil {
+			tokenRef := kubernetesAuth.SecretRef
+			if tokenRef.Key == "" {
+				tokenRef = kubernetesAuth.SecretRef.DeepCopy()
+				tokenRef.Key = "token"
+			}
+			jwt, err := a.secretKeyRef(ctx, tokenRef)
+			if err != nil {
+				return "", err
+			}
+			return jwt, nil
 		}
-		return jwt, nil
 	}
 	return readK8SServiceAccountJWT()
 }
@@ -282,7 +316,7 @@ func (a *akeylessBase) getJWTFromServiceAccount(ctx context.Context, serviceAcco
 		Namespace: a.namespace,
 		Name:      serviceAccountRef.Name,
 	}
-	if (a.store.GetObjectKind().GroupVersionKind().Kind == esv1beta1.ClusterSecretStoreKind) &&
+	if (a.storeKind == esv1beta1.ClusterSecretStoreKind) &&
 		(serviceAccountRef.Namespace != nil) {
 		ref.Namespace = *serviceAccountRef.Namespace
 	}
@@ -314,7 +348,7 @@ func (a *akeylessBase) secretKeyRef(ctx context.Context, secretRef *esmeta.Secre
 		Namespace: a.namespace,
 		Name:      secretRef.Name,
 	}
-	if (a.store.GetObjectKind().GroupVersionKind().Kind == esv1beta1.ClusterSecretStoreKind) &&
+	if (a.storeKind == esv1beta1.ClusterSecretStoreKind) &&
 		(secretRef.Namespace != nil) {
 		ref.Namespace = *secretRef.Namespace
 	}
@@ -347,7 +381,7 @@ func (a *akeylessBase) getJWTfromServiceAccountToken(ctx context.Context, servic
 			ExpirationSeconds: &expirationSeconds,
 		},
 	}
-	if (a.store.GetObjectKind().GroupVersionKind().Kind == esv1beta1.ClusterSecretStoreKind) &&
+	if (a.storeKind == esv1beta1.ClusterSecretStoreKind) &&
 		(serviceAccountRef.Namespace != nil) {
 		tokenRequest.Namespace = *serviceAccountRef.Namespace
 	}

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

@@ -25,10 +25,14 @@ func (mc *AkeylessMockClient) TokenFromSecretRef(ctx context.Context) (string, e
 	return "newToken", nil
 }
 
-func (mc *AkeylessMockClient) GetSecretByType(secretName, token string, version int32) (string, error) {
+func (mc *AkeylessMockClient) GetSecretByType(_ context.Context, secretName, token string, version int32) (string, error) {
 	return mc.getSecret(secretName, token, version)
 }
 
+func (mc *AkeylessMockClient) ListSecrets(ctx context.Context, path, tag, token string) ([]string, error) {
+	return nil, nil
+}
+
 func (mc *AkeylessMockClient) WithValue(in *Input, out *Output) {
 	if mc != nil {
 		mc.getSecret = func(secretName, token string, version int32) (string, error) {

+ 10 - 0
pkg/provider/akeyless/utils.go

@@ -14,6 +14,7 @@ limitations under the License.
 package akeyless
 
 import (
+	"encoding/base64"
 	"fmt"
 	"io"
 	"net/http"
@@ -107,3 +108,12 @@ func sendReq(url string) string {
 	body, _ := io.ReadAll(resp.Body)
 	return string(body)
 }
+
+func base64decode(in []byte) ([]byte, error) {
+	out := make([]byte, len(in))
+	l, err := base64.StdEncoding.Decode(out, in)
+	if err != nil {
+		return nil, err
+	}
+	return out[:l], nil
+}