Skip to content

Commit

Permalink
Add PayloadProvider interface to decouple AttestationToPayloadJSON fr…
Browse files Browse the repository at this point in the history
…om oci.Signature interface (#3693)

* Add PayloadProvider interface to decouple AttestationToPayloadJSON from oci.Signature interface

Signed-off-by: Cody Soyland <codysoyland@github.com>

* Add test for PayloadProvider interface

Signed-off-by: Cody Soyland <codysoyland@github.com>

---------

Signed-off-by: Cody Soyland <codysoyland@github.com>
  • Loading branch information
codysoyland authored May 13, 2024
1 parent 17c9af7 commit d2766d8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
13 changes: 12 additions & 1 deletion pkg/policy/attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ import (
"github.com/sigstore/cosign/v2/pkg/cosign/attestation"
)

// PayloadProvider is a subset of oci.Signature that only provides the
// Payload() method.
type PayloadProvider interface {
// Payload fetches the opaque data that is being signed.
// This will always return data when there is no error.
Payload() ([]byte, error)
}

// Assert that oci.Signature implements PayloadProvider
var _ PayloadProvider = (oci.Signature)(nil)

// AttestationToPayloadJSON takes in a verified Attestation (oci.Signature) and
// marshals it into a JSON depending on the payload that's then consumable
// by policy engine like cue, rego, etc.
Expand All @@ -45,7 +56,7 @@ import (
// or the predicateType is not the one they are looking for. Without returning
// this, it's hard for users to know which attestations/predicateTypes were
// inspected.
func AttestationToPayloadJSON(_ context.Context, predicateType string, verifiedAttestation oci.Signature) ([]byte, string, error) {
func AttestationToPayloadJSON(_ context.Context, predicateType string, verifiedAttestation PayloadProvider) ([]byte, string, error) {
if predicateType == "" {
return nil, "", errors.New("missing predicate type")
}
Expand Down
45 changes: 45 additions & 0 deletions pkg/policy/attestation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package policy

import (
"bytes"
"context"
"crypto/x509"
"encoding/json"
Expand Down Expand Up @@ -166,6 +167,50 @@ func TestAttestationToPayloadJson(t *testing.T) {
}
}

type myPayloadProvider struct {
payload []byte
}

func (m *myPayloadProvider) Payload() ([]byte, error) {
return m.payload, nil
}

// assert that myPayloadProvider implements PayloadProvider
var _ PayloadProvider = &myPayloadProvider{}

// TestPayloadProvider tests that the PayloadProvider interface is working as expected.
func TestPayloadProvider(t *testing.T) {
// Control: oci.Signature
attestationBytes := readAttestationFromTestFile(t, "valid", "vuln")
ociSig, err := static.NewSignature(attestationBytes, "")
if err != nil {
t.Fatal("Failed to create static.NewSignature: ", err)
}
jsonBytes, gotPredicateType, err := AttestationToPayloadJSON(context.TODO(), "vuln", ociSig)
if err != nil {
t.Fatalf("Failed to convert : %s", err)
}
if len(jsonBytes) == 0 {
t.Fatalf("Failed to get jsonBytes")
}
if gotPredicateType != attestation.CosignVulnProvenanceV01 {
t.Fatalf("Did not get expected predicateType, want: %s got: %s", attestation.CosignVulnProvenanceV01, gotPredicateType)
}

// Test: myPayloadProvider
provider := &myPayloadProvider{payload: attestationBytes}
jsonBytes2, gotPredicateType2, err := AttestationToPayloadJSON(context.TODO(), "vuln", provider)
if err != nil {
t.Fatalf("Failed to convert : %s", err)
}
if !bytes.Equal(jsonBytes, jsonBytes2) {
t.Fatalf("Expected same jsonBytes, got different")
}
if gotPredicateType != gotPredicateType2 {
t.Fatalf("Expected same predicateType, got different")
}
}

func checkPredicateType(t *testing.T, want, got string) {
t.Helper()
if want != got {
Expand Down

0 comments on commit d2766d8

Please sign in to comment.