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 0d3db56b5c2ec6bd785dd212a84cd5c143dbcfdc
Author: Pranjul Kalsi <[email protected]>
AuthorDate: Tue Jan 13 15:47:42 2026 +0530

    feat(jvm): Add multi-certificate and system truststore support for CA certs
---
 docs/modules/ROOT/partials/apis/camel-k-crds.adoc  |  23 +-
 docs/modules/traits/pages/jvm.adoc                 |  17 +-
 e2e/common/traits/jvm_test.go                      | 115 +++++++++-
 helm/camel-k/crds/camel-k-crds.yaml                | 168 +++++++++++----
 pkg/apis/camel/v1/trait/jvm.go                     |  13 +-
 pkg/apis/camel/v1/trait/zz_generated.deepcopy.go   |  10 +
 .../camel.apache.org_integrationplatforms.yaml     |  42 +++-
 .../camel.apache.org_integrationprofiles.yaml      |  42 +++-
 .../crd/bases/camel.apache.org_integrations.yaml   |  42 +++-
 .../config/crd/bases/camel.apache.org_pipes.yaml   |  42 +++-
 pkg/trait/init_containers.go                       |  48 ++++-
 pkg/trait/init_containers_test.go                  | 234 +++++++++++++++++++++
 pkg/trait/jvm_cacert.go                            |  67 ++++--
 pkg/trait/jvm_test.go                              | 107 ++++++++--
 pkg/trait/mount.go                                 |   2 +-
 15 files changed, 833 insertions(+), 139 deletions(-)

diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc 
b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
index 5d2e88a33..d1effbd3a 100644
--- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
+++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
@@ -7836,13 +7836,20 @@ The Jar dependency which will run the application. 
Leave it empty for managed In
 
 A list of JVM agents to download and execute with format 
`<agent-name>;<agent-url>[;<jvm-agent-options>]`.
 
+|`caCerts` +
+[]string
+|
+
+
+A list of paths to PEM-encoded CA certificates to import into the truststore.
+Certificates must be mounted via the mount trait.
+
 |`caCert` +
 string
 |
 
 
-Path to a PEM-encoded CA certificate file.
-Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+Path to a PEM-encoded CA certificate file. Use CACerts for multiple 
certificates.
 
 |`caCertMountPath` +
 string
@@ -7857,8 +7864,16 @@ string
 |
 
 
-Required when caCert is set. Path to a file containing the truststore password.
-Example: "/etc/camel/conf.d/_secrets/truststore-pass/password"
+Path to a custom truststore password file.
+Default: uses "changeit" if not specified.
+
+|`caCertUseSystemTruststore` +
+bool
+|
+
+
+If true, the JDK's default cacerts is copied as the base truststore.
+Default: false (empty truststore).
 
 
 |===
diff --git a/docs/modules/traits/pages/jvm.adoc 
b/docs/modules/traits/pages/jvm.adoc
index c3300594f..39a7f7641 100755
--- a/docs/modules/traits/pages/jvm.adoc
+++ b/docs/modules/traits/pages/jvm.adoc
@@ -63,10 +63,14 @@ Deprecated: no longer in use.
 | []string
 | A list of JVM agents to download and execute with format 
`<agent-name>;<agent-url>[;<jvm-agent-options>]`.
 
+| jvm.ca-certs
+| []string
+| A list of paths to PEM-encoded CA certificates to import into the truststore.
+Certificates must be mounted via the mount trait.
+
 | jvm.ca-cert
 | string
-| Path to a PEM-encoded CA certificate file.
-Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+| Path to a PEM-encoded CA certificate file. Use CACerts for multiple 
certificates.
 
 | jvm.ca-cert-mount-path
 | string
@@ -75,8 +79,13 @@ Default: "/etc/camel/conf.d/_truststore"
 
 | jvm.ca-cert-password
 | string
-| Required when caCert is set. Path to a file containing the truststore 
password.
-Example: "/etc/camel/conf.d/_secrets/truststore-pass/password"
+| Path to a custom truststore password file.
+Default: uses "changeit" if not specified.
+
+| jvm.ca-cert-use-system-truststore
+| bool
+| If true, the JDK's default cacerts is copied as the base truststore.
+Default: false (empty truststore).
 
 |===
 
