CoursesHelmAdvanced

Securing Helm in CI/CD & GitOps

Template-render, scan, and deploy safely.

Advanced14 min · lesson 12 of 12

Securing Helm in delivery combines what the chart renders with how it is deployed. Because Helm v3 uses your kubeconfig, a Helm operation has exactly your Kubernetes permissions — so run installs from CI with a least-privilege service account scoped to the target namespace, not cluster-admin. And treat the chart itself as a security surface: scan the rendered manifests for misconfigurations before they apply, the same way you scan IaC.

.gitlab-ci.yml
render-scan:
script:
- helm lint ./payments-api
- helm template payments ./payments-api -f prod-values.yaml > out.yaml
- kubeconform -strict out.yaml # schema validity
- checkov -f out.yaml --framework kubernetes # security posture of the result
- trivy config out.yaml # misconfig scan
# fail the pipeline on a public service, a privileged pod, missing limits, etc.

Helm with GitOps

In GitOps, you usually do not run helm install by hand at all — Argo CD or Flux render the chart and apply it, with Git as the source of truth (both are covered in the GitOps courses). The security model shifts accordingly: protect the Git repo and the values, let the GitOps controller hold the cluster credentials with scoped RBAC, and keep secrets out of values by using SOPS or the External Secrets Operator. Render-and-scan still runs in CI before merge.

The secure Helm pipeline
1PR: render
helm template
2scan
schema + security + policy
3merge
reviewed values
4deploy
scoped SA / GitOps
Render the chart, scan the real output, review, then deploy with least-privilege credentials — never cluster-admin from a laptop.
Keep secrets out of values, and installs off admin
Two recurring Helm security failures: secrets committed in values files (use SOPS/External Secrets/existingSecret instead), and installs run with cluster-admin (scope the deploy identity to the namespace and resource kinds the chart needs). A chart can render RBAC that escalates itself, so scanning the rendered output and constraining the deploy credential are both necessary — neither alone is enough.