maintain provenance of original artifact reference

This commit is contained in:
CamrynCarter
2026-08-13 17:07:02 -07:00
parent b75f9a2672
commit e375893381
3 changed files with 45 additions and 0 deletions
+27
View File
@@ -128,6 +128,15 @@ func storeFile(ctx context.Context, s *store.Layout, fi v1.File, ro *flags.CliRo
resolvedPath = abs
}
}
// Preserve the original source (a URL for remote files, an absolute path for
// local ones) so `store create manifest` can recover it later; nothing else in
// the store retains it.
desc.Annotations[consts.OriginalRefAnnotation] = resolvedPath
if err := s.OCI.AddIndex(desc); err != nil {
return err
}
if auditLevel(ro) != "none" {
e := audit.Entry{
StoreID: s.StoreID,
@@ -1177,6 +1186,15 @@ func fetchChart(ctx context.Context, s *store.Layout, j chartJob, tempRoot strin
}
}
// Charts have no registry-qualified annotation the way images do (via
// ContainerdImageNameKey), and RepoURL is otherwise never persisted anywhere in
// the store, so capture both here to maintain provenance regardless of whether
// --rewrite is ever applied.
chartDesc.Annotations[consts.OriginalRefAnnotation] = encodeOriginalChartRef(j.cfg.RepoURL, ref.Name())
if err := s.OCI.AddIndex(chartDesc); err != nil {
return nil, nil, err
}
if auditLevel(ro) != "none" {
e := audit.Entry{
StoreID: s.StoreID,
@@ -1516,3 +1534,12 @@ func rewriteChartReference(ctx context.Context, s *store.Layout, ref name.Refere
return nil
}
// encodeOriginalChartRef combines a chart's source repoURL with its pre-rewrite
// store "repo:tag" into a single string suitable for consts.OriginalRefAnnotation.
// Charts have no registry-qualified annotation the way images do (via
// ContainerdImageNameKey), so the repoURL has to be carried alongside the ref
// itself for `store create manifest` to recover a fully pullable chart reference.
func encodeOriginalChartRef(repoURL, total string) string {
return repoURL + "|" + total
}
+12
View File
@@ -71,6 +71,18 @@ const (
ImageAnnotationExcludeExtras = "hauler.dev/exclude-extras"
ImageRefKey = "org.opencontainers.image.ref.name"
// OriginalRefAnnotation preserves each artifact's original source reference at
// the time it's first added to the store (images, charts, and files alike,
// whether local or remote), regardless of whether --rewrite is ever applied, so
// tooling like `store create manifest` can always recover a pullable source even
// after the store's own ref/containerd-name annotations have since been
// overwritten by a rewrite. For images this is the fully qualified containerd
// image name (registry/repo:tag); for charts, which have no equivalent
// registry-qualified annotation, it's "repoURL|repo:tag" (see
// encodeOriginalChartRef in cmd/hauler/cli/store); for files it's the original
// URL or absolute local path.
OriginalRefAnnotation = "hauler.dev/original-ref"
// cosign keyless validation options
ImageAnnotationCertIdentity = "hauler.dev/certificate-identity"
ImageAnnotationCertIdentityRegexp = "hauler.dev/certificate-identity-regexp"
+6
View File
@@ -464,6 +464,9 @@ func (l *Layout) writeImage(ctx context.Context, annotationRef gname.Reference,
consts.KindAnnotationName: kind,
ocispec.AnnotationRefName: strings.TrimPrefix(annotationRef.Name(), annotationRef.Context().RegistryStr()+"/"),
consts.ContainerdImageNameKey: containerdName,
// Captured once at the initial add so the original, pullable reference
// survives even if a later --rewrite overwrites the annotations above.
consts.OriginalRefAnnotation: containerdName,
},
}
return l.OCI.AddIndex(desc)
@@ -539,6 +542,9 @@ func (l *Layout) writeIndex(ctx context.Context, annotationRef gname.Reference,
consts.KindAnnotationName: kind,
ocispec.AnnotationRefName: strings.TrimPrefix(annotationRef.Name(), annotationRef.Context().RegistryStr()+"/"),
consts.ContainerdImageNameKey: annotationRef.Name(),
// Captured once at the initial add so the original, pullable reference
// survives even if a later --rewrite overwrites the annotations above.
consts.OriginalRefAnnotation: annotationRef.Name(),
},
}
return l.OCI.AddIndex(desc)