diff --git a/e2e/common/traits/jvm_test.go b/e2e/common/traits/jvm_test.go
index 6e143b98b..f2a8fc5ea 100644
--- a/e2e/common/traits/jvm_test.go
+++ b/e2e/common/traits/jvm_test.go
@@ -120,7 +120,120 @@ func TestJVMTrait(t *testing.T) {
                        g.Eventually(IntegrationPodPhase(t, ctx, ns, name), 
TestTimeoutLong).Should(Equal(corev1.PodRunning))
                        g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
name, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
 
-                       // Verify init container was added
+                       pod := IntegrationPod(t, ctx, ns, name)()
+                       g.Expect(pod).NotTo(BeNil())
+                       initContainerNames := make([]string, 0)
+                       for _, c := range pod.Spec.InitContainers {
+                               initContainerNames = append(initContainerNames, 
c.Name)
+                       }
+                       
g.Expect(initContainerNames).To(ContainElement("generate-truststore"))
+               })
+
+               t.Run("JVM trait multiple CA certs", func(t *testing.T) {
+                       // Generate two valid self-signed certificates
+                       cert1Pem, err := generateSelfSignedCert()
+                       require.NoError(t, err)
+                       cert2Pem, err := generateSelfSignedCert()
+                       require.NoError(t, err)
+
+                       caCert1Data := make(map[string]string)
+                       caCert1Data["ca.crt"] = string(cert1Pem)
+                       err = CreatePlainTextSecret(t, ctx, ns, 
"test-ca-cert-1", caCert1Data)
+                       require.NoError(t, err)
+
+                       caCert2Data := make(map[string]string)
+                       caCert2Data["ca.crt"] = string(cert2Pem)
+                       err = CreatePlainTextSecret(t, ctx, ns, 
"test-ca-cert-2", caCert2Data)
+                       require.NoError(t, err)
+
+                       passwordData := make(map[string]string)
+                       passwordData["password"] = "test-password-123"
+                       err = CreatePlainTextSecret(t, ctx, ns, 
"test-multi-ca-password", passwordData)
+                       require.NoError(t, err)
+
+                       name := RandomizedSuffixName("multicacert")
+                       g.Expect(KamelRun(t, ctx, ns,
+                               "./files/Java.java",
+                               "--name", name,
+                               "-t", "mount.configs=secret:test-ca-cert-1",
+                               "-t", "mount.configs=secret:test-ca-cert-2",
+                               "-t", 
"mount.configs=secret:test-multi-ca-password",
+                               "-t", 
"jvm.ca-certs=/etc/camel/conf.d/_secrets/test-ca-cert-1/ca.crt",
+                               "-t", 
"jvm.ca-certs=/etc/camel/conf.d/_secrets/test-ca-cert-2/ca.crt",
+                               "-t", 
"jvm.ca-cert-password=/etc/camel/conf.d/_secrets/test-multi-ca-password/password",
+                       ).Execute()).To(Succeed())
+
+                       g.Eventually(IntegrationPodPhase(t, ctx, ns, name), 
TestTimeoutLong*2).Should(Equal(corev1.PodRunning))
+                       g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
name, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+
+                       pod := IntegrationPod(t, ctx, ns, name)()
+                       g.Expect(pod).NotTo(BeNil())
+                       initContainerNames := make([]string, 0)
+                       for _, c := range pod.Spec.InitContainers {
+                               initContainerNames = append(initContainerNames, 
c.Name)
+                       }
+                       
g.Expect(initContainerNames).To(ContainElement("generate-truststore"))
+               })
+
+               t.Run("JVM trait CA cert with system truststore", func(t 
*testing.T) {
+                       // Generate a valid self-signed certificate
+                       certPem, err := generateSelfSignedCert()
+                       require.NoError(t, err)
+
+                       caCertData := make(map[string]string)
+                       caCertData["ca.crt"] = string(certPem)
+                       err = CreatePlainTextSecret(t, ctx, ns, "test-ca-sys", 
caCertData)
+                       require.NoError(t, err)
+
+                       passwordData := make(map[string]string)
+                       passwordData["password"] = "test-password-456"
+                       err = CreatePlainTextSecret(t, ctx, ns, 
"test-ca-sys-password", passwordData)
+                       require.NoError(t, err)
+
+                       name := RandomizedSuffixName("syscacert")
+                       g.Expect(KamelRun(t, ctx, ns,
+                               "./files/Java.java",
+                               "--name", name,
+                               "-t", "mount.configs=secret:test-ca-sys",
+                               "-t", 
"mount.configs=secret:test-ca-sys-password",
+                               "-t", 
"jvm.ca-certs=/etc/camel/conf.d/_secrets/test-ca-sys/ca.crt",
+                               "-t", 
"jvm.ca-cert-password=/etc/camel/conf.d/_secrets/test-ca-sys-password/password",
+                               "-t", "jvm.ca-cert-use-system-truststore=true",
+                       ).Execute()).To(Succeed())
+
+                       g.Eventually(IntegrationPodPhase(t, ctx, ns, name), 
TestTimeoutLong).Should(Equal(corev1.PodRunning))
+                       g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
name, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+
+                       pod := IntegrationPod(t, ctx, ns, name)()
+                       g.Expect(pod).NotTo(BeNil())
+                       initContainerNames := make([]string, 0)
+                       for _, c := range pod.Spec.InitContainers {
+                               initContainerNames = append(initContainerNames, 
c.Name)
+                       }
+                       
g.Expect(initContainerNames).To(ContainElement("generate-truststore"))
+               })
+
+               t.Run("JVM trait CA cert with default password", func(t 
*testing.T) {
+                       certPem, err := generateSelfSignedCert()
+                       require.NoError(t, err)
+
+                       caCertData := make(map[string]string)
+                       caCertData["ca.crt"] = string(certPem)
+                       err = CreatePlainTextSecret(t, ctx, ns, 
"test-ca-default-pass", caCertData)
+                       require.NoError(t, err)
+
+                       // Note: No password secret is provided, will use 
default "changeit"
+                       name := RandomizedSuffixName("defaultpass")
+                       g.Expect(KamelRun(t, ctx, ns,
+                               "./files/Java.java",
+                               "--name", name,
+                               "-t", 
"mount.configs=secret:test-ca-default-pass",
+                               "-t", 
"jvm.ca-certs=/etc/camel/conf.d/_secrets/test-ca-default-pass/ca.crt",
+                       ).Execute()).To(Succeed())
+
+                       g.Eventually(IntegrationPodPhase(t, ctx, ns, name), 
TestTimeoutLong).Should(Equal(corev1.PodRunning))
+                       g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
name, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+
                        pod := IntegrationPod(t, ctx, ns, name)()
                        g.Expect(pod).NotTo(BeNil())
                        initContainerNames := make([]string, 0)
diff --git a/helm/camel-k/crds/camel-k-crds.yaml 
b/helm/camel-k/crds/camel-k-crds.yaml
index 301bbb9c0..1bdcfb2ab 100644
--- a/helm/camel-k/crds/camel-k-crds.yaml
+++ b/helm/camel-k/crds/camel-k-crds.yaml
@@ -4776,9 +4776,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -4787,9 +4786,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -7258,9 +7269,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -7269,9 +7279,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -9640,9 +9662,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -9651,9 +9672,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -11999,9 +12032,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -12010,9 +12042,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -21216,9 +21260,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -21227,9 +21270,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -23531,9 +23586,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -23542,9 +23596,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -34112,9 +34178,8 @@ spec:
                               type: string
                             type: array
                           caCert:
-                            description: |-
-                              Path to a PEM-encoded CA certificate file.
-                              Example: 
"/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                            description: Path to a PEM-encoded CA certificate 
file.
+                              Use CACerts for multiple certificates.
                             type: string
                           caCertMountPath:
                             description: |-
@@ -34123,9 +34188,21 @@ spec:
                             type: string
                           caCertPassword:
                             description: |-
-                              Required when caCert is set. Path to a file 
containing the truststore password.
-                              Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                              Path to a custom truststore password file.
+                              Default: uses "changeit" if not specified.
                             type: string
+                          caCertUseSystemTruststore:
+                            description: |-
+                              If true, the JDK's default cacerts is copied as 
the base truststore.
+                              Default: false (empty truststore).
+                            type: boolean
+                          caCerts:
+                            description: |-
+                              A list of paths to PEM-encoded CA certificates 
to import into the truststore.
+                              Certificates must be mounted via the mount trait.
+                            items:
+                              type: string
+                            type: array
                           classpath:
                             description: Additional JVM classpath (use `Linux` 
classpath
                               separator)
@@ -36357,9 +36434,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -36368,9 +36444,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       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 6ce82cab6..232205e1d 100644
--- a/pkg/apis/camel/v1/trait/jvm.go
+++ b/pkg/apis/camel/v1/trait/jvm.go
@@ -45,13 +45,18 @@ type JVMTrait struct {
        Jar string `json:"jar,omitempty" property:"jar"`
        // A list of JVM agents to download and execute with format 
`<agent-name>;<agent-url>[;<jvm-agent-options>]`.
        Agents []string `json:"agents,omitempty" property:"agents"`
-       // Path to a PEM-encoded CA certificate file.
-       // Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+       // A list of paths to PEM-encoded CA certificates to import into the 
truststore.
+       // Certificates must be mounted via the mount trait.
+       CACerts []string `json:"caCerts,omitempty" property:"ca-certs"`
+       // Path to a PEM-encoded CA certificate file. Use CACerts for multiple 
certificates.
        CACert string `json:"caCert,omitempty" property:"ca-cert"`
        // 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. Path to a file containing the 
truststore password.
-       // Example: "/etc/camel/conf.d/_secrets/truststore-pass/password"
+       // Path to a custom truststore password file.
+       // Default: uses "changeit" if not specified.
        CACertPassword string `json:"caCertPassword,omitempty" 
property:"ca-cert-password"`
+       // If true, the JDK's default cacerts is copied as the base truststore.
+       // Default: false (empty truststore).
+       CACertUseSystemTruststore *bool 
`json:"caCertUseSystemTruststore,omitempty" 
property:"ca-cert-use-system-truststore"`
 }
diff --git a/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go 
b/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go
index 24cd6c132..ed7752e52 100644
--- a/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go
@@ -581,6 +581,16 @@ func (in *JVMTrait) DeepCopyInto(out *JVMTrait) {
                *out = make([]string, len(*in))
                copy(*out, *in)
        }
+       if in.CACerts != nil {
+               in, out := &in.CACerts, &out.CACerts
+               *out = make([]string, len(*in))
+               copy(*out, *in)
+       }
+       if in.CACertUseSystemTruststore != nil {
+               in, out := &in.CACertUseSystemTruststore, 
&out.CACertUseSystemTruststore
+               *out = new(bool)
+               **out = **in
+       }
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new JVMTrait.
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 79c2711be..3308ff925 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
@@ -1502,9 +1502,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -1513,9 +1512,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -3984,9 +3995,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -3995,9 +4005,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       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 a41a34546..1db55503a 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
@@ -1368,9 +1368,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -1379,9 +1378,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -3727,9 +3738,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -3738,9 +3748,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       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 bb1aebbb0..4adf8f7fe 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
@@ -8206,9 +8206,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -8217,9 +8216,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
@@ -10521,9 +10532,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -10532,9 +10542,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       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 b2325b12c..c325d43c1 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
@@ -8262,9 +8262,8 @@ spec:
                               type: string
                             type: array
                           caCert:
-                            description: |-
-                              Path to a PEM-encoded CA certificate file.
-                              Example: 
"/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                            description: Path to a PEM-encoded CA certificate 
file.
+                              Use CACerts for multiple certificates.
                             type: string
                           caCertMountPath:
                             description: |-
@@ -8273,9 +8272,21 @@ spec:
                             type: string
                           caCertPassword:
                             description: |-
-                              Required when caCert is set. Path to a file 
containing the truststore password.
-                              Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                              Path to a custom truststore password file.
+                              Default: uses "changeit" if not specified.
                             type: string
+                          caCertUseSystemTruststore:
+                            description: |-
+                              If true, the JDK's default cacerts is copied as 
the base truststore.
+                              Default: false (empty truststore).
+                            type: boolean
+                          caCerts:
+                            description: |-
+                              A list of paths to PEM-encoded CA certificates 
to import into the truststore.
+                              Certificates must be mounted via the mount trait.
+                            items:
+                              type: string
+                            type: array
                           classpath:
                             description: Additional JVM classpath (use `Linux` 
classpath
                               separator)
@@ -10507,9 +10518,8 @@ spec:
                           type: string
                         type: array
                       caCert:
-                        description: |-
-                          Path to a PEM-encoded CA certificate file.
-                          Example: "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
+                        description: Path to a PEM-encoded CA certificate 
file. Use
+                          CACerts for multiple certificates.
                         type: string
                       caCertMountPath:
                         description: |-
@@ -10518,9 +10528,21 @@ spec:
                         type: string
                       caCertPassword:
                         description: |-
-                          Required when caCert is set. Path to a file 
containing the truststore password.
-                          Example: 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
+                          Path to a custom truststore password file.
+                          Default: uses "changeit" if not specified.
                         type: string
+                      caCertUseSystemTruststore:
+                        description: |-
+                          If true, the JDK's default cacerts is copied as the 
base truststore.
+                          Default: false (empty truststore).
+                        type: boolean
+                      caCerts:
+                        description: |-
+                          A list of paths to PEM-encoded CA certificates to 
import into the truststore.
+                          Certificates must be mounted via the mount trait.
+                        items:
+                          type: string
+                        type: array
                       classpath:
                         description: Additional JVM classpath (use `Linux` 
classpath
                           separator)
diff --git a/pkg/trait/init_containers.go b/pkg/trait/init_containers.go
index 574a1da18..1654b9afe 100644
--- a/pkg/trait/init_containers.go
+++ b/pkg/trait/init_containers.go
@@ -92,19 +92,49 @@ func (t *initContainersTrait) Configure(e *Environment) 
(bool, *TraitCondition,
                        t.tasks = append(t.tasks, agentDownloadTask)
                }
                // Set the CA cert truststore init container if configured
-               if ok && jvm.hasCACert() {
-                       if err := jvm.validateCACertConfig(); err != nil {
-                               return false, nil, err
+               if ok && jvm.hasCACerts() {
+                       var allCommands []string
+                       effectivePassword := 
jvm.getEffectiveTruststorePassword()
+
+                       if jvm.useSystemTruststore() {
+                               copyCmd := fmt.Sprintf("cp %s %s", 
jdkCacertsPath, jvm.getTrustStorePath())
+                               allCommands = append(allCommands, copyCmd)
+
+                               if jvm.hasCustomPassword() {
+                                       changePassCmd := fmt.Sprintf(
+                                               "keytool -storepasswd -keystore 
%s -storepass %s -new %s",
+                                               jvm.getTrustStorePath(), 
jdkCacertsDefaultPassword, effectivePassword,
+                                       )
+                                       allCommands = append(allCommands, 
changePassCmd)
+                               }
+                       }
+
+                       certPaths := jvm.getAllCACertPaths()
+                       for i, certPath := range certPaths {
+                               var cmd string
+                               if jvm.hasCustomPassword() {
+                                       cmd = fmt.Sprintf(
+                                               "keytool -importcert -noprompt 
-alias custom-ca-%d -storepass:file %s -keystore %s -file %s",
+                                               i, jvm.getCACertPasswordPath(), 
jvm.getTrustStorePath(), certPath,
+                                       )
+                               } else {
+                                       cmd = fmt.Sprintf(
+                                               "keytool -importcert -noprompt 
-alias custom-ca-%d -storepass %s -keystore %s -file %s",
+                                               i, jdkCacertsDefaultPassword, 
jvm.getTrustStorePath(), certPath,
+                                       )
+                               }
+                               allCommands = append(allCommands, cmd)
+                       }
+
+                       fullCommand := strings.Join(allCommands, " && ")
+                       // Wrap in bash shell when there are multiple commands 
or shell features are used
+                       if len(allCommands) > 1 || jvm.useSystemTruststore() {
+                               fullCommand = fmt.Sprintf("/bin/bash -c 
\"%s\"", fullCommand)
                        }
-                       // keytool reads password from file using 
-storepass:file
-                       keytoolCmd := fmt.Sprintf(
-                               "keytool -importcert -noprompt -alias custom-ca 
-storepass:file %s -keystore %s -file %s",
-                               jvm.getCACertPasswordPath(), 
jvm.getTrustStorePath(), jvm.getCACertPath(),
-                       )
                        caCertTask := containerTask{
                                name:    "generate-truststore",
                                image:   defaults.BaseImage(),
-                               command: keytoolCmd,
+                               command: fullCommand,
                        }
                        t.tasks = append(t.tasks, caCertTask)
                }
diff --git a/pkg/trait/init_containers_test.go 
b/pkg/trait/init_containers_test.go
index afad65841..9fef79054 100644
--- a/pkg/trait/init_containers_test.go
+++ b/pkg/trait/init_containers_test.go
@@ -18,6 +18,7 @@ limitations under the License.
 package trait
 
 import (
+       "strings"
        "testing"
 
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
@@ -432,3 +433,236 @@ func TestApplyInitContainerWithCACert(t *testing.T) {
 
        assert.Contains(t, initContainer.Command[0], "keytool")
 }
+
+func TestApplyInitContainerWithMultipleCACerts(t *testing.T) {
+       deployment := &appsv1.Deployment{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name: "my-it",
+                       Labels: map[string]string{
+                               v1.IntegrationLabel: "my-it",
+                       },
+               },
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{},
+                       },
+               },
+       }
+       catalog, _ := camel.DefaultCatalog()
+       traitCatalog := NewCatalog(nil)
+       fakeClient, _ := internal.NewFakeClient(deployment)
+       environment := Environment{
+               Client:       fakeClient,
+               CamelCatalog: catalog,
+               Catalog:      traitCatalog,
+               Resources:    kubernetes.NewCollection(),
+               Integration: &v1.Integration{
+                       ObjectMeta: metav1.ObjectMeta{
+                               Name: "my-it",
+                       },
+                       Spec: v1.IntegrationSpec{
+                               Traits: v1.Traits{
+                                       JVM: &trait.JVMTrait{
+                                               CACerts: []string{
+                                                       
"/etc/camel/conf.d/_secrets/ca1/ca.crt",
+                                                       
"/etc/camel/conf.d/_secrets/ca2/ca.crt",
+                                                       
"/etc/camel/conf.d/_secrets/ca3/ca.crt",
+                                               },
+                                               CACertPassword: 
"/etc/camel/conf.d/_secrets/truststore-pass/password",
+                                       },
+                               },
+                       },
+                       Status: v1.IntegrationStatus{
+                               Phase: v1.IntegrationPhaseRunning,
+                       },
+               },
+               Platform: &v1.IntegrationPlatform{
+                       Spec: v1.IntegrationPlatformSpec{
+                               Cluster: v1.IntegrationPlatformClusterOpenShift,
+                               Build: v1.IntegrationPlatformBuildSpec{
+                                       PublishStrategy: 
v1.IntegrationPlatformBuildPublishStrategyJib,
+                                       Registry:        
v1.RegistrySpec{Address: "registry"},
+                                       RuntimeVersion:  
catalog.Runtime.Version,
+                               },
+                       },
+                       Status: v1.IntegrationPlatformStatus{
+                               Phase: v1.IntegrationPlatformPhaseReady,
+                       },
+               },
+       }
+       environment.Resources.Add(deployment)
+       environment.Platform.ResyncStatusFullConfig()
+       _, _, err := traitCatalog.apply(&environment)
+
+       require.NoError(t, err)
+
+       deploy := 
environment.Resources.GetDeploymentForIntegration(environment.Integration)
+       require.NotNil(t, deploy)
+
+       require.Len(t, deploy.Spec.Template.Spec.InitContainers, 1)
+       initContainer := deploy.Spec.Template.Spec.InitContainers[0]
+       assert.Equal(t, "generate-truststore", initContainer.Name)
+       assert.Equal(t, defaults.BaseImage(), initContainer.Image)
+
+       commandStr := strings.Join(initContainer.Command, " ")
+       assert.Contains(t, commandStr, "/bin/bash")
+       assert.Contains(t, commandStr, "keytool")
+       assert.Contains(t, commandStr, "custom-ca-0")
+       assert.Contains(t, commandStr, "custom-ca-1")
+       assert.Contains(t, commandStr, "custom-ca-2")
+       assert.Contains(t, commandStr, "/etc/camel/conf.d/_secrets/ca1/ca.crt")
+       assert.Contains(t, commandStr, "/etc/camel/conf.d/_secrets/ca2/ca.crt")
+       assert.Contains(t, commandStr, "/etc/camel/conf.d/_secrets/ca3/ca.crt")
+       assert.Contains(t, commandStr, "&&")
+}
+
+func TestApplyInitContainerWithCACertsBackwardCompatibility(t *testing.T) {
+       deployment := &appsv1.Deployment{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name: "my-it",
+                       Labels: map[string]string{
+                               v1.IntegrationLabel: "my-it",
+                       },
+               },
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{},
+                       },
+               },
+       }
+       catalog, _ := camel.DefaultCatalog()
+       traitCatalog := NewCatalog(nil)
+       fakeClient, _ := internal.NewFakeClient(deployment)
+       environment := Environment{
+               Client:       fakeClient,
+               CamelCatalog: catalog,
+               Catalog:      traitCatalog,
+               Resources:    kubernetes.NewCollection(),
+               Integration: &v1.Integration{
+                       ObjectMeta: metav1.ObjectMeta{
+                               Name: "my-it",
+                       },
+                       Spec: v1.IntegrationSpec{
+                               Traits: v1.Traits{
+                                       JVM: &trait.JVMTrait{
+                                               CACerts: []string{
+                                                       
"/etc/camel/conf.d/_secrets/ca1/ca.crt",
+                                               },
+                                               CACert:         
"/etc/camel/conf.d/_secrets/ca2/ca.crt",
+                                               CACertPassword: 
"/etc/camel/conf.d/_secrets/truststore-pass/password",
+                                       },
+                               },
+                       },
+                       Status: v1.IntegrationStatus{
+                               Phase: v1.IntegrationPhaseRunning,
+                       },
+               },
+               Platform: &v1.IntegrationPlatform{
+                       Spec: v1.IntegrationPlatformSpec{
+                               Cluster: v1.IntegrationPlatformClusterOpenShift,
+                               Build: v1.IntegrationPlatformBuildSpec{
+                                       PublishStrategy: 
v1.IntegrationPlatformBuildPublishStrategyJib,
+                                       Registry:        
v1.RegistrySpec{Address: "registry"},
+                                       RuntimeVersion:  
catalog.Runtime.Version,
+                               },
+                       },
+                       Status: v1.IntegrationPlatformStatus{
+                               Phase: v1.IntegrationPlatformPhaseReady,
+                       },
+               },
+       }
+       environment.Resources.Add(deployment)
+       environment.Platform.ResyncStatusFullConfig()
+       _, _, err := traitCatalog.apply(&environment)
+
+       require.NoError(t, err)
+
+       deploy := 
environment.Resources.GetDeploymentForIntegration(environment.Integration)
+       require.NotNil(t, deploy)
+
+       require.Len(t, deploy.Spec.Template.Spec.InitContainers, 1)
+       initContainer := deploy.Spec.Template.Spec.InitContainers[0]
+
+       commandStr := strings.Join(initContainer.Command, " ")
+       assert.Contains(t, commandStr, "/etc/camel/conf.d/_secrets/ca1/ca.crt")
+       assert.Contains(t, commandStr, "/etc/camel/conf.d/_secrets/ca2/ca.crt")
+}
+
+func TestApplyInitContainerWithSystemTruststore(t *testing.T) {
+       deployment := &appsv1.Deployment{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name: "my-it",
+                       Labels: map[string]string{
+                               v1.IntegrationLabel: "my-it",
+                       },
+               },
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{},
+                       },
+               },
+       }
+       catalog, _ := camel.DefaultCatalog()
+       traitCatalog := NewCatalog(nil)
+       fakeClient, _ := internal.NewFakeClient(deployment)
+       environment := Environment{
+               Client:       fakeClient,
+               CamelCatalog: catalog,
+               Catalog:      traitCatalog,
+               Resources:    kubernetes.NewCollection(),
+               Integration: &v1.Integration{
+                       ObjectMeta: metav1.ObjectMeta{
+                               Name: "my-it",
+                       },
+                       Spec: v1.IntegrationSpec{
+                               Traits: v1.Traits{
+                                       JVM: &trait.JVMTrait{
+                                               CACerts: []string{
+                                                       
"/etc/camel/conf.d/_secrets/my-ca/ca.crt",
+                                               },
+                                               CACertPassword:            
"/etc/camel/conf.d/_secrets/truststore-pass/password",
+                                               CACertUseSystemTruststore: 
ptr.To(true),
+                                       },
+                               },
+                       },
+                       Status: v1.IntegrationStatus{
+                               Phase: v1.IntegrationPhaseRunning,
+                       },
+               },
+               Platform: &v1.IntegrationPlatform{
+                       Spec: v1.IntegrationPlatformSpec{
+                               Cluster: v1.IntegrationPlatformClusterOpenShift,
+                               Build: v1.IntegrationPlatformBuildSpec{
+                                       PublishStrategy: 
v1.IntegrationPlatformBuildPublishStrategyJib,
+                                       Registry:        
v1.RegistrySpec{Address: "registry"},
+                                       RuntimeVersion:  
catalog.Runtime.Version,
+                               },
+                       },
+                       Status: v1.IntegrationPlatformStatus{
+                               Phase: v1.IntegrationPlatformPhaseReady,
+                       },
+               },
+       }
+       environment.Resources.Add(deployment)
+       environment.Platform.ResyncStatusFullConfig()
+       _, _, err := traitCatalog.apply(&environment)
+
+       require.NoError(t, err)
+
+       deploy := 
environment.Resources.GetDeploymentForIntegration(environment.Integration)
+       require.NotNil(t, deploy)
+
+       require.Len(t, deploy.Spec.Template.Spec.InitContainers, 1)
+       initContainer := deploy.Spec.Template.Spec.InitContainers[0]
+       assert.Equal(t, "generate-truststore", initContainer.Name)
+
+       commandStr := strings.Join(initContainer.Command, " ")
+       assert.Contains(t, commandStr, "/bin/bash")
+
+       assert.Contains(t, commandStr, "cp $JAVA_HOME/lib/security/cacerts")
+       assert.Contains(t, commandStr, "keytool -storepasswd")
+       assert.Contains(t, commandStr, "-storepass changeit")
+       assert.Contains(t, commandStr, "keytool -importcert")
+       assert.Contains(t, commandStr, 
"/etc/camel/conf.d/_secrets/my-ca/ca.crt")
+       assert.Contains(t, commandStr, "&&")
+}
diff --git a/pkg/trait/jvm_cacert.go b/pkg/trait/jvm_cacert.go
index 7d11f678e..87ecd4cdd 100644
--- a/pkg/trait/jvm_cacert.go
+++ b/pkg/trait/jvm_cacert.go
@@ -17,17 +17,22 @@ limitations under the License.
 
 package trait
 
