Rules Reference¶
helm-guard implements 42 checks across 10 categories. Each check operates at a specific parser tier.
Parser tiers¶
| Tier | Files | Parser | Reliability |
|---|---|---|---|
| Tier 1 | Chart.yaml, values.yaml, Chart.lock, values.schema.json | ruamel.yaml (structured YAML) | High, no false negatives |
| Tier 2 | templates/.yaml, templates/.tpl | Line-by-line text scanning with regex | May miss complex patterns |
| Tier 3 | Rendered output (via helm template) |
YAML parsing of rendered manifests | Requires helm CLI, opt-in |
Pinning (HLM-PIN)¶
HLM-PIN-001: Chart dependency with SemVer range¶
- Severity: HIGH
- CWE: CWE-829
- Tier: 1
- Detects:
dependencies[].versionuses range operators (^,~,>=,>,<,||) - Remediation: Pin to exact version (e.g.,
version: 1.2.3)
HLM-PIN-002: Missing Chart.lock¶
- Severity: HIGH
- CWE: CWE-829
- Tier: 1
- Detects: Chart has dependencies in Chart.yaml but no Chart.lock
- Remediation: Run
helm dependency buildto generate Chart.lock
HLM-PIN-003: Mutable image tag in values.yaml¶
- Severity: MEDIUM
- CWE: CWE-829
- Tier: 1
- Detects: Image-related keys with mutable tags (no
@sha256:digest) - Remediation: Pin images to digest
HLM-PIN-004: OLM subscription channel not version-pinned¶
- Severity: MEDIUM
- CWE: CWE-829
- Tier: 1
- Detects: OLM channel like
stable,fast,alphawithout version suffix - Remediation: Use versioned channels (e.g.,
stable-v1.3)
HLM-PIN-005: Chart version not following SemVer¶
- Severity: MEDIUM
- CWE: CWE-1104
- Tier: 1
- Detects: Chart.yaml
versionfield missing or not following strict SemVer format (MAJOR.MINOR.PATCH) - Remediation: Use SemVer format (e.g.,
1.2.3)
Injection (HLM-INJ)¶
HLM-INJ-001: tpl function usage¶
- Severity: CRITICAL
- CWE: CWE-94
- Tier: 2
- Detects: Any
tplfunction call in template files. Thetplfunction executes its input as a Go template, enabling arbitrary code execution. - Remediation: Avoid
tplentirely. Use direct value interpolation.
HLM-INJ-002: Values in shell script without quote¶
- Severity: HIGH
- CWE: CWE-78
- Tier: 2
- Detects:
.Values.*insidesh -c,bash -c, orscript:blocks without pipe toquote/squote - Remediation: Pipe values through
quotein shell contexts
HLM-INJ-003: Values in resource name without length control¶
- Severity: MEDIUM
- CWE: CWE-20
- Tier: 2
- Detects:
.Values.*in lines containingname:withouttrunc 63 - Remediation: Use
{{ .Values.name | trunc 63 | trimSuffix "-" }}
HLM-INJ-004: lookup function in template¶
- Severity: CRITICAL
- CWE: CWE-94
- Tier: 2
- Detects: Any
lookupfunction call inside{{ }}delimiters. Thelookupfunction queries the live Kubernetes API during rendering, enabling exfiltration of cluster secrets and resources. - Remediation: Remove lookup calls. Use known resource references instead of dynamic cluster queries.
HLM-INJ-005: env/expandenv function in template¶
- Severity: HIGH
- CWE: CWE-200
- Tier: 2
- Detects:
envorexpandenvfunction calls inside{{ }}delimiters. These leak host environment variables (CI/CD secrets, tokens, credentials) into rendered manifests. - Remediation: Remove env/expandenv calls. Pass values explicitly via values.yaml.
HLM-INJ-006: .Files access with user-controlled path¶
- Severity: HIGH
- CWE: CWE-22
- Tier: 2
- Detects:
.Files.Getor.Files.Globcalls where the path argument is derived from.Values. An attacker can craft values to read arbitrary files from the chart directory. - Remediation: Hardcode file paths in .Files.Get calls. Do not use .Values for file path construction.
HLM-INJ-007: Hardcoded container registry in template¶
- Severity: MEDIUM
- CWE: CWE-829
- Tier: 2
- Detects: Template files with hardcoded
image:references (e.g.,image: docker.io/nginx:1.25) that bypassvalues.yamlconfiguration. Skips lines with{{ }}expressions or comments. - Remediation: Use
{{ .Values.image.repository }}:{{ .Values.image.tag }}pattern to allow registry redirection.
HLM-INJ-008: getHostByName DNS exfiltration¶
- Severity: HIGH
- CWE: CWE-200
- Tier: 2
- CVE: CVE-2023-25165
- Detects:
getHostByNamefunction calls inside{{ }}delimiters. This function performs DNS lookups during template rendering. CVE-2023-25165 demonstrated that an attacker can exfiltrate sensitive chart data (secrets, values) via DNS queries to attacker-controlled nameservers by encoding data in subdomain labels. - Remediation: Remove
getHostByNamecalls. Use static hostnames or ConfigMap-based resolution.
Trust (HLM-TRUST)¶
HLM-TRUST-001: No values.schema.json¶
- Severity: HIGH
- CWE: CWE-20
- Tier: 1
- Detects: Chart has values.yaml but no values.schema.json
- Remediation: Add values.schema.json with type constraints
HLM-TRUST-002: Secrets in values.yaml¶
- Severity: HIGH
- CWE: CWE-798
- Tier: 1
- Detects: Keys matching secret patterns (password, token, secret, apiKey) with non-empty defaults
- Remediation: Use empty defaults and set via
--setor external secrets
HLM-TRUST-003: Chart dependency from untrusted repository¶
- Severity: HIGH
- CWE: CWE-829
- Tier: 1
- Detects:
dependencies[].repositorynot in trusted list. Checks both direct and transitive dependencies. - Remediation: Use charts from trusted repos
HLM-TRUST-004: hostNetwork/hostPID enabled in values defaults¶
- Severity: HIGH
- CWE: CWE-250
- Tier: 1
- Detects:
hostNetwork: trueorhostPID: trueanywhere in values.yaml (recursive search). These give pods access to the host network/PID namespace, enabling container escape and network sniffing. - Remediation: Set
hostNetwork: falseandhostPID: falseas defaults. Users can override when needed.
HLM-TRUST-005: HTTP URL in values.yaml (cleartext connection)¶
- Severity: MEDIUM
- CWE: CWE-319
- Tier: 1
- Detects: String values starting with
http://(excluding localhost and 127.0.0.1). Data transmitted over HTTP is visible to network observers. - Remediation: Use HTTPS URLs for all external endpoints.
HLM-TRUST-006: Permissive NetworkPolicy in templates¶
- Severity: MEDIUM
- CWE: CWE-284
- Tier: 2
- Detects: Templates containing a NetworkPolicy resource with empty
ingress:,egress:, orspec: {}blocks. Empty rules allow all traffic. - Remediation: Define explicit ingress/egress rules. Avoid empty spec.
HLM-TRUST-007: Global values override security fields¶
- Severity: MEDIUM
- CWE: CWE-1188
- Tier: 1
- Detects:
globalsection in values.yaml that overrides security-related fields (securityContext,privileged,runAsRoot,runAsUser,allowPrivilegeEscalation,hostNetwork,hostPID,serviceAccount,rbac,networkPolicy) for all subcharts. A parent chart can silently weaken subchart security settings via global overrides. - Remediation: Review global security overrides. Ensure subcharts aren't silently made less secure.
Hooks (HLM-HOOK)¶
HLM-HOOK-001: Hook Job without security context reference¶
- Severity: HIGH
- CWE: CWE-250
- Tier: 2
- Detects: Template with
helm.sh/hookannotation that has nosecurityContextreference - Remediation: Add securityContext to hook Job specs
HLM-HOOK-002: Hook with before-hook-creation delete policy¶
- Severity: MEDIUM
- CWE: CWE-390
- Tier: 2
- Detects:
helm.sh/hook-delete-policy: before-hook-creation - Remediation: Use
hook-succeededorhook-faileddelete policies
HLM-HOOK-003: Post-renderer executing external script¶
- Severity: HIGH
- CWE: CWE-94
- Tier: 1
- Detects: Chart
values.yamlconfigures a post-renderer (keys:postRenderer,post-renderer,postrender) with a command or exec field. Post-renderers execute arbitrary code on rendered manifests before they are applied to the cluster, enabling supply chain attacks via malicious scripts. - Remediation: Audit post-renderer scripts. Pin to known-good versions. Prefer Kustomize-based post-rendering over arbitrary scripts.
OLM (HLM-OLM)¶
Note
OLM checks are not Helm-specific. They scan OLM Subscription CRDs that happen to be in chart templates or values. These are included because production deployments (e.g., odh-gitops) deploy operators via Helm charts containing OLM Subscription CRDs.
HLM-OLM-001: Automatic install plan without version pin¶
- Severity: HIGH
- CWE: CWE-829
- Tier: 1 + 2
- Detects:
installPlanApproval: AutomaticwithoutstartingCSVversion pin - Remediation: Use Manual approval or pin to CSV version
HLM-OLM-002: Subscription using community catalog¶
- Severity: MEDIUM
- CWE: CWE-829
- Tier: 1 + 2
- Detects:
source: community-operators - Remediation: Use certified catalogs
HLM-OLM-003: Operator in privileged namespace¶
- Severity: MEDIUM
- CWE: CWE-269
- Tier: 1 + 2
- Detects: Operator namespace in configurable
privileged_namespaceslist - Remediation: Use dedicated namespace
HLM-OLM-004: Automatic approval with unstable channel¶
- Severity: HIGH
- CWE: CWE-829
- Tier: 1
- Detects: OLM subscription with
installPlanApproval: Automaticcombined with an unstable channel (alpha,beta,preview,dev,nightly,canary). Unstable channels can push breaking or vulnerable operator versions automatically. - Remediation: Use Manual approval for unstable channels, or switch to a stable channel.
Provenance (HLM-PROV)¶
HLM-PROV-001: Chart not signed¶
- Severity: INFO (disabled by default)
- CWE: CWE-345
- Tier: 1
- Detects: No
.provfile - Remediation: Sign with
helm package --signor Cosign
Warning
This check fires on nearly every chart. It is disabled by default in skip_checks. Enable it by removing HLM-PROV-001 from your skip list.
Namespace (HLM-NS)¶
HLM-NS-001: Resource in privileged namespace (render mode)¶
- Severity: HIGH
- CWE: CWE-269
- Tier: 3 (requires
--render) - Detects: Rendered resources in configurable
privileged_namespaceslist - Remediation: Deploy to dedicated namespaces
Info
This check only runs when --render is used. It is a superset of kube-linter's use-namespace check.
HLM-NS-002: Release namespace without schema restriction¶
- Severity: MEDIUM
- CWE: CWE-269
- Tier: 2 + 1
- Detects: Templates use
.Release.Namespacebut values.schema.json doesn't constrain namespace values - Remediation: Add namespace constraints in values.schema.json
Security (HLM-SEC)¶
HLM-SEC-001: Path traversal in chart name¶
- Severity: HIGH
- CWE: CWE-22
- Tier: 1
- CVE: CVE-2024-25620, CVE-2026-35206
- Detects:
Chart.yamlnamefield containing path traversal sequences (..,/,\). CVE-2024-25620 and CVE-2026-35206 demonstrated that chart names with../can write files outside intended directories during chart archive extraction. - Remediation: Use a simple chart name without path separators or traversal sequences.
HLM-SEC-002: Chart.lock symlink arbitrary write¶
- Severity: CRITICAL
- CWE: CWE-59
- Tier: 1
- CVE: CVE-2025-53547 (CVSS 8.5)
- Detects:
Chart.lockis a symbolic link rather than a regular file. CVE-2025-53547 demonstrated that a symlinked Chart.lock enables arbitrary code execution when Helm writes dependency data through the symlink to the target file. - Remediation: Remove the symlink and create a regular Chart.lock file via
helm dependency build.
HLM-SEC-003: valueFiles path traversal¶
- Severity: HIGH
- CWE: CWE-22
- Tier: 2
- CVE: CVE-2022-24348
- Detects: Template files referencing
valueFilesorvaluesFileswith absolute paths or directory traversal (..). CVE-2022-24348 demonstrated this enables reading sensitive files from Argo CD reposerver, bypassing path validation via URI parsing confusion. - Remediation: Use relative paths within the chart directory only. Do not use absolute paths or
../in valueFiles.
HLM-SEC-004: Plugin version path traversal¶
- Severity: HIGH
- CWE: CWE-22
- Tier: 1
- CVE: CVE-2026-35204 (CVSS 8.4)
- Detects:
plugin.yamlversionfield containing path traversal sequences (..,/). CVE-2026-35204 demonstrated this enables arbitrary filesystem writes during plugin installation. - Remediation: Use a clean SemVer version string without path separators.
HLM-SEC-005: ServiceAccount token automount not disabled¶
- Severity: MEDIUM
- CWE: CWE-269
- Tier: 2
- Detects: Templates creating a
ServiceAccountresource without explicitly settingautomountServiceAccountToken: false. VoidLink malware targets/var/run/secrets/tokens in 22% of cloud environments. - Remediation: Add
automountServiceAccountToken: falseto ServiceAccount specs.
HLM-SEC-006: Missing .helmignore file¶
- Severity: MEDIUM
- CWE: CWE-200
- Tier: 1
- Detects: Chart has no
.helmignorefile. When packaged, sensitive files (.git/,.env, private keys, CI configs) may be included in the chart archive and distributed to users. - Remediation: Add a
.helmignorefile. Seehelm createfor the default template.
Dependencies (HLM-DEP)¶
HLM-DEP-001: Subchart values override of security fields¶
- Severity: MEDIUM
- CWE: CWE-1188
- Tier: 1
- Detects: Parent values.yaml overrides subchart security fields (securityContext, RBAC, serviceAccount)
- Remediation: Audit subchart security overrides
HLM-DEP-002: Dependency version conflict¶
- Severity: LOW
- CWE: CWE-1104
- Tier: 1
- Detects: Chart.lock has different version than Chart.yaml for same dependency (exact version specs only)
- Remediation: Run
helm dependency buildto refresh
HLM-DEP-003: Potential dependency name typosquat¶
- Severity: HIGH
- CWE: CWE-829
- Tier: 1
- Detects: Chart dependency names with edit distance <= 2 from common chart names (nginx, redis, postgresql, mysql, mongodb, kafka, elasticsearch, prometheus, grafana, cert-manager, etc.). This catches typosquatting attacks where a malicious chart uses a name like
ngnixorreddisto trick users. - Remediation: Verify the dependency is the intended chart. Check the repository URL matches the official source.
HLM-DEP-004: Chart dependency uses alias¶
- Severity: LOW
- CWE: CWE-829
- Tier: 1
- Detects: Chart dependency in Chart.yaml uses an
aliasfield that differs from the chartname. Aliases can hide the real chart name, making security audits harder and potentially masking a malicious dependency behind a trusted-looking alias. - Remediation: Verify the aliased dependency is the intended chart from the expected repository.