refactor(misconf): replace custom Helm archive parsing with Helm SDK loaders#10718
Merged
nikpivkin merged 16 commits intoMay 27, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors the Helm misconfiguration scanner to delegate chart-archive loading to the Helm v4 SDK (instead of Trivy’s custom tar extraction), simplifies the parser API, and restructures the Helm scanner/parser tests around txtar-based fixtures.
Changes:
- Replace custom Helm archive unpacking with Helm SDK archive loaders; stop treating plain
.tarfiles as Helm chart archives. - Move chart discovery/skip rules into the scanner and make the parser stateless with focused
ParseFS/ParseArchiveentry points. - Overhaul Helm tests and fixtures (txtar fixtures, new archive-building helpers), removing large/legacy binary fixture trees.
Reviewed changes
Copilot reviewed 118 out of 143 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/iac/scanners/helm/scanner.go | Refactors chart discovery and scanning flow; adds archive skip heuristics and uses new parser API. |
| pkg/iac/scanners/helm/scanner_test.go | Reworks scanner tests to use txtar fixtures and adds chart discovery/skip scenarios. |
| pkg/iac/scanners/helm/parser/parser.go | Replaces internal stateful parsing with stateless ParseFS/ParseArchive returning rendered manifests via Helm SDK loaders. |
| pkg/iac/scanners/helm/parser/parser_test.go | Rebuilds parser tests into table-driven cases; adds archive parsing coverage and txtar-based expected outputs. |
| pkg/iac/scanners/helm/parser/parser_tar.go | Removes custom tar extraction implementation. |
| pkg/iac/detection/peek.go | Drops .tar from “archive” detection (Helm chart archives are now .tgz/.tar.gz only). |
| internal/testutil/gzip.go | Adds helpers to build tar/tar.gz archives from fs.FS for tests. |
| pkg/iac/scanners/helm/testdata/with-subchart.txtar | Adds txtar fixture for verifying subchart scanning occurs exactly once. |
| pkg/iac/scanners/helm/testdata/templated-name.txtar | Updates txtar fixture description/header content for templated chart names. |
| pkg/iac/scanners/helm/testdata/simmilar-templates.txtar | Expands fixture and adds second similar template for code-snippet selection tests. |
| pkg/iac/scanners/helm/testdata/non-helm-chart.txtar | Adds non-Helm txtar fixture to ensure scanner doesn’t error on unrelated input. |
| pkg/iac/scanners/helm/testdata/aws-cluster-autoscaler.txtar | Adds real-world-ish fixture to test parser/scanner recovery scenarios. |
| pkg/iac/scanners/helm/test/parser_test.go | Removes legacy parser tests (replaced by new parser package tests). |
| pkg/iac/scanners/helm/test/option_test.go | Removes legacy option tests (covered by new parser tests). |
| pkg/iac/scanners/helm/test/helpers_test.go | Removes legacy test helpers (replaced by internal/testutil helpers). |
| pkg/iac/scanners/helm/test/testdata/with-tarred-dep/renovate.json | Removes legacy fixture file as part of testdata overhaul. |
| pkg/iac/scanners/helm/test/testdata/with-tarred-dep/LICENSE | Removes legacy fixture file as part of testdata overhaul. |
| pkg/iac/scanners/helm/test/testdata/with-tarred-dep/.helmignore | Removes legacy fixture file as part of testdata overhaul. |
| pkg/iac/scanners/helm/test/testdata/with-subchart/Chart.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-subchart/values.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-subchart/charts/nginx/Chart.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-subchart/charts/nginx/values.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-subchart/charts/nginx/templates/pod.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-kube-version/Chart.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-kube-version/.helmignore | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-kube-version/templates/pdb.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-api-version/Chart.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-api-version/.helmignore | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/with-api-version/templates/pdb.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/Chart.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/.helmignore | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/values.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/templates/_helpers.tpl | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/templates/deployment.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/templates/hpa.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/templates/ingress.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/templates/NOTES.txt | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/templates/service.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/templates/serviceaccount.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/testchart/templates/tests/test-connection.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/simmilar-templates/Chart.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/simmilar-templates/templates/manifest.yaml | Removes legacy on-disk fixture (replaced by txtar). |
| pkg/iac/scanners/helm/test/testdata/numberName/Chart.yaml | Removes legacy on-disk fixture (replaced by new parser txtar fixtures). |
| pkg/iac/scanners/helm/test/testdata/expected/with-tarred-dep/templates/ingress.yaml | Removes legacy expected-render output (expected outputs moved/reworked). |
| pkg/iac/scanners/helm/test/testdata/expected/with-tarred-dep/templates/service.yaml | Removes legacy expected-render output (expected outputs moved/reworked). |
| pkg/iac/scanners/helm/test/testdata/expected/testchart/templates/service.yaml | Removes legacy expected-render output (expected outputs moved/reworked). |
| pkg/iac/scanners/helm/test/testdata/expected/testchart/templates/serviceaccount.yaml | Removes legacy expected-render output (expected outputs moved/reworked). |
| pkg/iac/scanners/helm/test/testdata/expected/options/testchart/templates/service.yaml | Removes legacy expected-render output (expected outputs moved/reworked). |
| pkg/iac/scanners/helm/test/testdata/expected/options/testchart/templates/serviceaccount.yaml | Removes legacy expected-render output (expected outputs moved/reworked). |
| pkg/iac/scanners/helm/test/testdata/expected/mysql/templates/serviceaccount.yaml | Removes legacy MySQL expected output fixture. |
| pkg/iac/scanners/helm/test/testdata/expected/mysql/templates/secrets.yaml | Removes legacy MySQL expected output fixture. |
| pkg/iac/scanners/helm/test/testdata/expected/mysql/templates/primary/svc.yaml | Removes legacy MySQL expected output fixture. |
| pkg/iac/scanners/helm/test/testdata/expected/mysql/templates/primary/svc-headless.yaml | Removes legacy MySQL expected output fixture. |
| pkg/iac/scanners/helm/test/testdata/expected/mysql/templates/primary/statefulset.yaml | Removes legacy MySQL expected output fixture. |
| pkg/iac/scanners/helm/test/testdata/expected/mysql/templates/primary/configmap.yaml | Removes legacy MySQL expected output fixture. |
| pkg/iac/scanners/helm/test/mysql/Chart.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/Chart.lock | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/.helmignore | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/values.schema.json | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/ci/values-production-with-rbac.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/NOTES.txt | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/_helpers.tpl | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/extra-list.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/metrics-svc.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/networkpolicy.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/role.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/rolebinding.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/secrets.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/serviceaccount.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/servicemonitor.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/primary/configmap.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/primary/initialization-configmap.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/primary/pdb.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/primary/statefulset.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/primary/svc.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/primary/svc-headless.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/secondary/configmap.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/secondary/pdb.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/secondary/statefulset.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/secondary/svc.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/templates/secondary/svc-headless.yaml | Removes legacy large MySQL chart fixture. |
| pkg/iac/scanners/helm/test/mysql/charts/common/Chart.yaml | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/values.yaml | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_affinities.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_capabilities.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_errors.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_images.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_ingress.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_labels.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_names.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_secrets.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_storage.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_tplvalues.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_utils.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/_warnings.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/validations/_cassandra.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/validations/_mariadb.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/validations/_mongodb.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/validations/_postgresql.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/validations/_redis.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/test/mysql/charts/common/templates/validations/_validations.tpl | Removes legacy large MySQL chart fixture dependency. |
| pkg/iac/scanners/helm/parser/testdata/testchart.txtar | Adds base chart fixture for parser tests in txtar form. |
| pkg/iac/scanners/helm/parser/testdata/values.yaml | Adds shared values file used by parser option tests. |
| pkg/iac/scanners/helm/parser/testdata/with-api-version.txtar | Updates API-version-dependent chart fixture to txtar chart structure. |
| pkg/iac/scanners/helm/parser/testdata/with-kube-version.txtar | Updates kube-version-dependent chart fixture to txtar chart structure. |
| pkg/iac/scanners/helm/parser/testdata/chart-without-name.txtar | Adds fixture for missing name: handling. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-integer-name.txtar | Adds fixture intended to exercise non-string chart name handling. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-packaged-dep/Chart.yaml | Adds minimal chart with a packaged dependency. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-packaged-dep/.helmignore | Adds helmignore for packaged-dependency chart fixture. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-packaged-dep/values.yaml | Adds values for packaged-dependency chart fixture. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-packaged-dep/templates/deployment.yaml | Adds minimal deployment template for packaged-dependency chart fixture. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-packaged-dep/templates/ingress.yaml | Adds minimal ingress template for packaged-dependency chart fixture. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-packaged-dep/templates/service.yaml | Adds minimal service template for packaged-dependency chart fixture. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-packaged-dep/templates/secrets-crdb-ca.yaml | Adds secret template for packaged-dependency chart fixture. |
| pkg/iac/scanners/helm/parser/testdata/chart-with-packaged-dep/templates/secrets-dbconn.yaml | Adds secret template for packaged-dependency chart fixture. |
| pkg/iac/scanners/helm/parser/testdata/non-deps-archives/Chart.yaml | Removes old fixture (dependency/archive classification tests removed/changed). |
| pkg/iac/scanners/helm/parser/testdata/multiple-archived-deps/Chart.yaml | Removes old fixture (dependency/archive classification tests removed/changed). |
| pkg/iac/scanners/helm/parser/testdata/chart-and-archived-chart/my-chart/Chart.yaml | Removes old fixture (archive-vs-dir skip logic moved to scanner tests). |
| pkg/iac/scanners/helm/parser/testdata/chart-and-archived-chart/my-chart/templates/pod.yaml | Removes old fixture (archive-vs-dir skip logic moved to scanner tests). |
| pkg/iac/scanners/helm/parser/testdata/expected/testchart.txtar | Updates expected rendered output format for new txtar fixtures. |
| pkg/iac/scanners/helm/parser/testdata/expected/testchart-with-options.txtar | Updates expected rendered output for option-based rendering. |
| pkg/iac/scanners/helm/parser/testdata/expected/with-api-version.txtar | Updates expected rendered output for API version option. |
| pkg/iac/scanners/helm/parser/testdata/expected/with-kube-version.txtar | Updates expected rendered output for kube version option. |
| pkg/iac/scanners/helm/parser/testdata/expected/chart-with-packaged-dep.txtar | Adds/updates expected render output for packaged-dependency fixture. |
Comments suppressed due to low confidence (1)
pkg/iac/scanners/helm/testdata/simmilar-templates.txtar:2
- There is trailing whitespace at the end of the first line, which makes diffs noisier and can trip whitespace linters. Please trim it.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
3850eee to
4665293
Compare
DmitriyLewen
previously approved these changes
May 27, 2026
DmitriyLewen
left a comment
Contributor
There was a problem hiding this comment.
LGTM
left small comment
DmitriyLewen
approved these changes
May 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Replaces Trivy's custom Helm archive parsing with the Helm SDK's own loaders, cleans up the parser/scanner architecture, and overhauls the test structure.
Background
Since the initial Helm support (f5e655e22a), Trivy unpacked chart archives manually via a custom
unpackArchiveimplementation inparser_tar.go. Over time this accumulated several problems:.tarsupport: Trivy accepted plain.taras a Helm chart format, but Helm never produces it —helm packagealways outputs.tgz. A symlink-handling workaround was later added (4eae37c52b) to deal with non-Helm archives that were being incorrectly processed as charts. The root fix is to not accept.tarat all. By delegating toLoadArchiveFiles, the symlink workaround is no longer needed — Helm itself does not handle symlinks becausehelm packageresolves them into regular files, so they simply don't appear in legitimate chart archives.Breaking changes
None. The removed behaviour was never part of a supported contract:
.tarwithout gzip:helm packagenever produces plain.tararchives, so no legitimate chart scanner input is affected.helm packageresolves symlinks into regular files at pack time, symlinks cannot appear in legitimate chart archives. The workaround existed solely to handle non-Helm-produced archives that should not have been accepted in the first place.This can be verified empirically:
$ ln -s dangerous.yaml testchart/templates/dangerous-link.yaml $ helm package testchart Successfully packaged chart and saved it to: testchart-0.1.0.tgz $ tar tvf testchart-0.1.0.tgz | grep dangerous -rw-r--r-- 0 0 0 194 May 27 16:25 testchart/templates/dangerous-link.yaml -rw-r--r-- 0 0 0 194 May 27 16:25 testchart/templates/dangerous.yamlhelm packageproduces.tgz(not.tar), and both entries are regular files — the symlink was resolved at pack time.To confirm no regression on a real-world chart, the same archive was scanned with both the released version and the patched one:
Changes
Parser — simplified API, no internal state
The custom archive unpacking logic is removed. Archive loading is delegated to
loader.LoadArchiveFilesfromhelm.sh/helm/v4.The parser now has two focused entry points:
Previously,
ParseFSboth discovered charts and rendered them, accumulating state across calls. Now the parser is stateless — it holds only the Helm action client — and each call is independent. The caller decides what to parse.Scanner — owns chart discovery
Chart discovery is now handled entirely by the scanner. It distinguishes two skip scenarios to avoid duplicate results:
my-chart/my-chart-1.0.0.tgzalongsidemy-chart/Chart.yaml) — the unpacked directory takes precedence../my-chart-1.0.0.tgzalongside./my-chart/) — same rule.Forward compatibility
Delegating to the Helm SDK makes Charts v3 support straightforward in the future: detect the chart API version and call the appropriate SDK loader. No changes to Trivy's own parsing logic will be needed.
Test changes
The test suite was overhauled alongside the logic changes:
parser/, scanner tests inhelm/. Previously everything was mixed in atest/subdirectory..tar.gzand.tgztestdata files are replaced with.txtartext archives. Chart content is visible directly in the file; archives are constructed programmatically in tests using new helpers. This makes chart structure transparent during code review and removes binary blobs from the repository.values.yaml,README.md, nested templates and a bundledcommonsubchart) was used solely as a parser test fixture. It is replaced with a minimal chart written for this purpose.Related issues
Checklist