Skip to content

Add company-internal CA extension point to eSignet Helm chart#1990

Draft
Ivanmeneges wants to merge 1 commit into
developfrom
cursor/internal-ca-helm-extension-403f
Draft

Add company-internal CA extension point to eSignet Helm chart#1990
Ivanmeneges wants to merge 1 commit into
developfrom
cursor/internal-ca-helm-extension-403f

Conversation

@Ivanmeneges

@Ivanmeneges Ivanmeneges commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds first-class Helm support for trusting a company-internal CA in eSignet deployments, addressing the gap where only the development-oriented enable_insecure workaround existed.

Changes

Helm chart (helm/esignet)

  • New customCA values block to mount a Secret/ConfigMap with PEM-encoded root/intermediate CA certificate(s)
  • Init container imports the CA bundle into the Java cacerts truststore before the app starts
  • Wired previously unused extraVolumes / extraVolumeMounts extension points in the deployment template
  • Added extraInitContainers for additional custom init hooks
  • Validation prevents using customCA and enable_insecure together

Deploy scripts

  • New shared deploy/configure_tls_trust.sh helper used by eSignet install scripts
  • Install flow now offers three TLS trust options:
    1. Public SSL (default)
    2. Development self-signed (enable_insecure)
    3. Company internal CA (customCA)

Documentation

  • Updated helm/esignet/README.md with usage examples
  • Added commented customCA samples in deploy values files

Usage

kubectl -n esignet create secret generic company-internal-ca \
  --from-file=ca.crt=/path/to/company-ca-bundle.pem

helm upgrade --install esignet mosip/esignet \
  --set customCA.enabled=true \
  --set customCA.secretName=company-internal-ca

Notes

  • enable_insecure remains available for dev/self-signed environments but is mutually exclusive with customCA
  • Supports PEM bundles containing multiple certificates (root + intermediate)
  • OIDC UI is unchanged (nginx-based; no Java truststore requirement)
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Added support for trusting company-internal CA certificates for outbound HTTPS, including an init-step to import PEM CAs into the Java truststore.
    • Added an interactive TLS trust configuration during deployment with three modes: public CAs, development/self-signed workaround, or custom internal CA.
  • Documentation

    • Added TLS trust configuration docs with examples and usage guidance.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds an interactive TLS trust helper and integrates it into installer scripts; extends Helm chart values and templates to support an optional company-internal CA bundle (Secret/ConfigMap), an init container that builds a Java truststore from PEMs, and deployment wiring to mount the truststore and CA bundle.

Changes

Custom Company CA Trust Support

Layer / File(s) Summary
TLS Trust Configuration CLI Helper
deploy/configure_tls_trust.sh
New interactive Bash function configure_tls_trust(namespace) prompts for TLS mode (default, insecure, custom CA), checks/creates a Kubernetes Secret from a PEM bundle when chosen, and exports TRUST_HELM_ARGS for Helm installs.
Installer Script Integration
deploy/esignet/install.sh, deploy/esignet-with-plugins/install.sh, deploy/esignet/values.yaml, deploy/esignet-with-plugins/values.yaml
Installer scripts now source the shared TLS helper and call configure_tls_trust "$NS" to compute $TRUST_HELM_ARGS, then pass those args to Helm; deploy-level values.yaml files include commented customCA examples.
Helm Values Schema and Documentation
helm/esignet/values.yaml, helm/esignet/README.md
Adds extraInitContainers and a customCA values block (enable, Secret/ConfigMap, mountPath, aliasPrefix, javaHome, keystorePassword, initContainerImage). README documents three TLS modes, examples, mutual exclusivity, and extension points.
Helm Template Validation Helpers
helm/esignet/templates/_helpers.tpl
New helpers: esignet.truststoreRequired, esignet.customCAInitImage, and esignet.validateValues.customCA; esignet.validateValues now includes custom CA validation messages.
Custom CA Init Container Implementation
helm/esignet/templates/custom-ca-initcontainer.yaml
New named template esignet.customCAInitContainer defines an init container that copies Java cacerts to a writable keystore, validates and splits a PEM bundle, imports certificates via keytool with aliases, fails if none imported, and wires writable cacerts and read-only CA bundle mounts.
Deployment Template Integration
helm/esignet/templates/deployment.yaml
Deployment now conditionally renders the custom CA init container when enabled, uses esignet.truststoreRequired to mount cacerts at configured Java home, adds a company-ca-bundle volume from Secret/ConfigMap when customCA.enabled, and preserves extension hooks (extraVolumeMounts, extraVolumes, extraInitContainers).

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant InstallerScript as Installer Script
  participant TLSHelper as TLS Helper<br/>configure_tls_trust
  participant Kubectl
  participant HelmChart as Helm Chart
  participant JavaService as Java Service

  User->>InstallerScript: Run install.sh
  InstallerScript->>TLSHelper: source and call configure_tls_trust($NS)
  User->>TLSHelper: Select TLS mode
  alt Custom CA Mode
    TLSHelper->>Kubectl: Check Secret exists
    alt Secret missing
      User->>TLSHelper: Provide PEM CA bundle path
      TLSHelper->>Kubectl: Create CA Secret in namespace
    end
    TLSHelper-->>InstallerScript: TRUST_HELM_ARGS with customCA
  else Insecure Mode
    TLSHelper-->>InstallerScript: TRUST_HELM_ARGS with enable_insecure=true
  else Default Mode
    TLSHelper-->>InstallerScript: TRUST_HELM_ARGS (empty)
  end
  InstallerScript->>HelmChart: helm install/upgrade with $TRUST_HELM_ARGS
  HelmChart->>JavaService: render/init customCA init container
  JavaService->>JavaService: init container builds truststore and imports certs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Poem

