attest

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2024 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewAttestationManifest added in v0.1.8

func NewAttestationManifest(subject *v1.Descriptor) (*attestation.Manifest, error)

func SignStatements added in v0.1.7

func SignStatements(ctx context.Context, idx v1.ImageIndex, signer dsse.SignerVerifier, opts *attestation.SigningOptions) ([]*attestation.Manifest, error)

this is only relevant if there are (unsigned) in-toto statements.

Example (Remote)
package main

import (
	"context"

	"github.com/docker/attest/pkg/attest"
	"github.com/docker/attest/pkg/attestation"
	"github.com/docker/attest/pkg/mirror"
	"github.com/docker/attest/pkg/oci"
	"github.com/docker/attest/pkg/signerverifier"

	v1 "github.com/google/go-containerregistry/pkg/v1"
	"github.com/google/go-containerregistry/pkg/v1/empty"
	"github.com/google/go-containerregistry/pkg/v1/mutate"
)

func main() {
	// configure signerverifier
	// local signer (unsafe for production)
	signer, err := signerverifier.GenKeyPair()
	if err != nil {
		panic(err)
	}
	// example using AWS KMS signer
	// aws_arn := "arn:aws:kms:us-west-2:123456789012:key/12345678-1234-1234-1234-123456789012"
	// aws_region := "us-west-2"
	// signer, err := signerverifier.GetAWSSigner(cmd.Context(), aws_arn, aws_region)

	// configure signing options
	opts := &attestation.SigningOptions{
		SkipTL: true, // skip trust logging to a transparency log
	}

	// load image index with unsigned attestation-manifests
	ref := "docker/image-signer-verifier:latest"
	attIdx, err := oci.IndexFromRemote(ref)
	if err != nil {
		panic(err)
	}
	// example for local image index
	// path := "/myimage"
	// attIdx, err = oci.IndexFromPath(path)
	// if err != nil {
	// 	panic(err)
	// }

	// sign all attestations in an image index
	signedManifests, err := attest.SignStatements(context.Background(), attIdx.Index, signer, opts)
	if err != nil {
		panic(err)
	}
	signedIndex := attIdx.Index
	signedIndex, err = attestation.UpdateIndexImages(signedIndex, signedManifests)
	if err != nil {
		panic(err)
	}

	// push image index with signed attestation-manifests
	err = mirror.PushIndexToRegistry(signedIndex, ref)
	if err != nil {
		panic(err)
	}
	// output image index to filesystem (optional)
	path := "/myimage"
	idx := v1.ImageIndex(empty.Index)
	idx = mutate.AppendManifests(idx, mutate.IndexAddendum{
		Add: signedIndex,
		Descriptor: v1.Descriptor{
			Annotations: map[string]string{
				oci.OCIReferenceTarget: attIdx.Name,
			},
		},
	})
	err = mirror.SaveIndexAsOCILayout(idx, path)
	if err != nil {
		panic(err)
	}
}

Types

type Outcome added in v0.1.4

type Outcome string
const (
	OutcomeSuccess  Outcome = "success"
	OutcomeFailure  Outcome = "failure"
	OutcomeNoPolicy Outcome = "no_policy"
)

func (Outcome) StringForVSA added in v0.1.4

func (o Outcome) StringForVSA() (string, error)

type VerificationResult added in v0.1.4

type VerificationResult struct {
	Outcome           Outcome
	Policy            *policy.Policy
	Input             *policy.Input
	VSA               *intoto.Statement
	Violations        []policy.Violation
	SubjectDescriptor *v1.Descriptor
}

func Verify

func Verify(ctx context.Context, src *oci.ImageSpec, opts *policy.Options) (result *VerificationResult, err error)
Example (Remote)
package main

import (
	"context"
	"fmt"
	"os"
	"path/filepath"

	"github.com/docker/attest/internal/embed"
	"github.com/docker/attest/pkg/attest"
	"github.com/docker/attest/pkg/oci"
	"github.com/docker/attest/pkg/policy"
	"github.com/docker/attest/pkg/tuf"
)

func createTufClient(outputPath string) (*tuf.Client, error) {
	// using oci tuf metadata and targets
	metadataURI := "registry-1.docker.io/docker/tuf-metadata:latest"
	targetsURI := "registry-1.docker.io/docker/tuf-targets"
	// example using http tuf metadata and targets
	// metadataURI := "https://docker.github.io/tuf-staging/metadata"
	// targetsURI := "https://docker.github.io/tuf-staging/targets"

	return tuf.NewClient(embed.RootStaging.Data, outputPath, metadataURI, targetsURI, tuf.NewMockVersionChecker())
}

func main() {
	// create a tuf client
	home, err := os.UserHomeDir()
	if err != nil {
		panic(err)
	}
	tufOutputPath := filepath.Join(home, ".docker", "tuf")
	tufClient, err := createTufClient(tufOutputPath)
	if err != nil {
		panic(err)
	}

	// create a resolver for remote attestations
	image := "registry-1.docker.io/library/notary:server"
	platform := "linux/amd64"

	// configure policy options
	opts := &policy.Options{
		TUFClient:       tufClient,
		LocalTargetsDir: filepath.Join(home, ".docker", "policy"), // location to store policy files downloaded from TUF
		LocalPolicyDir:  "",                                       // overrides TUF policy for local policy files if set
		PolicyID:        "",                                       // set to ignore policy mapping and select a policy by id
	}

	src, err := oci.ParseImageSpec(image, oci.WithPlatform(platform))
	if err != nil {
		panic(err)
	}
	// verify attestations
	result, err := attest.Verify(context.Background(), src, opts)
	if err != nil {
		panic(err)
	}
	switch result.Outcome {
	case attest.OutcomeSuccess:
		fmt.Println("policy passed")
	case attest.OutcomeNoPolicy:
		fmt.Println("no policy for image")
	case attest.OutcomeFailure:
		fmt.Println("policy failed")
	}
}

func VerifyAttestations

func VerifyAttestations(ctx context.Context, resolver oci.AttestationResolver, pctx *policy.Policy) (*VerificationResult, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL