This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 8143b8a6512570319573f3623cd9f70a8e32b053
Author: Pranjul Kalsi <[email protected]>
AuthorDate: Tue Dec 16 02:53:40 2025 +0530

    fix(jvm): secure JVM truststore password handling via secret reference
---
 docs/modules/traits/pages/jvm.adoc                 | 24 +++++-
 e2e/common/traits/jvm_test.go                      |  6 ++
 helm/camel-k/crds/camel-k-crds.yaml                | 48 +++++++++++
 pkg/apis/camel/v1/trait/jvm.go                     |  4 +
 .../camel.apache.org_integrationplatforms.yaml     | 12 +++
 .../camel.apache.org_integrationprofiles.yaml      | 12 +++
 .../crd/bases/camel.apache.org_integrations.yaml   | 12 +++
 .../config/crd/bases/camel.apache.org_pipes.yaml   | 12 +++
 pkg/trait/init_containers.go                       | 12 ++-
 pkg/trait/init_containers_test.go                  |  3 +-
 pkg/trait/jvm.go                                   | 16 +++-
 pkg/trait/jvm_cacert.go                            | 44 ++++++++--
 pkg/trait/jvm_test.go                              | 99 +++++++++++++++++++++-
 pkg/trait/mount_test.go                            |  3 +-
 14 files changed, 290 insertions(+), 17 deletions(-)

diff --git a/docs/modules/traits/pages/jvm.adoc 
b/docs/modules/traits/pages/jvm.adoc
index f894ee970..07b6e06c8 100755
--- a/docs/modules/traits/pages/jvm.adoc
+++ b/docs/modules/traits/pages/jvm.adoc
@@ -72,6 +72,12 @@ Example: "secret:my-ca-certs" or 
"secret:my-ca-certs/custom-ca.crt"
 | The path where the generated truststore will be mounted
 Default: "/etc/camel/conf.d/_truststore"
 
+| jvm.ca-cert-password
+| string
+| **Required when ca-cert is set.** A secret reference containing the 
truststore password.
+If the secret key is not specified, "password" is used as the default key.
+Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+
 |===
 
 // End of autogenerated code - DO NOT EDIT! (configuration)
@@ -116,18 +122,25 @@ First, create a Kubernetes Secret containing the CA 
certificate:
 kubectl create secret generic my-private-ca 
--from-file=ca.crt=/path/to/ca-certificate.pem
 ----
 
-Then reference the secret when running the integration:
+Next, create a Secret containing the truststore password:
+
+[source,console]
+----
+kubectl create secret generic my-truststore-pwd 
--from-literal=password=mysecurepassword
+----
+
+Then reference both secrets when running the integration:
 
 [source,console]
 ----
-$ kamel run MyRoute.java -t jvm.ca-cert=secret:my-private-ca
+$ kamel run MyRoute.java -t jvm.ca-cert=secret:my-private-ca -t 
jvm.ca-cert-password=secret:my-truststore-pwd
 ----
 
 If your certificate is stored under a different key in the secret:
 
 [source,console]
 ----
-$ kamel run MyRoute.java -t jvm.ca-cert=secret:my-private-ca/custom-ca.pem
+$ kamel run MyRoute.java -t jvm.ca-cert=secret:my-private-ca/custom-ca.pem -t 
jvm.ca-cert-password=secret:my-truststore-pwd
 ----
 
 This will automatically:
@@ -135,3 +148,8 @@ This will automatically:
 1. Mount the CA certificate secret
 2. Generate a JVM truststore using an init container
 3. Configure the JVM to use the generated truststore via 
