Files
attest/pkg/oci/types.go
Jonny Stoten 1a7897a052 Return VSA and rich errors from verification (#38)
* Start of richer results from verification

* Pull out VSA code from signing

* Expose attestation signing fns

* Add VSA test

* Notes for policy result

* Require separate policy for VSA creation

* Load test signing key from tests

* Return rich object from policy

* Add result object schema and fix tests

* Ensure example test runs

* Remove data.yaml files from mock policies

* Don't run example - TUF policy isn't compatible

* Add attestation to manifests for all subjects

* Ensure adding attestation doesn't touch statements

* Don't export sign function

* Remove attestations from VerificationResult

* Change bool to Outcome enum in result

* Use outputLayout directly

* Make clearer that Outcome strings are for VSA

* Return multiple SLSA levels from policy

* Fix unmarshalling of policy-id (#39)

* Rename function

* Rename policy.VerificationResult -> policy.Result

* Re-add test for canonical input

---------

Co-authored-by: James Carnegie <james.carnegie@docker.com>
Co-authored-by: James Carnegie <kipz@users.noreply.github.com>
2024-05-22 14:49:23 +01:00

69 lines
1.9 KiB
Go

package oci
import (
"fmt"
"log"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/layout"
"github.com/google/go-containerregistry/pkg/v1/remote"
)
const (
DockerReferenceDigest = "vnd.docker.reference.digest"
AttestationManifestType = "attestation-manifest"
InTotoPredicateType = "in-toto.io/predicate-type"
OciReferenceTarget = "org.opencontainers.image.ref.name"
)
type AttestationIndex struct {
Index v1.ImageIndex
Name string
}
func AttestationIndexFromPath(path string) (*AttestationIndex, error) {
wrapperIdx, err := layout.ImageIndexFromPath(path)
if err != nil {
return nil, fmt.Errorf("failed to load image index: %w", err)
}
idxm, err := wrapperIdx.IndexManifest()
if err != nil {
return nil, fmt.Errorf("failed to get digest: %w", err)
}
imageName := idxm.Manifests[0].Annotations[OciReferenceTarget]
idxDigest := idxm.Manifests[0].Digest
idx, err := wrapperIdx.ImageIndex(idxDigest)
if err != nil {
return nil, fmt.Errorf("failed to extract ImageIndex for digest %s: %w", idxDigest.String(), err)
}
return &AttestationIndex{
Index: idx,
Name: imageName,
}, nil
}
func AttestationIndexFromRemote(image string) (*AttestationIndex, error) {
ref, err := name.ParseReference(image)
if err != nil {
log.Fatalf("Failed to parse image name: %v", err)
}
// Get the authenticator from the default Docker keychain
auth, err := authn.DefaultKeychain.Resolve(ref.Context())
if err != nil {
log.Fatalf("Failed to get authenticator: %v", err)
}
// Pull the image from the registry
idx, err := remote.Index(ref, remote.WithAuth(auth))
if err != nil {
return nil, fmt.Errorf("failed to pull image %s: %w", image, err)
}
return &AttestationIndex{
Index: idx,
Name: image,
}, nil
}