Documentation
¶
Overview ¶
Package v1 provides types for chart-lock attestation data attached to Chainguard Helm charts.
A chart-lock is an in-toto attestation attached to a Chainguard Helm chart OCI artifact. It captures the pinned image references and value mapping templates for every image in the chart, including subcharts. This enables downstream consumers to resolve, relocate, or transform a chart's image references without needing to understand the chart's internal values.yaml structure.
Reading a Chart-Lock ¶
Extract a chart-lock from a DSSE-wrapped attestation payload with ParseChartLockAttestation. It returns ErrChartLockNotFound when the payload is not a chart-lock:
for _, att := range attestations {
payload, _ := att.Payload()
lock, err := v1.ParseChartLockAttestation(payload)
if errors.Is(err, v1.ErrChartLockNotFound) {
continue // not a chart-lock, try next
}
if err != nil {
return err
}
// use lock
}
When the in-toto statement is already unwrapped — for example, surfaced by a verifier that decodes the DSSE envelope — use ParseChartLockAttestationFromPayload instead:
lock, err := v1.ParseChartLockAttestationFromPayload(att.Statement)
Generating Value Overrides ¶
The primary workflow is to walk a chart-lock's image tree and produce Helm value overrides. ChartImages.Walk recursively traverses images at the current level and all subcharts, nesting subchart results under their dependency key:
merged, err := lock.Images.Walk(func(id string, ref *v1.ChartImage, tokens images.TokenList) (any, error) {
// ref has the pinned RepoName, Tag, and Digest.
// tokens has the lexed template markers from the mapping.
//
// Return a transformed value, or nil to exclude the field.
return myRegistry + "/" + ref.RepoName, nil
})
The callback receives both the pinned image metadata and the template tokens, so callers can produce anything from simple strings to structured expressions depending on the use case.
Updating Digests After Relocation ¶
When copying a chart to a new registry, image digests may change. Lock.WithChartDigests returns a new lock with updated digests and chart ref, leaving all other fields intact:
updated := lock.WithChartDigests(newChartRef, &v1.ChartDigests{
Digests: map[string]string{"nginx": "sha256:newdigest..."},
})
Index ¶
- Constants
- Variables
- type Chart
- type ChartDigests
- type ChartImage
- type ChartImages
- func (ci *ChartImages) Images() iter.Seq[*ChartImage]
- func (ci *ChartImages) IsOptionalImage(imageID string) bool
- func (ci *ChartImages) OptionalImages() iter.Seq[*ChartImage]
- func (ci *ChartImages) RequiredImages() iter.Seq[*ChartImage]
- func (ci *ChartImages) Walk(fn WalkFunc) (map[string]any, error)
- type Lock
- type WalkFunc
Examples ¶
Constants ¶
const PredicateType = "https://chainguard.dev/attestation/chart-lock/v1"
PredicateType is the predicate type for chart-lock attestations.
Variables ¶
var ErrChartLockNotFound = errors.New("chart-lock attestation not found")
ErrChartLockNotFound is returned when no chart-lock attestation exists.
Functions ¶
This section is empty.
Types ¶
type ChartDigests ¶ added in v0.1.51
type ChartDigests struct {
Digests map[string]string // image ID -> resolved digest
Subcharts map[string]*ChartDigests // dep name -> subchart digests
}
ChartDigests holds resolved digest strings for a chart level and its subcharts.
type ChartImage ¶
type ChartImage struct {
RepoName string `json:"repoName"`
Tag string `json:"tag"`
Digest string `json:"digest"`
}
ChartImage holds a pinned image reference.
func (*ChartImage) Reference ¶ added in v0.1.58
func (img *ChartImage) Reference(prefix string) string
Reference renders the image reference as prefix/repoName[:tag][@digest], where prefix is the registry/org the image lives under. An empty tag, digest, or prefix is omitted.
type ChartImages ¶
type ChartImages struct {
Refs map[string]*ChartImage `json:"refs"`
Template *images.Mapping `json:"template"`
Subcharts map[string]*ChartImages `json:"subcharts,omitempty"`
}
ChartImages contains the locked image references and mapping template.
Subcharts holds nested ChartImages keyed by Helm dependency name.
func (*ChartImages) Images ¶ added in v0.1.58
func (ci *ChartImages) Images() iter.Seq[*ChartImage]
Images iterates every pinned image in this ChartImages and all nested subcharts in unspecified order; a nil receiver yields nothing. Unlike Walk it ignores the template, so it also visits images with no template mapping.
func (*ChartImages) IsOptionalImage ¶ added in v0.1.58
func (ci *ChartImages) IsOptionalImage(imageID string) bool
IsOptionalImage reports whether imageID is marked as optional in the template at this level. Returns false if the template is nil or the image is not found.
func (*ChartImages) OptionalImages ¶ added in v0.1.121
func (ci *ChartImages) OptionalImages() iter.Seq[*ChartImage]
OptionalImages iterates every pinned image in this ChartImages, returning only those that are marked as optional in the template mapping.
func (*ChartImages) RequiredImages ¶ added in v0.1.121
func (ci *ChartImages) RequiredImages() iter.Seq[*ChartImage]
RequiredImages iterates every pinned image in this ChartImages, excluding those that are marked as optional in the template mapping.
func (*ChartImages) Walk ¶ added in v0.1.51
func (ci *ChartImages) Walk(fn WalkFunc) (map[string]any, error)
Walk recursively walks all images at this level and its subcharts. Each image's ref is looked up from Refs and passed to fn along with the image ID. Returns an error if an image ID in the template has no corresponding entry in Refs. Subchart results are nested under the subchart key in the output.
type Lock ¶
type Lock struct {
Chart *Chart `json:"chart"`
Images *ChartImages `json:"images"`
}
Lock contains the locked chart metadata and image references.
Example ¶
ExampleLock demonstrates constructing a Lock value.
package main
import (
"fmt"
v1 "chainguard.dev/sdk/helm/v1"
)
func main() {
lock := &v1.Lock{
Chart: &v1.Chart{
Package: "nginx",
Ref: "cgr.dev/chainguard/nginx-chart:1.0.0",
},
}
fmt.Println(lock.Chart.Package)
}
Output: nginx
func ParseChartLockAttestation ¶ added in v0.1.51
ParseChartLockAttestation parses a chart-lock predicate from a DSSE-wrapped in-toto attestation payload. Returns ErrChartLockNotFound if the payload is not a chart-lock attestation.
For an already-unwrapped in-toto statement (e.g. one surfaced by a verifier that decodes the DSSE envelope), use ParseChartLockAttestationFromPayload.
func ParseChartLockAttestationFromPayload ¶ added in v0.1.193
ParseChartLockAttestationFromPayload parses a chart-lock predicate from an in-toto attestation statement — the DSSE envelope's payload, already unwrapped. Returns ErrChartLockNotFound if the statement is not a chart-lock attestation.
func (*Lock) WithChartDigests ¶ added in v0.1.51
func (l *Lock) WithChartDigests(chartRef string, digests *ChartDigests) *Lock
WithChartDigests returns a new Lock with the chart ref updated and image digests replaced with the provided resolved digests.