Skip to content

[REQ] Helm chart-aware patching: copa patch-chart #1494

Description

@omercnet

What kind of request is this?

New feature

What is your request or suggestion?

Summary

Today, Copa patches individual container images. However, the dominant unit of deployment in Kubernetes is the Helm chart — a versioned bundle of manifests, values, and sub-charts that together describe a complete application. This proposal requests a new copa patch-chart subcommand that treats Helm charts as first-class citizens, patching all referenced container images and producing an updated chart with corrected image references, all within the same OCI registry.


Motivation

When securing a Kubernetes workload, patching individual images is only half the job. The other half is ensuring that the Helm chart used to deploy those workloads actually references the patched images. Today, users must manually correlate Copa's patched image outputs back to their chart values — a fragile, error-prone, and often undocumented step.

This gap means that even when Copa is run correctly, a subsequent helm upgrade using the original chart will re-deploy the unpatched images. Chart-aware patching closes this loop end-to-end.


Proposed CLI Interface

copa patch-chart \
  --chart oci://registry.example.com/myorg/mychart:1.2.3 \
  --output oci://registry.example.com/myorg/mychart:1.2.3-patched \
  --image-registry registry.example.com/myorg \
  --scanner trivy \
  --ignore-errors

Key flags:

Flag Description
--chart OCI reference or local path to the Helm chart
--output OCI reference or local path to write the patched chart
--image-registry Registry namespace where patched images will be pushed
--tag-suffix Suffix appended to patched image tags (default: -patched)
--values Additional values files to use when rendering the chart for image discovery
--scanner Scanner plugin to use (default: trivy)
--ignore-errors Continue if individual images cannot be patched
--dry-run Print discovered images and planned changes without patching

Proposed Behavior

Step 1 — Image discovery via helm template

Rather than heuristically parsing values.yaml, the command renders the chart using helm template and extracts all image: fields from the resulting Kubernetes manifests. This approach:

  • Correctly handles conditional templates and feature flags
  • Resolves sub-chart image references
  • Respects any --values overrides provided by the user

Step 2 — Scan and patch each image

For each discovered image, Copa runs the existing patch pipeline:

  1. Scan with the configured scanner (e.g., Trivy)
  2. Patch via copa patch if vulnerabilities are found
  3. Push the patched image to the target registry with a deterministic new tag or digest

Images that are already clean (no fixable CVEs) are skipped; their references remain unchanged in the output chart.

Step 3 — Generate patched chart

Copa produces an updated Helm chart where all patchable image references in values.yaml (and sub-chart values) are rewritten to point to the patched images. The output is one of:

  • Option A (recommended): A new chart version pushed to the OCI registry, with values.yaml updated in-place and Chart.yaml version bumped (e.g., appending +copa.YYYYMMDD to the version).
  • Option B: A values-copa-patched.yaml overlay file that users apply with helm install -f values-copa-patched.yaml, leaving the original chart untouched.

Both options should be supported. Option B is useful when the user does not control the chart's registry.

Step 4 — Emit a patch report

Copa outputs a machine-readable report (JSON) summarizing:

  • Which images were discovered
  • Which were patched and what CVEs were fixed
  • Which were skipped (clean or unpatchable)
  • The old→new image reference mapping

This report can optionally be attached to the output chart as an OCI referrer (using the OCI referrers API), enabling downstream attestation and audit workflows.


Image Reference Schema Discovery

Helm charts have no enforced schema for how images are declared. Common patterns include:

# Pattern A: split repository/tag
image:
  repository: myregistry.io/myapp
  tag: "1.2.3"

# Pattern B: full image URI
image: myregistry.io/myapp:1.2.3

# Pattern C: digest-pinned
image:
  repository: myregistry.io/myapp
  digest: sha256:abc123...

The helm template-based discovery approach handles all of these naturally, since it reads from rendered Pod specs rather than raw values. Copa then traces each rendered image URI back to its source location in values.yaml to rewrite it.

For cases where automatic tracing is ambiguous (e.g., images constructed dynamically in templates), Copa should:

  1. Log a warning identifying the unresolvable reference
  2. Continue patching the remaining images
  3. Document the unresolved reference in the patch report

OCI-Native Bundle (Stretch Goal)

As a follow-on, Copa could leverage the OCI referrers API to produce a fully self-contained bundle:

oci://registry.example.com/myorg/mychart:1.2.3-patched
  └── [helm chart artifact]            ← updated chart with patched image refs
  └── [referrer] patched image A       ← co-located patched image
  └── [referrer] patched image B       ← co-located patched image
  └── [referrer] copa-patch-report     ← attestation / audit trail

This would make the patched chart and all its runtime dependencies addressable and distributable as a single OCI artifact — particularly valuable for air-gapped environments.


Why This Belongs in Copa Core

This feature is a natural extension of Copa's existing value proposition:

Reduce the complexity of patching [...] to running a single tool.

Today, "a single tool" still leaves users with a gap between patched images and the charts that deploy them. copa patch-chart completes that picture. The scanning, patching, and OCI push logic already exist in Copa — the new work is chart rendering, image reference rewriting, and chart artifact publishing.

A reference implementation of this pattern exists in Verity, an automated container security patching system for Helm charts built on top of Copa and Trivy. The intent is to validate the approach there and contribute the chart-native primitives upstream to Copa.


Are you willing to implement it?

Yes, I already implemented my own concept in my Copa fork used in https://github.com/verity-org/verity but would like to upstream it back here with input from the copa maintainers

Are you willing to submit PRs to contribute to this feature request?

  • Yes, I am willing to implement it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions