Helm is the de facto package manager for Kubernetes, but Helm charts can introduce security vulnerabilities if not properly vetted and configured. This guide covers securing Helm deployments from chart development to production deployment.
Helm chart security encompasses chart provenance, secure defaults, secrets management, and runtime security configurations. Understanding these aspects is essential for maintaining secure Kubernetes deployments.
Chart Provenance and Signing
# Sign a Helm chart
helm package --sign --key mykey --keyring ~/.gnupg/secring.gpg mychart/
# Verify chart signature
helm verify mychart-1.0.0.tgz
# Install with verification
helm install myrelease mychart-1.0.0.tgz --verifySecure Values Configuration
# values.yaml with security defaults
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
networkPolicy:
enabled: trueSecrets Management
# Use External Secrets Operator
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: app-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: SecretStore
target:
name: app-secrets
data:
- secretKey: database-password
remoteRef:
key: production/database
property: passwordChart Security Scanning
# Scan with Checkov
checkov -d mychart/ --framework helm
# Scan with Kubesec
helm template mychart/ | kubesec scan -
# Scan with Trivy
trivy config mychart/Pod Security in Templates
# deployment.yaml template
spec:
template:
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: AlwaysNetwork Policies
{{- if .Values.networkPolicy.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ include "mychart.fullname" . }}
spec:
podSelector:
matchLabels:
{{- include "mychart.selectorLabels" . | nindent 6 }}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080
{{- end }}Best Practices
- Sign and verify all charts
- Use secure defaults in values.yaml
- Never store secrets in charts
- Scan charts before deployment
- Pin image tags with digests
- Enable network policies by default
- Use read-only root filesystem
- Drop all capabilities
- Set resource limits
- Review third-party charts carefully
Conclusion
Helm chart security requires attention from development through deployment. By implementing chart signing, secure defaults, and proper secrets management, you can ensure your Kubernetes applications are deployed securely.