`-Djavax.net.ssl.trustStore`
+4. Inject the truststore password securely as an environment variable from 
your secret
+
+NOTE: The `ca-cert-password` option is **required** when using `ca-cert`. The 
password is never exposed in command-line arguments - it is injected as an 
environment variable from the secret.
+
+
diff --git a/e2e/common/traits/jvm_test.go b/e2e/common/traits/jvm_test.go
index 274e804f0..ea07ae3f6 100644
--- a/e2e/common/traits/jvm_test.go
+++ b/e2e/common/traits/jvm_test.go
@@ -102,11 +102,17 @@ func TestJVMTrait(t *testing.T) {
                        err = CreatePlainTextSecret(t, ctx, ns, "test-ca-cert", 
caCertData)
                        require.NoError(t, err)
 
+                       passwordData := make(map[string]string)
+                       passwordData["password"] = "test-password-123"
+                       err = CreatePlainTextSecret(t, ctx, ns, 
"test-ca-password", passwordData)
+                       require.NoError(t, err)
+
                        name := RandomizedSuffixName("cacert")
                        g.Expect(KamelRun(t, ctx, ns,
                                "./files/Java.java",
                                "--name", name,
                                "-t", "jvm.ca-cert=secret:test-ca-cert",
+                               "-t", 
"jvm.ca-cert-password=secret:test-ca-password",
                        ).Execute()).To(Succeed())
 
                        g.Eventually(IntegrationPodPhase(t, ctx, ns, name), 
TestTimeoutLong).Should(Equal(corev1.PodRunning))
diff --git a/helm/camel-k/crds/camel-k-crds.yaml 
b/helm/camel-k/crds/camel-k-crds.yaml
index d480cd3de..2ceed0549 100644
--- a/helm/camel-k/crds/camel-k-crds.yaml
+++ b/helm/camel-k/crds/camel-k-crds.yaml
@@ -4731,6 +4731,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -7134,6 +7140,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -9439,6 +9451,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -11721,6 +11739,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -20837,6 +20861,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -23073,6 +23103,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -33551,6 +33587,12 @@ spec:
                               The path where the generated truststore will be 
mounted
                               Default: "/etc/camel/conf.d/_truststore"
                             type: string
+                          caCertPassword:
+                            description: |-
+                              Required when caCert is set. A secret reference 
containing the truststore password.
+                              If the secret key is not specified, "password" 
is used as the default key.
+                              Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                            type: string
                           classpath:
                             description: Additional JVM classpath (use `Linux` 
classpath
                               separator)
@@ -35719,6 +35761,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
diff --git a/pkg/apis/camel/v1/trait/jvm.go b/pkg/apis/camel/v1/trait/jvm.go
index 1f17f35a7..b00c7c6a8 100644
--- a/pkg/apis/camel/v1/trait/jvm.go
+++ b/pkg/apis/camel/v1/trait/jvm.go
@@ -48,4 +48,8 @@ type JVMTrait struct {
        // The path where the generated truststore will be mounted
        // Default: "/etc/camel/conf.d/_truststore"
        CACertMountPath string `json:"caCertMountPath,omitempty" 
property:"ca-cert-mount-path"`
+       // Required when caCert is set. A secret reference containing the 
truststore password.
+       // If the secret key is not specified, "password" is used as the 
default key.
+       // Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+       CACertPassword string `json:"caCertPassword,omitempty" 
property:"ca-cert-password"`
 }
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
index eb8324738..2a8131651 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
@@ -1482,6 +1482,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -3885,6 +3891,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
index 8e6205d2e..924a60f7c 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
@@ -1350,6 +1350,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -3632,6 +3638,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
index 4f57d79dd..097df5642 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
@@ -8164,6 +8164,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -10400,6 +10406,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
diff --git a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
index 1ad74cde2..147c06e12 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
@@ -8220,6 +8220,12 @@ spec:
                               The path where the generated truststore will be 
mounted
                               Default: "/etc/camel/conf.d/_truststore"
                             type: string
+                          caCertPassword:
+                            description: |-
+                              Required when caCert is set. A secret reference 
containing the truststore password.
+                              If the secret key is not specified, "password" 
is used as the default key.
+                              Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                            type: string
                           classpath:
                             description: Additional JVM classpath (use `Linux` 
classpath
                               separator)
@@ -10388,6 +10394,12 @@ spec:
                           The path where the generated truststore will be 
mounted
                           Default: "/etc/camel/conf.d/_truststore"
                         type: string
+                      caCertPassword:
+                        description: |-
+                          Required when caCert is set. A secret reference 
containing the truststore password.
+                          If the secret key is not specified, "password" is 
used as the default key.
+                          Example: "secret:my-truststore-password" or 
"secret:my-truststore-password/mykey"
+                        type: string
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
diff --git a/pkg/trait/init_containers.go b/pkg/trait/init_containers.go
index 4ae0ad9ba..ec423ef64 100644
--- a/pkg/trait/init_containers.go
+++ b/pkg/trait/init_containers.go
@@ -42,6 +42,7 @@ type containerTask struct {
        image     string
        command   string
        isSidecar bool
+       env       []corev1.EnvVar
 }
 
 type initContainersTrait struct {
@@ -100,14 +101,20 @@ func (t *initContainersTrait) Configure(e *Environment) 
(bool, *TraitCondition,
                                secretKey = "ca.crt"
                        }
 
+                       secretName, secretKey2, err := 
jvm.getTrustStorePasswordSecretRef()
+                       if err != nil {
+                               return false, nil, err
+                       }
+
                        keytoolCmd := fmt.Sprintf(
-                               "keytool -importcert -noprompt -alias custom-ca 
-storepass %s -keystore %s -file /etc/secrets/cacert/%s",
-                               getTrustStorePassword(e.Integration.Name), 
jvm.getTrustStorePath(), secretKey,
+                               "keytool -importcert -noprompt -alias custom-ca 
-storepass:env %s -keystore %s -file /etc/secrets/cacert/%s",
+                               truststorePasswordEnvVar, 
jvm.getTrustStorePath(), secretKey,
                        )
                        caCertTask := containerTask{
                                name:    "generate-truststore",
                                image:   defaults.BaseImage(),
                                command: keytoolCmd,
+                               env:     
[]corev1.EnvVar{getTrustStorePasswordEnvVar(secretName, secretKey2)},
                        }
                        t.tasks = append(t.tasks, caCertTask)
                }
@@ -156,6 +163,7 @@ func (t *initContainersTrait) 
configureContainers(containers *[]corev1.Container
                        Name:    task.name,
                        Image:   task.image,
                        Command: splitContainerCommand(task.command),
+                       Env:     task.env,
                }
                if task.isSidecar {
                        initCont.RestartPolicy = 
ptr.To(corev1.ContainerRestartPolicyAlways)
diff --git a/pkg/trait/init_containers_test.go 
b/pkg/trait/init_containers_test.go
index 695430027..9f562b8f5 100644
--- a/pkg/trait/init_containers_test.go
+++ b/pkg/trait/init_containers_test.go
@@ -393,7 +393,8 @@ func TestApplyInitContainerWithCACert(t *testing.T) {
                        Spec: v1.IntegrationSpec{
                                Traits: v1.Traits{
                                        JVM: &trait.JVMTrait{
-                                               CACert: "secret:my-ca-secret",
+                                               CACert:         
"secret:my-ca-secret",
+                                               CACertPassword: 
"secret:my-ca-password",
                                        },
                                },
                        },
diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go
index efe76877e..484d7d4eb 100644
--- a/pkg/trait/jvm.go
+++ b/pkg/trait/jvm.go
@@ -378,7 +378,7 @@ func getLegacyCamelQuarkusDependenciesPaths() *sets.Set {
        return s
 }
 
-// configureCACert returns the JVM arguments for truststore configuration.
+// configureCACert configures the CA certificate truststore and returns the 
JVM arguments.
 func (t *jvmTrait) configureCaCert(e *Environment) ([]string, error) {
        if t.CACert == "" {
                return nil, nil
@@ -389,8 +389,20 @@ func (t *jvmTrait) configureCaCert(e *Environment) 
([]string, error) {
                return nil, err
        }
 
+       secretName, secretKey, err := t.getTrustStorePasswordSecretRef()
+       if err != nil {
+               return nil, fmt.Errorf("failed to configure truststore 
password: %w", err)
+       }
+
+       // Inject password
+       container := e.GetIntegrationContainer()
+       if container != nil {
+               envVar := getTrustStorePasswordEnvVar(secretName, secretKey)
+               container.Env = append(container.Env, envVar)
+       }
+
        return []string{
                "-Djavax.net.ssl.trustStore=" + t.getTrustStorePath(),
-               "-Djavax.net.ssl.trustStorePassword=" + 
getTrustStorePassword(e.Integration.Name),
+               fmt.Sprintf("-Djavax.net.ssl.trustStorePassword=$(%s)", 
truststorePasswordEnvVar),
        }, nil
 }
diff --git a/pkg/trait/jvm_cacert.go b/pkg/trait/jvm_cacert.go
index 71dc67cd9..6220a5e0e 100644
--- a/pkg/trait/jvm_cacert.go
+++ b/pkg/trait/jvm_cacert.go
@@ -21,13 +21,17 @@ import (
        "errors"
        "fmt"
        "strings"
+
+       corev1 "k8s.io/api/core/v1"
 )
 
 const (
-       defaultCACertMountPath = "/etc/camel/conf.d/_truststore"
-       caCertVolumeName       = "jvm-truststore"
-       caCertSecretVolumeName = "ca-cert-secret" //nolint:gosec // G101: not a 
credential, just a volume name
-       trustStoreName         = "truststore.jks"
+       defaultCACertMountPath      = "/etc/camel/conf.d/_truststore"
+       caCertVolumeName            = "jvm-truststore"
+       caCertSecretVolumeName      = "ca-cert-secret" //nolint:gosec // G101: 
not a credential, just a volume name
+       trustStoreName              = "truststore.jks"
+       truststorePasswordEnvVar    = "TRUSTSTORE_PASSWORD"
+       truststorePasswordSecretKey = "password"
 )
 
 func (t *jvmTrait) hasCACert() bool {
@@ -66,6 +70,34 @@ func (t *jvmTrait) getTrustStorePath() string {
        return t.getCACertMountPath() + "/" + trustStoreName
 }
 
-func getTrustStorePassword(integrationName string) string {
-       return "camelk-" + integrationName
+// getTrustStorePasswordSecretRef parses and returns the user-provided 
password secret reference.
+func (t *jvmTrait) getTrustStorePasswordSecretRef() (string, string, error) {
+       if t.CACertPassword == "" {
+               return "", "", errors.New("ca-cert-password is required when 
ca-cert is set")
+       }
+
+       secretName, secretKey, err := parseSecretRef(t.CACertPassword)
+       if err != nil {
+               return "", "", fmt.Errorf("invalid ca-cert-password reference: 
%w", err)
+       }
+       if secretKey == "" {
+               secretKey = truststorePasswordSecretKey
+       }
+
+       return secretName, secretKey, nil
+}
+
+// getTrustStorePasswordEnvVar returns the environment variable for truststore 
password injection.
+func getTrustStorePasswordEnvVar(secretName, secretKey string) corev1.EnvVar {
+       return corev1.EnvVar{
+               Name: truststorePasswordEnvVar,
+               ValueFrom: &corev1.EnvVarSource{
+                       SecretKeyRef: &corev1.SecretKeySelector{
+                               LocalObjectReference: 
corev1.LocalObjectReference{
+                                       Name: secretName,
+                               },
+                               Key: secretKey,
+                       },
+               },
+       }
 }
diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go
index 76a750a80..62883cfad 100644
--- a/pkg/trait/jvm_test.go
+++ b/pkg/trait/jvm_test.go
@@ -720,9 +720,39 @@ func TestApplyJvmTraitAgentFail(t *testing.T) {
        assert.Contains(t, err.Error(), "could not parse JVM agent")
 }
 
+func TestApplyJvmTraitWithCACertMissingPassword(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       trait.CACert = "secret:my-ca-secret"
+
+       d := appsv1.Deployment{
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name: 
defaultContainerName,
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+       environment.Resources.Add(&d)
+       configure, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.True(t, configure)
+       assert.Nil(t, condition)
+
+       err = trait.Apply(environment)
+       require.Error(t, err)
+       assert.Contains(t, err.Error(), "ca-cert-password is required")
+}
+
 func TestApplyJvmTraitWithCACert(t *testing.T) {
        trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
        trait.CACert = "secret:my-ca-secret"
+       trait.CACertPassword = "secret:my-truststore-password"
 
        d := appsv1.Deployment{
                Spec: appsv1.DeploymentSpec{
@@ -747,9 +777,22 @@ func TestApplyJvmTraitWithCACert(t *testing.T) {
        err = trait.Apply(environment)
        require.NoError(t, err)
 
-       // JVM trait now only adds JVM args for truststore
        assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Djavax.net.ssl.trustStore=/etc/camel/conf.d/_truststore/truststore.jks")
-       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Djavax.net.ssl.trustStorePassword=camelk-my-it")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Djavax.net.ssl.trustStorePassword=$(TRUSTSTORE_PASSWORD)")
+
+       // Verify TRUSTSTORE_PASSWORD env var is injected from user-provided 
secret
+       var foundEnvVar bool
+       for _, env := range d.Spec.Template.Spec.Containers[0].Env {
+               if env.Name == "TRUSTSTORE_PASSWORD" {
+                       foundEnvVar = true
+                       assert.NotNil(t, env.ValueFrom)
+                       assert.NotNil(t, env.ValueFrom.SecretKeyRef)
+                       assert.Equal(t, "my-truststore-password", 
env.ValueFrom.SecretKeyRef.Name)
+                       assert.Equal(t, "password", 
env.ValueFrom.SecretKeyRef.Key)
+                       break
+               }
+       }
+       assert.True(t, foundEnvVar, "TRUSTSTORE_PASSWORD env var should be 
injected")
 }
 
 func TestParseSecretRef(t *testing.T) {
@@ -771,3 +814,55 @@ func TestParseSecretRef(t *testing.T) {
        require.Error(t, err)
        assert.Contains(t, err.Error(), "secret name is empty")
 }
+
+func TestApplyJvmTraitWithCACertUserProvidedPassword(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       trait.CACert = "secret:my-ca-secret"
+       trait.CACertPassword = "secret:my-custom-password/mykey"
+
+       d := appsv1.Deployment{
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name: 
defaultContainerName,
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+       environment.Resources.Add(&d)
+       configure, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.True(t, configure)
+       assert.Nil(t, condition)
+
+       err = trait.Apply(environment)
+       require.NoError(t, err)
+
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Djavax.net.ssl.trustStorePassword=$(TRUSTSTORE_PASSWORD)")
+
+       var foundEnvVar bool
+       for _, env := range d.Spec.Template.Spec.Containers[0].Env {
+               if env.Name == "TRUSTSTORE_PASSWORD" {
+                       foundEnvVar = true
+                       assert.NotNil(t, env.ValueFrom)
+                       assert.NotNil(t, env.ValueFrom.SecretKeyRef)
+                       assert.Equal(t, "my-custom-password", 
env.ValueFrom.SecretKeyRef.Name)
+                       assert.Equal(t, "mykey", env.ValueFrom.SecretKeyRef.Key)
+                       break
+               }
+       }
+       assert.True(t, foundEnvVar, "TRUSTSTORE_PASSWORD env var should be 
injected")
+
+       var foundAutoSecret bool
+       environment.Resources.VisitSecret(func(secret *corev1.Secret) {
+               if secret.Name == "my-it-truststore-password" {
+                       foundAutoSecret = true
+               }
+       })
+       assert.False(t, foundAutoSecret, "Auto-generated password secret should 
NOT be created when user provides one")
+}
diff --git a/pkg/trait/mount_test.go b/pkg/trait/mount_test.go
index 863cd401b..afd675b36 100644
--- a/pkg/trait/mount_test.go
+++ b/pkg/trait/mount_test.go
@@ -729,7 +729,8 @@ func TestCACertVolume(t *testing.T) {
 
        environment.Integration.Spec.Traits.Mount = &traitv1.MountTrait{}
        environment.Integration.Spec.Traits.JVM = &traitv1.JVMTrait{
-               CACert: "secret:my-ca-secret",
+               CACert:         "secret:my-ca-secret",
+               CACertPassword: "secret:my-ca-password",
        }
        environment.Platform.ResyncStatusFullConfig()
        conditions, traits, err := traitCatalog.apply(environment)

Reply via email to