🐰 I hopped in to fetch the PEM so fine,
I split the bundle, one cert at a time,
Keytool danced and aliases grew,
The truststore woke — HTTPS anew,
Hop hop, secure connections — that's divine!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding company-internal CA support to the eSignet Helm chart, which is the primary objective across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/internal-ca-helm-extension-403f

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@deploy/configure_tls_trust.sh`:
- Around line 27-39: The script enables customCA by setting TRUST_HELM_ARGS with
customCA.enabled and customCA.secretName but doesn't validate or propagate
customCA.secretKey; update deploy/configure_tls_trust.sh to check the existing
Secret (variable ca_secret in the script) for the expected key (default "ca.crt"
or a user-provided key), fail with an informative message if the key is missing,
and append --set customCA.secretKey=<key> to TRUST_HELM_ARGS when setting
customCA.enabled=true so the Helm chart's init container (which reads
customCA.secretKey) can find the PEM bundle.

In `@helm/esignet/templates/_helpers.tpl`:
- Around line 73-82: In the template defined by
"esignet.validateValues.customCA" add a validation branch that detects when
.Values.customCA.enabled is true AND both .Values.customCA.secretName and
.Values.customCA.configMapName are non-empty, and emit an error message
indicating that both cannot be set simultaneously (explain that Secret takes
precedence and one must be removed); update the conditional logic alongside the
existing checks for missing names and enable_insecure to ensure this new
mutually-exclusive check runs when customCA.enabled is true.
- Around line 52-54: esignet.validateValues must actively block invalid flag
combinations and be invoked during chart rendering: update the validate function
(esignet.validateValues) to call {{ failf }} when .Values.enable_insecure and
.Values.customCA.enabled are both true (or otherwise enforce a single source of
truth), then include a call to that helper from top-level templates (e.g.,
deployment.yaml and other rendered templates) so validation runs; additionally,
change the init container rendering logic so the enable_insecure init container
(the initContainers block that copies /cacerts) is only rendered when
.Values.enable_insecure is true AND .Values.customCA.enabled is false, or alter
its copy behavior to avoid overwriting the cacerts volume when
customCAInitContainer is enabled, referencing the customCAInitContainer, the
initContainers block, and the cacerts volume to locate the code to change.

In `@helm/esignet/values.yaml`:
- Around line 527-549: The values.yaml default for customCA.javaHome may not
match the Java installation in the main app image, causing the init container to
mount/update the wrong truststore; update either by adding a clear comment near
customCA.javaHome (and mention mountPath and that it must match the main
container JAVA_HOME) or add a runtime validation step in the init container
entrypoint (the init container that uses initContainerImage and writes to {{
.Values.customCA.javaHome }}/lib/security/cacerts) to check that
$JAVA_HOME/lib/security/cacerts exists at the target mountPath and exit with a
clear error if not found so the mismatch is detected early.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 80f08999-cf89-4492-a069-9b0aae7e3b6a

📥 Commits

Reviewing files that changed from the base of the PR and between 9ed9e02 and 31fd675.

📒 Files selected for processing (10)
  • deploy/configure_tls_trust.sh
  • deploy/esignet-with-plugins/install.sh
  • deploy/esignet-with-plugins/values.yaml
  • deploy/esignet/install.sh
  • deploy/esignet/values.yaml
  • helm/esignet/README.md
  • helm/esignet/templates/_helpers.tpl
  • helm/esignet/templates/custom-ca-initcontainer.yaml
  • helm/esignet/templates/deployment.yaml
  • helm/esignet/values.yaml

Comment on lines +27 to +39
if ! kubectl -n "$ns" get secret "$ca_secret" >/dev/null 2>&1; then
read -p "Secret '$ca_secret' not found. Provide path to PEM CA bundle file: " ca_file
if [[ -z "${ca_file}" || ! -f "${ca_file}" ]]; then
echo "CA bundle file not found; EXITING"
exit 1
fi
kubectl -n "$ns" create secret generic "$ca_secret" \
--from-file=ca.crt="${ca_file}" \
--dry-run=client -o yaml | kubectl apply -f -
echo "Created Secret '$ca_secret' with company CA bundle."
fi

TRUST_HELM_ARGS="--set customCA.enabled=true --set customCA.secretName=${ca_secret}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify helper/chart key contract alignment
rg -n 'customCA\.secretName|customCA\.secretKey|secretKey:\s*ca\.crt|configMapKey:\s*ca\.crt' \
  deploy/configure_tls_trust.sh \
  helm/esignet/values.yaml \
  helm/esignet/templates/custom-ca-initcontainer.yaml

Repository: mosip/esignet

Length of output: 509


Propagate/validate customCA.secretKey when using an existing CA Secret

The Helm init container builds CA_FILE from customCA.secretKey whenever customCA.secretName is set (defaulting to secretKey: ca.crt). deploy/configure_tls_trust.sh enables only --set customCA.secretName=... for an existing Secret, so if that Secret’s data key isn’t ca.crt (or the configured secretKey), the init container won’t find the mounted PEM file and the pod can fail to start.
Validate the Secret contains the expected key and set --set customCA.secretKey=... accordingly when enabling customCA.enabled=true.

🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 28-28: read without -r will mangle backslashes.

(SC2162)


[warning] 39-39: TRUST_HELM_ARGS appears unused. Verify use (or export if used externally).

(SC2034)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deploy/configure_tls_trust.sh` around lines 27 - 39, The script enables
customCA by setting TRUST_HELM_ARGS with customCA.enabled and
customCA.secretName but doesn't validate or propagate customCA.secretKey; update
deploy/configure_tls_trust.sh to check the existing Secret (variable ca_secret
in the script) for the expected key (default "ca.crt" or a user-provided key),
fail with an informative message if the key is missing, and append --set
customCA.secretKey=<key> to TRUST_HELM_ARGS when setting customCA.enabled=true
so the Helm chart's init container (which reads customCA.secretKey) can find the
PEM bundle.

