diff --git a/deploy/helm/openshell/README.md b/deploy/helm/openshell/README.md index 4d09c32de8..052a140ab6 100644 --- a/deploy/helm/openshell/README.md +++ b/deploy/helm/openshell/README.md @@ -242,6 +242,8 @@ discovery endpoint or its TLS CA. | openshiftRoute.host | string | `""` | Hostname for the Route. Must match a SAN on the gateway's server cert. | | pkiInitJob.enabled | bool | `true` | Run a pre-install/pre-upgrade Job that creates gateway and client mTLS Secrets. When certManager.enabled=true, cert-manager owns TLS and this same hook runs in JWT-only mode even if pkiInitJob.enabled remains true. | | pkiInitJob.failOnTimeout | bool | `true` | Fail the helm install/upgrade if cert-manager does not issue the certificate within the polling timeout. When true (default), the install fails immediately if the timeout is reached, providing clear feedback that BackendTLSPolicy is non-functional. When false, the hook succeeds with a warning and you can run `helm upgrade` after cert-manager issues the certificate to create the backend CA ConfigMap. If you set this to false and see "TLS error: Secret is not supplied by SDS" when connecting to the gateway, check if the TLS secret exists and run `helm upgrade` to create the ConfigMap. | +| pkiInitJob.podSecurityContext | object | `{"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` | Pod securityContext for the certgen hook Jobs. Defaults satisfy the Restricted Pod Security Standard. | +| pkiInitJob.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsUser":1000}` | Container securityContext for the certgen hook Jobs. | | pkiInitJob.serverDnsNames | list | `[]` | Extra DNS SANs to append to the server certificate. | | pkiInitJob.serverIpAddresses | list | `[]` | Extra IP SANs to append to the server certificate. | | pkiInitJob.timeoutSeconds | int | `120` | Maximum time in seconds for the certgen hook to poll for cert-manager certificates. When using cert-manager with BackendTLSPolicy, the hook polls for this many seconds waiting for the certificate to be issued, then creates the backend CA ConfigMap. The Job deadline is set to (timeoutSeconds + 30) to allow time for ConfigMap creation and cleanup. Increase this if cert-manager takes longer than 120 seconds to issue certificates. | diff --git a/deploy/helm/openshell/templates/certgen.yaml b/deploy/helm/openshell/templates/certgen.yaml index f7c9a751d3..8d2e81faa6 100644 --- a/deploy/helm/openshell/templates/certgen.yaml +++ b/deploy/helm/openshell/templates/certgen.yaml @@ -79,6 +79,10 @@ spec: spec: restartPolicy: OnFailure serviceAccountName: {{ $hookName }} + {{- with .Values.pkiInitJob.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} @@ -88,10 +92,7 @@ spec: image: {{ include "openshell.image" . | quote }} imagePullPolicy: {{ .Values.gateway.image.pullPolicy | default .Values.global.image.pullPolicy }} securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL + {{- toYaml .Values.pkiInitJob.securityContext | nindent 12 }} env: - name: POD_NAMESPACE valueFrom: @@ -150,6 +151,10 @@ spec: spec: restartPolicy: OnFailure serviceAccountName: {{ $hookName }} + {{- with .Values.pkiInitJob.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} @@ -159,10 +164,7 @@ spec: image: {{ include "openshell.image" . | quote }} imagePullPolicy: {{ .Values.gateway.image.pullPolicy | default .Values.global.image.pullPolicy }} securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL + {{- toYaml .Values.pkiInitJob.securityContext | nindent 12 }} env: - name: POD_NAMESPACE valueFrom: diff --git a/deploy/helm/openshell/tests/certgen_security_context_test.yaml b/deploy/helm/openshell/tests/certgen_security_context_test.yaml new file mode 100644 index 0000000000..d82d0a024e --- /dev/null +++ b/deploy/helm/openshell/tests/certgen_security_context_test.yaml @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +suite: certgen hook securityContext +templates: + - templates/certgen.yaml +release: + name: openshell + namespace: my-namespace + +tests: + - it: renders a Restricted-compliant pod and container securityContext by default + template: templates/certgen.yaml + documentIndex: 3 + asserts: + - equal: + path: spec.template.spec.securityContext.runAsNonRoot + value: true + - equal: + path: spec.template.spec.securityContext.seccompProfile.type + value: RuntimeDefault + - equal: + path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.capabilities.drop[0] + value: ALL + + - it: renders an explicitly set pkiInitJob.podSecurityContext + template: templates/certgen.yaml + documentIndex: 3 + set: + pkiInitJob.podSecurityContext: + runAsNonRoot: true + runAsUser: 2000 + seccompProfile: + type: RuntimeDefault + asserts: + - equal: + path: spec.template.spec.securityContext.runAsUser + value: 2000 + + - it: renders the same securityContext on the cert-manager backend-ca hook + template: templates/certgen.yaml + set: + certManager.enabled: true + grpcRoute.backendTLSPolicy.enabled: true + documentIndex: 4 + asserts: + - equal: + path: spec.template.spec.securityContext.runAsNonRoot + value: true + - equal: + path: spec.template.spec.containers[0].securityContext.capabilities.drop[0] + value: ALL diff --git a/deploy/helm/openshell/values.yaml b/deploy/helm/openshell/values.yaml index 426f3ae424..548a37cd38 100644 --- a/deploy/helm/openshell/values.yaml +++ b/deploy/helm/openshell/values.yaml @@ -532,6 +532,19 @@ pkiInitJob: # see "TLS error: Secret is not supplied by SDS" when connecting to the gateway, # check if the TLS secret exists and run `helm upgrade` to create the ConfigMap. failOnTimeout: true + # -- Pod securityContext for the certgen hook Jobs. Defaults satisfy the + # Restricted Pod Security Standard. + podSecurityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + # -- Container securityContext for the certgen hook Jobs. + securityContext: + runAsUser: 1000 + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL # cert-manager Certificate/Issuer resources (requires cert-manager CRDs in-cluster). # Does not install cert-manager itself.