-import "errors"
+import (
+       "k8s.io/utils/ptr"
+)
 
 const (
-       defaultCACertMountPath   = "/etc/camel/conf.d/_truststore"
-       caCertVolumeName         = "jvm-truststore"
-       trustStoreName           = "truststore.jks"
-       truststorePasswordEnvVar = "TRUSTSTORE_PASSWORD"
+       defaultCACertMountPath    = "/etc/camel/conf.d/_truststore"
+       caCertVolumeName          = "jvm-truststore"
+       trustStoreName            = "truststore.jks"
+       truststorePasswordEnvVar  = "TRUSTSTORE_PASSWORD"
+       jdkCacertsPath            = "$JAVA_HOME/lib/security/cacerts"
+       jdkCacertsDefaultPassword = "changeit"
 )
 
-func (t *jvmTrait) hasCACert() bool {
-       return t.CACert != ""
+// hasCACerts returns true if any CA certificates are configured (either via 
CACerts array or CACert).
+func (t *jvmTrait) hasCACerts() bool {
+       return len(t.CACerts) > 0 || t.CACert != ""
 }
 
 func (t *jvmTrait) getCACertMountPath() string {
@@ -42,24 +47,50 @@ func (t *jvmTrait) getTrustStorePath() string {
        return t.getCACertMountPath() + "/" + trustStoreName
 }
 
-// validateCACertConfig validates that the required file paths are provided.
-func (t *jvmTrait) validateCACertConfig() error {
-       if t.CACert == "" {
-               return nil
-       }
-       if t.CACertPassword == "" {
-               return errors.New("ca-cert-password is required when ca-cert is 
set")
+// hasCustomPassword returns true if a custom password file path is provided.
+func (t *jvmTrait) hasCustomPassword() bool {
+       return t.CACertPassword != ""
+}
+
+// getEffectiveTruststorePassword returns the password for the truststore.
+func (t *jvmTrait) getEffectiveTruststorePassword() string {
+       if t.hasCustomPassword() {
+               return "$(cat " + t.CACertPassword + ")"
        }
 
-       return nil
+       return jdkCacertsDefaultPassword
 }
 
-// getCACertPath returns the user-provided CA certificate file path.
-func (t *jvmTrait) getCACertPath() string {
-       return t.CACert
+// getAllCACertPaths returns all configured CA certificate paths.
+// It merges the CACert (if set) with the CACerts array.
+func (t *jvmTrait) getAllCACertPaths() []string {
+       var paths []string
+
+       paths = append(paths, t.CACerts...)
+
+       if t.CACert != "" {
+               found := false
+               for _, p := range paths {
+                       if p == t.CACert {
+                               found = true
+
+                               break
+                       }
+               }
+               if !found {
+                       paths = append(paths, t.CACert)
+               }
+       }
+
+       return paths
 }
 
 // getCACertPasswordPath returns the user-provided password file path.
 func (t *jvmTrait) getCACertPasswordPath() string {
        return t.CACertPassword
 }
+
+// useSystemTruststore returns true if JDK's default cacerts should be used as 
base.
+func (t *jvmTrait) useSystemTruststore() bool {
+       return ptr.Deref(t.CACertUseSystemTruststore, false)
+}
diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go
index 7402d748a..f0290a530 100644
--- a/pkg/trait/jvm_test.go
+++ b/pkg/trait/jvm_test.go
@@ -752,24 +752,6 @@ func TestApplyJvmTraitWithCACert(t *testing.T) {
        assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Djavax.net.ssl.trustStorePassword=$(TRUSTSTORE_PASSWORD)")
 }
 
-func TestValidateCACertConfig(t *testing.T) {
-       trait, _ := createNominalJvmTest(v1.IntegrationKitTypePlatform)
-
-       trait.CACert = ""
-       err := trait.validateCACertConfig()
-       require.NoError(t, err)
-
-       trait.CACert = "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
-       trait.CACertPassword = ""
-       err = trait.validateCACertConfig()
-       require.Error(t, err)
-       assert.Contains(t, err.Error(), "ca-cert-password is required")
-
-       trait.CACertPassword = 
"/etc/camel/conf.d/_secrets/truststore-pass/password"
-       err = trait.validateCACertConfig()
-       require.NoError(t, err)
-}
-
 func TestApplyJvmTraitWithCustomCACertMountPath(t *testing.T) {
        trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
        trait.CACert = "/etc/camel/conf.d/_secrets/my-ca/ca.crt"
@@ -802,3 +784,92 @@ func TestApplyJvmTraitWithCustomCACertMountPath(t 
*testing.T) {
        assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Djavax.net.ssl.trustStore=/custom/truststore/path/truststore.jks")
        assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Djavax.net.ssl.trustStorePassword=$(TRUSTSTORE_PASSWORD)")
 }
+
+func TestGetAllCACertPaths(t *testing.T) {
+       trait, _ := createNominalJvmTest(v1.IntegrationKitTypePlatform)
+
+       trait.CACerts = []string{"/path/to/ca1.crt", "/path/to/ca2.crt"}
+       trait.CACert = ""
+       paths := trait.getAllCACertPaths()
+       assert.Len(t, paths, 2)
+       assert.Contains(t, paths, "/path/to/ca1.crt")
+       assert.Contains(t, paths, "/path/to/ca2.crt")
+
+       trait.CACerts = nil
+       trait.CACert = "/path/to/legacy.crt"
+       paths = trait.getAllCACertPaths()
+       assert.Len(t, paths, 1)
+       assert.Contains(t, paths, "/path/to/legacy.crt")
+
+       trait.CACerts = []string{"/path/to/ca1.crt", "/path/to/ca2.crt"}
+       trait.CACert = "/path/to/ca3.crt"
+       paths = trait.getAllCACertPaths()
+       assert.Len(t, paths, 3)
+       assert.Contains(t, paths, "/path/to/ca1.crt")
+       assert.Contains(t, paths, "/path/to/ca2.crt")
+       assert.Contains(t, paths, "/path/to/ca3.crt")
+
+       trait.CACerts = []string{"/path/to/ca1.crt"}
+       trait.CACert = "/path/to/ca1.crt"
+       paths = trait.getAllCACertPaths()
+       assert.Len(t, paths, 1)
+       assert.Contains(t, paths, "/path/to/ca1.crt")
+
+       trait.CACerts = nil
+       trait.CACert = ""
+       paths = trait.getAllCACertPaths()
+       assert.Len(t, paths, 0)
+}
+
+func TestHasCACerts(t *testing.T) {
+       trait, _ := createNominalJvmTest(v1.IntegrationKitTypePlatform)
+
+       trait.CACerts = nil
+       trait.CACert = ""
+       assert.False(t, trait.hasCACerts())
+
+       trait.CACerts = []string{"/path/to/ca1.crt"}
+       trait.CACert = ""
+       assert.True(t, trait.hasCACerts())
+
+       trait.CACerts = nil
+       trait.CACert = "/path/to/legacy.crt"
+       assert.True(t, trait.hasCACerts())
+
+       trait.CACerts = []string{"/path/to/ca1.crt"}
+       trait.CACert = "/path/to/ca2.crt"
+       assert.True(t, trait.hasCACerts())
+}
+
+func TestHasCustomPassword(t *testing.T) {
+       trait, _ := createNominalJvmTest(v1.IntegrationKitTypePlatform)
+
+       trait.CACertPassword = ""
+       assert.False(t, trait.hasCustomPassword())
+
+       trait.CACertPassword = "/path/to/password"
+       assert.True(t, trait.hasCustomPassword())
+}
+
+func TestGetEffectiveTruststorePassword(t *testing.T) {
+       trait, _ := createNominalJvmTest(v1.IntegrationKitTypePlatform)
+
+       trait.CACertPassword = ""
+       assert.Equal(t, "changeit", trait.getEffectiveTruststorePassword())
+
+       trait.CACertPassword = "/path/to/password"
+       assert.Equal(t, "$(cat /path/to/password)", 
trait.getEffectiveTruststorePassword())
+}
+
+func TestUseSystemTruststore(t *testing.T) {
+       trait, _ := createNominalJvmTest(v1.IntegrationKitTypePlatform)
+
+       trait.CACertUseSystemTruststore = nil
+       assert.False(t, trait.useSystemTruststore())
+
+       trait.CACertUseSystemTruststore = ptr.To(false)
+       assert.False(t, trait.useSystemTruststore())
+
+       trait.CACertUseSystemTruststore = ptr.To(true)
+       assert.True(t, trait.useSystemTruststore())
+}
diff --git a/pkg/trait/mount.go b/pkg/trait/mount.go
index 3e25bad0f..4322df614 100644
--- a/pkg/trait/mount.go
+++ b/pkg/trait/mount.go
@@ -205,7 +205,7 @@ func (t *mountTrait) configureVolumesAndMounts(
                }
 
                // Mount CA cert truststore volume if configured
-               if ok && jvm.hasCACert() {
+               if ok && jvm.hasCACerts() {
                        mountPath := jvm.getCACertMountPath()
 
                        // EmptyDir volume for truststore output

Reply via email to