Comment on lines +52 to +54
{{- define "esignet.truststoreRequired" -}}
{{- or .Values.enable_insecure .Values.customCA.enabled -}}
{{- end -}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for where esignet.validateValues is called and whether fail is used
rg -n 'esignet.validateValues' --type=yaml -B 2 -A 5

# Look for Helm fail patterns in templates
rg -n '\{\{-?\s*fail\s+' helm/esignet/templates/ --type=yaml

Repository: mosip/esignet

Length of output: 39


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Find all occurrences of validateValues (any template extension, not just yaml)
rg -n 'esignet\.validateValues|validateValues' helm/esignet/templates -S

# 2) Find the helper definition for validateValues (if it exists)
rg -n 'define\s+"esignet\.validateValues"' -S helm/esignet/templates

# 3) Check whether any template uses Helm's hard-fail ({{ fail ... }})
rg -n '\{\{-?\s*fail\s+' helm/esignet/templates -S

# 4) Check for 'required' and 'failf' style patterns too (commonly used in charts)
rg -n '\{\{-?\s*(required|failf)\s+' helm/esignet/templates -S

Repository: mosip/esignet

Length of output: 662


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="helm/esignet/templates/_helpers.tpl"

echo "---- validateValues definition (lines 1-140) ----"
nl -ba "$FILE" | sed -n '1,140p'

echo "---- locate calls to validateValues helper ----"
rg -n 'include\s+"esignet\.validateValues"|esignet\.validateValues' helm/esignet/templates -S

echo "---- check for fail/failf/required usage in entire templates dir ----"
rg -n '\{\{-?\s*(fail|failf)\s+' helm/esignet/templates -S || true
rg -n '\{\{-?\s*required\s+' helm/esignet/templates -S || true

Repository: mosip/esignet

Length of output: 168


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="helm/esignet/templates/_helpers.tpl"

echo "---- validateValues definition (whole file, capped at 220 lines) ----"
# show with line numbers (cat -n available)
cat -n "$FILE" | sed -n '1,220p'

echo "---- locate calls to validateValues helper ----"
rg -n 'include\s+"esignet\.validateValues"|include\s+"esignet\.validateValues\.' helm/esignet/templates -S

echo "---- check for fail/failf/required usage in entire templates dir ----"
rg -n '\{\{-?\s*(fail|failf)\s+' helm/esignet/templates -S || true
rg -n '\{\{-?\s*required\s+' helm/esignet/templates -S || true

echo "---- check where validation messages are emitted (if any) ----"
rg -n 'messages|print|printf' helm/esignet/templates/_helpers.tpl -S

Repository: mosip/esignet

Length of output: 5312


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- all occurrences of validateValues usage ----"
rg -n 'validateValues' helm/esignet/templates -S

echo "---- specifically look for including the root helper ----"
rg -n 'include\s+"esignet\.validateValues"\s' helm/esignet/templates -S

echo "---- also handle calling by name without include (rare) ----"
rg -n 'esignet\.validateValues\s' helm/esignet/templates -S

Repository: mosip/esignet

Length of output: 691


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- validateValues usage anywhere under helm/esignet ----"
rg -n 'validateValues' helm/esignet -S

echo "---- check for the printed validation banner string ----"
rg -n 'VALUES VALIDATION' helm/esignet -S || true

echo "---- check for any template that might deliberately call include/esignet.validateValues indirectly ----"
rg -n 'include\s+"esignet\.' helm/esignet/templates -S | head -n 50

Repository: mosip/esignet

Length of output: 1880


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="helm/esignet/templates/deployment.yaml"
echo "---- deployment.yaml around truststoreRequired usages (lines 130-220) ----"
cat -n "$FILE" | sed -n '130,230p'

echo "---- find initContainers blocks to see gating conditions (up to 260) ----"
rg -n 'initContainers:|customCA|enable_insecure|cacerts|truststoreRequired' "$FILE" -S

echo "---- deployment.yaml around cacerts mounts (lines 150-210) ----"
rg -n 'cacerts|truststoreRequired' "$FILE" -n -S

Repository: mosip/esignet

Length of output: 5300


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="helm/esignet/templates/deployment.yaml"
cat -n "$FILE" | sed -n '40,120p'

Repository: mosip/esignet

Length of output: 4802


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Confirm validateValues helper is never invoked
rg -n 'include\s+"esignet\.validateValues"' -S helm/esignet || true
rg -n 'esignet\.validateValues' -S helm/esignet || true

# 2) Inspect customCA init container template to see how it uses the cacerts volume
rg -n 'define "esignet\.customCAInitContainer"' -S helm/esignet/templates/_helpers.tpl
# print around it
FILE="helm/esignet/templates/_helpers.tpl"
start=$(rg -n 'define "esignet\.customCAInitContainer"' "$FILE" -n | cut -d: -f1 | head -n1)
echo "customCAInitContainer starts at line $start"
cat -n "$FILE" | sed -n "${start},$((start+120))p"

# 3) Inspect values for enable_insecure and initContainers
VALS="helm/esignet/values.yaml"
ls -la helm/esignet | cat
rg -n 'enable_insecure|initContainers|customCA' "$VALS" -S || true
# print relevant sections if present
cat -n "$VALS" | sed -n '1,260p'

Repository: mosip/esignet

Length of output: 583


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- helper definitions for customCA init container ----"
rg -n 'define "esignet\.customCAInitContainer"|customCAInitContainer' helm/esignet/templates/_helpers.tpl -S || true
FILE="helm/esignet/templates/_helpers.tpl"
# Try to print around the helper if it exists
LINE=$(rg -n 'define "esignet\.customCAInitContainer"' "$FILE" -S | cut -d: -f1 | head -n1 || true)
if [ -n "${LINE:-}" ]; then
  cat -n "$FILE" | sed -n "$LINE,$((LINE+160))p"
fi

echo "---- locate values files ----"
find helm/esignet -maxdepth 1 -type f -name 'values*.yaml' -o -name 'values*.yml' -print

echo "---- grep enable_insecure/customCA-related values across chart root values files ----"
for f in $(find helm/esignet -maxdepth 1 -type f -name 'values*.yaml' -o -name 'values*.yml' -print); do
  echo "### $f"
  rg -n 'enable_insecure|customCA|initContainers|cacerts' "$f" -S || true
done

echo "---- inspect deployment.yaml init container gating for customCA vs enable_insecure (lines 50-110 already partly shown; show full block) ----"
cat -n helm/esignet/templates/deployment.yaml | sed -n '45,110p'

Repository: mosip/esignet

Length of output: 4137


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- rg for esignet.customCAInitContainer definition/inclusions ----"
rg -n 'esignet\.customCAInitContainer' helm/esignet/templates -S

echo "---- locate values files ----"
find helm/esignet -maxdepth 2 -type f \( -name 'values.yaml' -o -name 'values.yml' -o -name 'values.*.yaml' -o -name 'values.*.yml' \) -print

# pick whatever exists
for f in $(find helm/esignet -maxdepth 2 -type f \( -name 'values.yaml' -o -name 'values.yml' -o -name 'values.*.yaml' -o -name 'values.*.yml' \) -print); do
  echo "### $f"
  rg -n 'enable_insecure|customCA|initContainers|cacerts' "$f" -S || true
done

Repository: mosip/esignet

Length of output: 941


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- custom-ca-initcontainer.yaml (full file, likely small) ----"
cat -n helm/esignet/templates/custom-ca-initcontainer.yaml | sed -n '1,220p'

echo "---- values.yaml: initContainers section for enable_insecure ----"
# print around initContainers block
cat -n helm/esignet/values.yaml | sed -n '300,430p'

echo "---- values.yaml: customCA.enabled/related keys ----"
rg -n '^customCA:|enable_insecure:' helm/esignet/values.yaml -n || true
cat -n helm/esignet/values.yaml | sed -n '500,620p'

Repository: mosip/esignet

Length of output: 9722


Fix: validation doesn’t prevent deploying conflicting enable_insecure + customCA.enabled

  • esignet.validateValues only emits text (printf "\nVALUES VALIDATION:\n%s" ...) and never calls {{ fail }}/failf, and esignet.validateValues isn’t invoked anywhere in the chart templates—so the customCA validation at _helpers.tpl (lines 78-81) won’t block rendering.
  • With both flags true, deployment.yaml renders both init containers (customCAInitContainer under .Values.customCA.enabled and the initContainers block under .Values.enable_insecure) and both write to the same cacerts volume (via /cacerts/cacerts). The enable_insecure init container overwrites /cacerts by copying the keystore (cp ...cacerts /cacerts), which can wipe the imported company CA certs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@helm/esignet/templates/_helpers.tpl` around lines 52 - 54,
esignet.validateValues must actively block invalid flag combinations and be
invoked during chart rendering: update the validate function
(esignet.validateValues) to call {{ failf }} when .Values.enable_insecure and
.Values.customCA.enabled are both true (or otherwise enforce a single source of
truth), then include a call to that helper from top-level templates (e.g.,
deployment.yaml and other rendered templates) so validation runs; additionally,
change the init container rendering logic so the enable_insecure init container
(the initContainers block that copies /cacerts) is only rendered when
.Values.enable_insecure is true AND .Values.customCA.enabled is false, or alter
its copy behavior to avoid overwriting the cacerts volume when
customCAInitContainer is enabled, referencing the customCAInitContainer, the
initContainers block, and the cacerts volume to locate the code to change.

Comment on lines +73 to +82
{{- define "esignet.validateValues.customCA" -}}
{{- if and .Values.customCA.enabled (and (not .Values.customCA.secretName) (not .Values.customCA.configMapName)) -}}
esignet: customCA.enabled
When customCA.enabled is true, set either customCA.secretName or customCA.configMapName.
{{- end -}}
{{- if and .Values.enable_insecure .Values.customCA.enabled -}}
esignet: customCA.enable_insecure
enable_insecure and customCA.enabled cannot be used together. Use customCA for company-internal PKI.
{{- end -}}
{{- end -}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add validation when both secretName and configMapName are set.

The validation at line 74 ensures at least one of secretName or configMapName is set when customCA.enabled is true. However, it doesn't validate the case where both are set simultaneously.

According to the deployment template (context snippet from deployment.yaml:187-194), when both are set, the Secret takes precedence and the ConfigMap is silently ignored:

{{- if .Values.customCA.secretName }}
secret:
  secretName: {{ .Values.customCA.secretName }}
{{- else }}
configMap:
  name: {{ .Values.customCA.configMapName }}

This could lead to silent misconfiguration where a user sets both, expecting the ConfigMap to be used, but the Secret is selected instead.

🔒 Suggested validation enhancement
 {{- define "esignet.validateValues.customCA" -}}
 {{- if and .Values.customCA.enabled (and (not .Values.customCA.secretName) (not .Values.customCA.configMapName)) -}}
 esignet: customCA.enabled
     When customCA.enabled is true, set either customCA.secretName or customCA.configMapName.
 {{- end -}}
+{{- if and .Values.customCA.enabled (and .Values.customCA.secretName .Values.customCA.configMapName) -}}
+esignet: customCA.source
+    Set either customCA.secretName or customCA.configMapName, not both.
+{{- end -}}
 {{- if and .Values.enable_insecure .Values.customCA.enabled -}}
 esignet: customCA.enable_insecure
     enable_insecure and customCA.enabled cannot be used together. Use customCA for company-internal PKI.
 {{- end -}}
 {{- end -}}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@helm/esignet/templates/_helpers.tpl` around lines 73 - 82, In the template
defined by "esignet.validateValues.customCA" add a validation branch that
detects when .Values.customCA.enabled is true AND both
.Values.customCA.secretName and .Values.customCA.configMapName are non-empty,
and emit an error message indicating that both cannot be set simultaneously
(explain that Secret takes precedence and one must be removed); update the
conditional logic alongside the existing checks for missing names and
enable_insecure to ensure this new mutually-exclusive check runs when
customCA.enabled is true.

Comment thread helm/esignet/values.yaml
Comment on lines +527 to +549
## Trust a company-internal CA for outbound HTTPS calls from the Java service.
## Create a Secret or ConfigMap with PEM-encoded root/intermediate certificate(s)
## before enabling this option. Recommended for on-prem deployments using internal PKI.
##
customCA:
enabled: false
## Use an existing Secret that contains PEM-encoded CA certificate(s).
secretName: ""
secretKey: ca.crt
## Alternatively, use a ConfigMap instead of a Secret.
configMapName: ""
configMapKey: ca.crt
## Path where the CA bundle is mounted inside the init container.
mountPath: /etc/ssl/certs/company-ca
## Prefix used for keytool aliases when importing certificates.
aliasPrefix: company-ca
javaHome: /usr/local/openjdk-11
keystorePassword: changeit
initContainerImage:
registry: docker.io
repository: openjdk
tag: 11-jre
pullPolicy: Always

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Document or validate javaHome compatibility.

The customCA.javaHome default assumes OpenJDK 11 at /usr/local/openjdk-11, matching the existing enable_insecure init container pattern (line 346). However, if the main application image (mosipdev/esignet-with-plugins:develop, line 55) uses a different Java installation path or version, the truststore mount at {{ .Values.customCA.javaHome }}/lib/security/cacerts will fail silently—Java will continue using the default system truststore instead of the custom one.

Consider either:

  1. Adding a comment in values.yaml noting that javaHome must match the Java installation in the main container image, or
  2. Adding runtime validation in the init container to verify $JAVA_HOME/lib/security/cacerts exists in the target mount location
📝 Suggested documentation addition
   aliasPrefix: company-ca
+  ## Must match the Java installation path in the main application container.
+  ## Verify this matches the JAVA_HOME in mosipdev/esignet-with-plugins image.
   javaHome: /usr/local/openjdk-11
   keystorePassword: changeit
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@helm/esignet/values.yaml` around lines 527 - 549, The values.yaml default for
customCA.javaHome may not match the Java installation in the main app image,
causing the init container to mount/update the wrong truststore; update either
by adding a clear comment near customCA.javaHome (and mention mountPath and that
it must match the main container JAVA_HOME) or add a runtime validation step in
the init container entrypoint (the init container that uses initContainerImage
and writes to {{ .Values.customCA.javaHome }}/lib/security/cacerts) to check
that $JAVA_HOME/lib/security/cacerts exists at the target mountPath and exit
with a clear error if not found so the mismatch is detected early.

Introduce customCA values and init container to import PEM-encoded
corporate CA bundles into the Java truststore. Wire extraVolumes and
extraVolumeMounts in the deployment template, and update install scripts
with a dedicated TLS trust configuration option.

Co-authored-by: Ivanmeneges <Ivanmeneges@users.noreply.github.com>
Signed-off-by: Cursor Agent <cursoragent@cursor.com>
@cursor cursor Bot force-pushed the cursor/internal-ca-helm-extension-403f branch from 31fd675 to 8a8e13a Compare June 11, 2026 07:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@helm/esignet/templates/custom-ca-initcontainer.yaml`:
- Line 18: The cp command copying "${JAVA_HOME}/lib/security/cacerts" to
"${KEYSTORE}" can fail with an opaque "No such file or directory" when
customCA.javaHome is wrong; update the initContainer command that contains cp
"${JAVA_HOME}/lib/security/cacerts" "${KEYSTORE}" to first test for the source
file and exit with a descriptive error that includes the resolved
JAVA_HOME/customCA.javaHome (e.g., if [ -f "${JAVA_HOME}/lib/security/cacerts"
]; then cp ...; else echo "ERROR: Java cacerts not found at
${JAVA_HOME}/lib/security/cacerts — ensure customCA.javaHome matches the Java
installation in the image" >&2; exit 1; fi), so operators see the bad javaHome
value and can fix values.yaml.

In `@helm/esignet/templates/deployment.yaml`:
- Around line 75-80: Call the existing validation template and add a runtime
guard so both init containers cannot be rendered together: invoke the
esignet.validateValues template near the top of deployment.yaml (before any
conditional init-container logic) and modify the enable_insecure init-container
block (the include of "common.tplvalues.render" for .Values.initContainers) to
only render when .Values.enable_insecure is true AND .Values.customCA.enabled is
false; also update the esignet.validateValues helper in _helpers.tpl to
return/throw a failure (not just print) when customCA.enabled and
enable_insecure are both true so Helm install/upgrade fails early.

In `@helm/esignet/values.yaml`:
- Around line 371-373: The default value for extraInitContainers is currently an
empty map ({}) but must be an array; update the values.yaml entry named
extraInitContainers to be an empty list ([]) so templates that call
common.tplvalues.render on extraInitContainers produce a YAML list of init
containers instead of a dict, avoiding invalid Kubernetes manifests when
rendering initContainers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3ccde635-a505-4632-b21d-183ba2977da5

📥 Commits

Reviewing files that changed from the base of the PR and between 31fd675 and 8a8e13a.

📒 Files selected for processing (10)
  • deploy/configure_tls_trust.sh
  • deploy/esignet-with-plugins/install.sh
  • deploy/esignet-with-plugins/values.yaml
  • deploy/esignet/install.sh
  • deploy/esignet/values.yaml
  • helm/esignet/README.md
  • helm/esignet/templates/_helpers.tpl
  • helm/esignet/templates/custom-ca-initcontainer.yaml
  • helm/esignet/templates/deployment.yaml
  • helm/esignet/values.yaml

ALIAS_PREFIX="{{ .Values.customCA.aliasPrefix }}"
CA_FILE="{{ .Values.customCA.mountPath }}/{{ if .Values.customCA.secretName }}{{ .Values.customCA.secretKey }}{{ else }}{{ .Values.customCA.configMapKey }}{{ end }}"

cp "${JAVA_HOME}/lib/security/cacerts" "${KEYSTORE}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Improve error message when javaHome path is incorrect.

If customCA.javaHome doesn't match the actual Java installation in the init container image, the cp command at line 18 will fail with a generic "No such file or directory" error. This makes it difficult for operators to diagnose that they need to update the javaHome value in values.yaml.

💡 Proposed improvement
       CA_FILE="{{ .Values.customCA.mountPath }}/{{ if .Values.customCA.secretName }}{{ .Values.customCA.secretKey }}{{ else }}{{ .Values.customCA.configMapKey }}{{ end }}"

+      if [[ ! -f "${JAVA_HOME}/lib/security/cacerts" ]]; then
+        echo "Java cacerts not found at ${JAVA_HOME}/lib/security/cacerts"
+        echo "Verify that customCA.javaHome (${JAVA_HOME}) matches the Java installation in this image"
+        exit 1
+      fi
+
       cp "${JAVA_HOME}/lib/security/cacerts" "${KEYSTORE}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cp "${JAVA_HOME}/lib/security/cacerts" "${KEYSTORE}"
CA_FILE="{{ .Values.customCA.mountPath }}/{{ if .Values.customCA.secretName }}{{ .Values.customCA.secretKey }}{{ else }}{{ .Values.customCA.configMapKey }}{{ end }}"
if [[ ! -f "${JAVA_HOME}/lib/security/cacerts" ]]; then
echo "Java cacerts not found at ${JAVA_HOME}/lib/security/cacerts"
echo "Verify that customCA.javaHome (${JAVA_HOME}) matches the Java installation in this image"
exit 1
fi
cp "${JAVA_HOME}/lib/security/cacerts" "${KEYSTORE}"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@helm/esignet/templates/custom-ca-initcontainer.yaml` at line 18, The cp
command copying "${JAVA_HOME}/lib/security/cacerts" to "${KEYSTORE}" can fail
with an opaque "No such file or directory" when customCA.javaHome is wrong;
update the initContainer command that contains cp
"${JAVA_HOME}/lib/security/cacerts" "${KEYSTORE}" to first test for the source
file and exit with a descriptive error that includes the resolved
JAVA_HOME/customCA.javaHome (e.g., if [ -f "${JAVA_HOME}/lib/security/cacerts"
]; then cp ...; else echo "ERROR: Java cacerts not found at
${JAVA_HOME}/lib/security/cacerts — ensure customCA.javaHome matches the Java
installation in the image" >&2; exit 1; fi), so operators see the bad javaHome
value and can fix values.yaml.

Comment on lines +75 to 80
{{- if .Values.customCA.enabled }}
{{- include "esignet.customCAInitContainer" . | nindent 8 }}
{{- end }}
{{- if .Values.enable_insecure }}
{{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }}
{{- end }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

Both customCA and enable_insecure init containers can run simultaneously and conflict.

When customCA.enabled and enable_insecure are both set to true, both init containers are rendered (line 75-77 and 78-80) and execute sequentially. Both write to the shared cacerts volume:

  1. The customCA init container (line 76) imports company CA certificates into /cacerts/cacerts.
  2. The enable_insecure init container (defined in values.yaml:351) then runs cp /usr/local/openjdk-11/lib/security/cacerts /cacerts, which overwrites the file with the default JVM truststore, removing all the company CA certificates imported by the first init container.

This results in a broken configuration where the Java application cannot trust either the company-internal CA or the self-signed certificate from mosip-api-internal-host.

The validation in _helpers.tpl lines 78-81 would catch this, but as noted in previous reviews, esignet.validateValues is never invoked, so the check doesn't run.

🔧 Recommended fix

The proper fix requires two changes:

  1. Invoke validation in a rendered template to enforce mutual exclusivity at helm install time
  2. Add a runtime guard to prevent rendering both init containers

Option A (recommended): Add validation call and guard the enable_insecure block:

In deployment.yaml:

       {{- if .Values.customCA.enabled }}
       {{- include "esignet.customCAInitContainer" . | nindent 8 }}
       {{- end }}
-      {{- if .Values.enable_insecure }}
+      {{- if and .Values.enable_insecure (not .Values.customCA.enabled) }}
         {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }}
       {{- end }}

And in _helpers.tpl, change the validation to fail instead of just printing:

 {{- if and .Values.enable_insecure .Values.customCA.enabled -}}
-esignet: customCA.enable_insecure
-    enable_insecure and customCA.enabled cannot be used together. Use customCA for company-internal PKI.
+{{- fail "enable_insecure and customCA.enabled cannot be used together. Use customCA for company-internal PKI." -}}
 {{- end -}}

Then invoke validation in deployment.yaml (add near the top, before any conditionals):

{{- include "esignet.validateValues" . -}}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- if .Values.customCA.enabled }}
{{- include "esignet.customCAInitContainer" . | nindent 8 }}
{{- end }}
{{- if .Values.enable_insecure }}
{{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }}
{{- end }}
{{- if .Values.customCA.enabled }}
{{- include "esignet.customCAInitContainer" . | nindent 8 }}
{{- end }}
{{- if and .Values.enable_insecure (not .Values.customCA.enabled) }}
{{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }}
{{- end }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@helm/esignet/templates/deployment.yaml` around lines 75 - 80, Call the
existing validation template and add a runtime guard so both init containers
cannot be rendered together: invoke the esignet.validateValues template near the
top of deployment.yaml (before any conditional init-container logic) and modify
the enable_insecure init-container block (the include of
"common.tplvalues.render" for .Values.initContainers) to only render when
.Values.enable_insecure is true AND .Values.customCA.enabled is false; also
update the esignet.validateValues helper in _helpers.tpl to return/throw a
failure (not just print) when customCA.enabled and enable_insecure are both true
so Helm install/upgrade fails early.

Comment thread helm/esignet/values.yaml
Comment on lines +371 to +373
## Additional init containers appended after built-in truststore init containers.
##
extraInitContainers: {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix: extraInitContainers should be a list, not a dict.

The deployment template at line 82 renders extraInitContainers using common.tplvalues.render, expecting a YAML list (array) of init container specs. However, the default value is set to {} (empty dict) instead of [] (empty list). If a user leaves this at the default and the template attempts to render it, Kubernetes will reject the manifest because init containers must be an array.

🛠️ Proposed fix
 ## Additional init containers appended after built-in truststore init containers.
 ##
-extraInitContainers: {}
+extraInitContainers: []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Additional init containers appended after built-in truststore init containers.
##
extraInitContainers: {}
## Additional init containers appended after built-in truststore init containers.
##
extraInitContainers: []
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@helm/esignet/values.yaml` around lines 371 - 373, The default value for
extraInitContainers is currently an empty map ({}) but must be an array; update
the values.yaml entry named extraInitContainers to be an empty list ([]) so
templates that call common.tplvalues.render on extraInitContainers produce a
YAML list of init containers instead of a dict, avoiding invalid Kubernetes
manifests when rendering initContainers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants