Skip to content

address helm chart verification, auth, and TLS options#601

Open
amartin120 wants to merge 3 commits into
hauler-dev:mainfrom
amartin120:fix-chart-params
Open

address helm chart verification, auth, and TLS options#601
amartin120 wants to merge 3 commits into
hauler-dev:mainfrom
amartin120:fix-chart-params

Conversation

@amartin120
Copy link
Copy Markdown
Contributor

@amartin120 amartin120 commented May 5, 2026

Please check below, if the PR fulfills these requirements:

  • Commit(s) and code follow the repositories guidelines.
  • Test(s) have been added or updated to support these change(s).
  • Doc(s) have been added or updated to support these change(s).

Types of Changes:

  • bugfix

Proposed Changes:

Fixes security finding H1 from the internal security review:

Helm chart --verify, auth, and TLS flags are silently dropped, giving users false confidence that provenance verification or authenticated/TLS chart fetching is in effect when it is not. This is a supply-chain integrity risk — tampered or unauthenticated charts are fetched without complaint.

Root cause: pkg/content/chart/chart.go's NewChart accepts *action.ChartPathOptions from the caller but only copies Version onto a fresh action.NewInstall(...) client. Every other field (Verify, Username, Password, CertFile, KeyFile, CaFile, InsecureSkipTLSverify, PlainHTTP, Keyring, PassCredentialsAll) was thrown away. CLI flags were correctly bound and passed in — they just never reached Helm.

Changes

  • pkg/content/chart/chart.go — propagate all auth/TLS/verify fields from opts onto client.ChartPathOptions before LocateChart runs. Per-field copy (not blanket *opts assignment) is deliberate so the existing conditional RepoURL handling for OCI / HTTP / bare-name repos stays intact.
  • internal/flags/add.go — add --keyring flag so --verify is fully usable; defaults to Helm's $HOME/.gnupg/pubring.gpg when unset.
  • pkg/apis/hauler.cattle.io/v1/chart.go — extend the Chart manifest type with Verify, Keyring, UsernameEnv, PasswordEnv, PassCredentialsAll, CertFile, KeyFile, CaFile, InsecureSkipTLSverify, PlainHTTP. Credentials are referenced by env-var name — raw username/password values are intentionally not part of the manifest schema.
  • cmd/hauler/cli/store/sync.go — new resolveChartCreds helper resolves UsernameEnv/PasswordEnv to actual values at sync time via os.Getenv. The resolved values are then plumbed into action.ChartPathOptions.Username/Password for that chart entry. Errors loudly if only one of the env-name fields is set, or if both are set but the named env vars are empty/unset — better to fail fast than silently fetch unauthenticated.
  • pkg/content/chart/chart_test.go — regression test TestNewChart_VerifyOnUnsignedChartFails that calls NewChart with Verify: true against the unsigned rancher-cluster-templates-0.5.2.tgz testdata and asserts a provenance-tokened error. Pre-fix this test would fail (nil error returned); post-fix Helm's downloader.VerifyChart runs and errors on the missing .prov.
  • cmd/hauler/cli/store/sync_test.go — five unit tests for resolveChartCreds: empty config, happy path, only-username-env-set, only-password-env-set, both-set-but-env-vars-unset.

Manifest example (env-var credentials)

  apiVersion: hauler.cattle.io/v1                                                                                                                                                                                                                                                                   
  kind: Charts                                                                                                                                                                                                                                                                                    
  spec:                                                                                                                                                                                                                                                                                             
    charts:
      - name: chart-a                                                                                                                                                                                                                                                                               
        repoURL: https://repo-a.example.com/charts                                                                                                                                                                                                                                                
        version: 1.2.3                                                                                                                                                                                                                                                                              
        verify: true
        usernameEnv: REPO_A_USER                                                                                                                                                                                                                                                                    
        passwordEnv: REPO_A_PASS                                                                                                                                                                                                                                                                    
      - name: chart-b                                                                                                                                                                                                                                                                             
        repoURL: https://repo-b.example.com/charts                                                                                                                                                                                                                                                  
        caFile: /etc/ssl/certs/internal-ca.crt
                                                                                                                                                                                                                                                                                             
  export REPO_A_USER=... REPO_A_PASS=...                                                                                                                                                                                                                                                            
  hauler store sync -f manifest.yaml

Different charts can reference different env vars — there's no single-credential constraint.

Things we should know...

  • No credentials in YAML. The manifest schema only carries env-var names (usernameEnv, passwordEnv), not values. Hauler reads os.Getenv(...) at sync time. Raw username/password fields were considered and intentionally rejected to avoid the YAML-secrets footgun.
  • OCI vs HTTP auth differs. --username/--password (CLI) and usernameEnv/passwordEnv (manifest) apply to HTTP repos only. For OCI registries, auth still comes from hauler login (Helm's RegistryConfig credentials file). This matches Helm CLI behavior.
  • Fail-fast on misconfigured env vars. If only one of usernameEnv/passwordEnv is set, or if both are set but the named env vars are empty/unset, hauler store sync returns an error rather than silently dropping creds and fetching unauthenticated.
  • CLI flags unchanged. hauler store add chart --username ... --password ... still works for one-shot use; credentials in shell process state aren't a YAML-leak risk.
  • Subchart/dependency chain in cmd/hauler/cli/store/add.go does depOpts := *opts, so auth/TLS automatically propagate to dependent charts once the top-level fix is in place. No change needed there.
  • --verify without --keyring falls back to Helm's $HOME/.gnupg/pubring.gpg. On systems without that file, verification fails with a Helm-native error.
  • Pre-existing lint notes (omitempty on nested struct fields) on the Charts wrapper are not from this PR — same pattern is used in image.go/file.go/driver.go. Unrelated cleanup belongs in its own PR.

Verification/Testing of Changes:

  • make fmt
  • make vet
  • make test — full suite passes
  • go test ./pkg/content/chart/... -v -run TestNewChart_VerifyOnUnsignedChartFails — passes
  • Manual smoke: hauler store add chart rancher-cluster-templates-0.5.2.tgz --repo ./testdata --verify — expect a provenance error (pre-fix: silently succeeds)
  • Manual smoke: same scenario via a v1 manifest with verify: true through hauler store sync

Additional Context:

amartin120 added 2 commits May 5, 2026 14:24
Signed-off-by: Adam Martin <adam.martin@ranchergovernment.com>
…t in manifest

Signed-off-by: Adam Martin <adam.martin@ranchergovernment.com>
@github-project-automation github-project-automation Bot moved this to To Triage in Hauler May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To Triage

Development

Successfully merging this pull request may close these issues.

2 participants