feat: add attest sign/verify

This commit is contained in:
mrjoelkamp
2024-04-29 12:52:39 -05:00
parent ee218dd402
commit b16511d6e4
3 changed files with 102 additions and 0 deletions

2
pkg/attest/sign.go Normal file
View File

@@ -0,0 +1,2 @@
package attest

40
pkg/attest/verify.go Normal file
View File

@@ -0,0 +1,40 @@
package attest
import (
"context"
"fmt"
"github.com/docker/attest/pkg/oci"
"github.com/docker/attest/pkg/policy"
)
func VerifyAttestations(ctx context.Context, resolver oci.AttestationResolver, files []*policy.PolicyFile) error {
digest, err := resolver.ImageDigest(ctx)
if err != nil {
return fmt.Errorf("failed to get image digest: %w", err)
}
name, err := resolver.ImageName(ctx)
if err != nil {
return fmt.Errorf("failed to get image name: %w", err)
}
purl, canonical, err := oci.RefToPURL(name, resolver.ImagePlatformStr())
if err != nil {
return fmt.Errorf("failed to convert ref to purl: %w", err)
}
input := &policy.PolicyInput{
Digest: digest,
Purl: purl,
IsCanonical: canonical,
}
evaluator, err := policy.GetPolicyEvaluator(ctx)
if err != nil {
return err
}
err = evaluator.Evaluate(ctx, resolver, files, input)
if err != nil {
return fmt.Errorf("policy evaluation failed: %w", err)
}
return nil
}

60
pkg/attest/verify_test.go Normal file
View File

@@ -0,0 +1,60 @@
package attest
import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"testing"
"github.com/docker/attest/pkg/attestation"
"github.com/docker/attest/pkg/oci"
"github.com/docker/attest/pkg/policy"
"github.com/stretchr/testify/assert"
)
var (
ExampleAttestation = filepath.Join("..", "..", "test", "testdata", "example_attestation.json")
)
func TestVerifyAttestations(t *testing.T) {
ex, err := os.ReadFile(ExampleAttestation)
assert.NoError(t, err)
var env = new(attestation.Envelope)
err = json.Unmarshal(ex, env)
assert.NoError(t, err)
resolver := &oci.MockResolver{
Envs: []*attestation.Envelope{env},
}
testCases := []struct {
name string
policyEvaluationError error
expectedError error
}{
{"policy ok", nil, nil},
{"policy error", fmt.Errorf("policy error"), fmt.Errorf("policy evaluation failed: policy error")},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
mockPE := policy.MockPolicyEvaluator{
EvaluateFunc: func(ctx context.Context, resolver oci.AttestationResolver, policy []*policy.PolicyFile, input *policy.PolicyInput) error {
return tc.policyEvaluationError
},
}
ctx := policy.WithPolicyEvaluator(context.Background(), &mockPE)
err = VerifyAttestations(ctx, resolver, nil)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Equal(t, tc.expectedError.Error(), err.Error())
} else {
assert.NoError(t, err)
}
})
}
}