Browse Source

fix!: Get rid of getSecretKey (#5738)

Co-authored-by: Gergely Brautigam <skarlso777@gmail.com>
Jean-Philippe Evrard 3 months ago
parent
commit
17d3e22b8d

+ 3 - 6
docs/guides/templating.md

@@ -138,10 +138,8 @@ In case you have a secret that contains a (partial) certificate chain you can ex
 
 
 ### RSA Decryption Data From Provider
 ### RSA Decryption Data From Provider
 
 
-When a provider returns RSA-encrypted values, you can decrypt them directly in the template using the `getSecretKey` and `rsaDecrypt` functions (engine v2).
-
-- `getSecretKey` reads a specific key from a Kubernetes Secret. Use it to fetch the RSA private key (PEM in plain text, without passphrase) used for decryption. (**Note:** It is recommended to fetch the key from a different Secret to ensure stronger security in the process).
-- `rsaDecrypt` performs decryption with the private key passed through the pipeline: `<privateKeyPEM | rsaDecrypt "<SCHEME>" "<HASH>" <ciphertext> >`. `SCHEME` and `HASH` are strings (for example, `"RSA-OAEP"` and `"SHA1"`). The third argument must be the ciphertext in binary form.
+When a provider returns RSA-encrypted values, you can decrypt them directly in the template using the `rsaDecrypt` functions (engine v2).
+`rsaDecrypt` performs decryption with the private key passed through the pipeline: `<privateKeyPEM | rsaDecrypt "<SCHEME>" "<HASH>" <ciphertext> >`. `SCHEME` and `HASH` are strings (for example, `"RSA-OAEP"` and `"SHA1"`). The third argument must be the ciphertext in binary form.
 
 
 Base64 handling: providers often return ciphertext as Base64. You can either:
 Base64 handling: providers often return ciphertext as Base64. You can either:
 - decode in the template with `b64dec` (for example: `(.password_encrypted_base64 | b64dec)`), or
 - decode in the template with `b64dec` (for example: `(.password_encrypted_base64 | b64dec)`), or
@@ -149,7 +147,7 @@ Base64 handling: providers often return ciphertext as Base64. You can either:
 
 
 Prerequisites
 Prerequisites
 - `spec.target.template.engineVersion: v2`.
 - `spec.target.template.engineVersion: v2`.
-- A valid RSA private key in PEM format without passphrase (from another Secret via `getSecretKey`, or from the same ExternalSecret).
+- A valid RSA private key in PEM format without passphrase (from another reference in the same ExternalSecret).
 - Ciphertext must match the key pair and the chosen algorithm/hash.
 - Ciphertext must match the key pair and the chosen algorithm/hash.
 
 
 Full example:
 Full example:
@@ -204,7 +202,6 @@ In addition to that you can use over 200+ [sprig functions](http://masterminds.g
 | filterCertChain  | Filters PEM block(s) with a specific certificate type (`leaf`, `intermediate` or `root`)  from a certificate chain of PEM blocks (PEM blocks with type `CERTIFICATE`). |
 | filterCertChain  | Filters PEM block(s) with a specific certificate type (`leaf`, `intermediate` or `root`)  from a certificate chain of PEM blocks (PEM blocks with type `CERTIFICATE`). |
 | jwkPublicKeyPem  | Takes an json-serialized JWK and returns an PEM block of type `PUBLIC KEY` that contains the public key. [See here](https://golang.org/pkg/crypto/x509/#MarshalPKIXPublicKey) for details.                                   |
 | jwkPublicKeyPem  | Takes an json-serialized JWK and returns an PEM block of type `PUBLIC KEY` that contains the public key. [See here](https://golang.org/pkg/crypto/x509/#MarshalPKIXPublicKey) for details.                                   |
 | jwkPrivateKeyPem | Takes an json-serialized JWK as `string` and returns an PEM block of type `PRIVATE KEY` that contains the private key in PKCS #8 format. [See here](https://golang.org/pkg/crypto/x509/#MarshalPKCS8PrivateKey) for details. |
 | jwkPrivateKeyPem | Takes an json-serialized JWK as `string` and returns an PEM block of type `PRIVATE KEY` that contains the private key in PKCS #8 format. [See here](https://golang.org/pkg/crypto/x509/#MarshalPKCS8PrivateKey) for details. |
-| getSecretKey      | Reads a specific key from a Kubernetes `Secret` and returns it as a string. Typical usage: ``getSecretKey "secret-name" "namespace" "key"``. |
 | rsaDecrypt | Decrypts RSA ciphertext using a PEM private key. Usage: ``<rsaDecrypt "SCHEME" "HASH" ciphertext privateKeyPEM>`` or ``<privateKeyPEM \| rsaDecrypt "SCHEME" "HASH" ciphertext>``. **SCHEME**: supported values are `"None"` and `"RSA-OAEP"`. **HASH**: supported values are `"SHA1"` and `"SHA256"`. **Ciphertext** must be binary — use `b64dec` or `decodingStrategy: Base64` to convert Base64 payloads. |
 | rsaDecrypt | Decrypts RSA ciphertext using a PEM private key. Usage: ``<rsaDecrypt "SCHEME" "HASH" ciphertext privateKeyPEM>`` or ``<privateKeyPEM \| rsaDecrypt "SCHEME" "HASH" ciphertext>``. **SCHEME**: supported values are `"None"` and `"RSA-OAEP"`. **HASH**: supported values are `"SHA1"` and `"SHA256"`. **Ciphertext** must be binary — use `b64dec` or `decodingStrategy: Base64` to convert Base64 payloads. |
 | toYaml           | Takes an interface, marshals it to yaml. It returns a string, even on marshal error (empty string).                                                                                                                          |
 | toYaml           | Takes an interface, marshals it to yaml. It returns a string, even on marshal error (empty string).                                                                                                                          |
 | fromYaml         | Function converts a YAML document into a map[string]any.                                                                                                                                                             |
 | fromYaml         | Function converts a YAML document into a map[string]any.                                                                                                                                                             |

+ 10 - 10
docs/snippets/rsadecrypt-template-v2-external-secret.yaml

@@ -10,17 +10,17 @@ spec:
       engineVersion: v2
       engineVersion: v2
       data:
       data:
         # Decrypt a binary ciphertext using a private key stored in a Kubernetes Secret.
         # Decrypt a binary ciphertext using a private key stored in a Kubernetes Secret.
-        # getSecretKey("secret-name", "namespace", "key") reads the PEM private key.
         # rsaDecrypt("SCHEME", "HASH", ciphertext, privateKeyPEM) decrypts the ciphertext (binary).
         # rsaDecrypt("SCHEME", "HASH", ciphertext, privateKeyPEM) decrypts the ciphertext (binary).
-        password: '{{ getSecretKey "my_secret_with_pk" "namespace_pk" "key_pk" | rsaDecrypt "RSA-OAEP" "SHA1" .password_encrypted_binary }}'
-
-        # Alternatives:
-        # - If provider returns Base64, decode in-template with b64dec:
-        # password: '{{ getSecretKey "my_secret_with_pk" "namespace_pk" "key_pk" | rsaDecrypt "RSA-OAEP" "SHA1" (.password_encrypted_base64 | b64dec) }}'
-        # - Or set decodingStrategy: Base64 on the spec.data.remoteRef so template receives binary.
-        # - Or use a private key pulled into this ExternalSecret (then use {{ .private_key }}):
-        # password: '{{ .private_key | rsaDecrypt "RSA-OAEP" "SHA1" .password_encrypted_binary }}'
+        password: '{{ rsaDecrypt "RSA-OAEP" "SHA1" .password_encrypted_binary .privatekey }}'
   data:
   data:
+  - secretKey: privatekey
+    remoteRef:
+      key: a-secretname-in-cluster
+      property: privatekey
+    sourceRef:
+      storeRef:
+        kind: SecretStore # or ClusterSecretStore
+        name: kubernetes # name of the k8s provider
   - secretKey: password_encrypted_binary
   - secretKey: password_encrypted_binary
     remoteRef:
     remoteRef:
       key: /credentials/password_encrypted_binary
       key: /credentials/password_encrypted_binary
@@ -31,4 +31,4 @@ spec:
   #     key: /credentials/password_encrypted_base64
   #     key: /credentials/password_encrypted_base64
   #     decodingStrategy: Base64
   #     decodingStrategy: Base64
   # ...
   # ...
-{% endraw %}
+{% endraw %}

+ 0 - 54
runtime/template/v2/kubernetes.go

@@ -1,54 +0,0 @@
-/*
-Copyright © 2025 ESO Maintainer Team
-
-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
-
-    https://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 template
-
-import (
-	"context"
-	"fmt"
-
-	"k8s.io/client-go/kubernetes"
-	ctrlcfg "sigs.k8s.io/controller-runtime/pkg/client/config"
-
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-const (
-	errCreatingConfig    = "error creating cluster configuration: %v"
-	errCreatingClientset = "error creating Kubernetes clientset: %v"
-	errFetchingSecret    = "error fetching secret: %v"
-	errKeyNotFound       = "key %s not found in secret %s"
-)
-
-func getSecretKey(secretName, namespace, keyName string) (string, error) {
-	restCfg, err := ctrlcfg.GetConfig()
-	if err != nil {
-		return "", fmt.Errorf(errCreatingConfig, err)
-	}
-	clientset, err := kubernetes.NewForConfig(restCfg)
-	if err != nil {
-		return "", fmt.Errorf(errCreatingClientset, err)
-	}
-	secret, err := clientset.CoreV1().Secrets(namespace).Get(context.Background(), secretName, metav1.GetOptions{})
-	if err != nil {
-		return "", fmt.Errorf(errFetchingSecret, err)
-	}
-	val, ok := secret.Data[keyName]
-	if !ok {
-		return "", fmt.Errorf(errKeyNotFound, keyName, secretName)
-	}
-	return string(val), nil
-}

+ 1 - 2
runtime/template/v2/template.go

@@ -55,8 +55,7 @@ var tplFuncs = tpl.FuncMap{
 	"toYaml":   toYAML,
 	"toYaml":   toYAML,
 	"fromYaml": fromYAML,
 	"fromYaml": fromYAML,
 
 
-	"getSecretKey": getSecretKey,
-	"rsaDecrypt":   rsaDecrypt,
+	"rsaDecrypt": rsaDecrypt,
 }
 }
 
 
 var leftDelim, rightDelim string
 var leftDelim, rightDelim string