diff --git a/pkg/policy/eval.go b/pkg/policy/eval.go index 27861b4329d9..8c669a7a899e 100644 --- a/pkg/policy/eval.go +++ b/pkg/policy/eval.go @@ -20,6 +20,7 @@ import ( "fmt" "cuelang.org/go/cue/cuecontext" + "github.com/sigstore/cosign/pkg/cosign/rego" "knative.dev/pkg/logging" ) @@ -42,7 +43,7 @@ func EvaluatePolicyAgainstJSON(ctx context.Context, name, policyType string, pol case "rego": regoValidationErr := evaluateRego(ctx, jsonBytes, policyBody) if regoValidationErr != nil { - return fmt.Errorf("failed evaluating rego policy for type %s", name) + return fmt.Errorf("failed evaluating rego policy for type %s: %s", name, regoValidationErr.Error()) } default: return fmt.Errorf("sorry Type %s is not supported yet", policyType) @@ -73,9 +74,8 @@ func evaluateCue(ctx context.Context, attestation []byte, evaluator string) erro // evaluateRego evaluates a rego policy `evaluator` against `attestation` func evaluateRego(ctx context.Context, attestation []byte, evaluator string) error { - // TODO(vaikas) Fix this - // The existing stuff wants files, and it doesn't work. There must be - // a way to load it from a []byte like we can do with cue. Tomorrows problem - // regoValidationErrs := rego.ValidateJSON(payload, regoPolicies) - return fmt.Errorf("TODO(vaikas): Don't know how to this from bytes yet") + logging.FromContext(ctx).Infof("Evaluating attestation: %s", string(attestation)) + logging.FromContext(ctx).Infof("Evaluating evaluator: %s", evaluator) + + return rego.ValidateJSONWithModuleInput(attestation, evaluator) } diff --git a/pkg/policy/eval_test.go b/pkg/policy/eval_test.go index c44729bc265d..999c5f4a52e5 100644 --- a/pkg/policy/eval_test.go +++ b/pkg/policy/eval_test.go @@ -167,8 +167,46 @@ func TestEvalPolicy(t *testing.T) { keylesssignature: { signatures: list.MaxItems(1) & list.MinItems(1) } - }`, - }} + }`}, { + name: "Rego cluster image policy main policy, checks out", + json: cipAttestation, + policyType: "rego", + policyFile: `package sigstore + + default isCompliant = false + + isCompliant { + attestationsKeylessATT := input.authorityMatches.keylessatt.attestations + count(attestationsKeylessATT) == 1 + + attestationsKeyATT := input.authorityMatches.keyatt.attestations + count(attestationsKeyATT) == 1 + + keySignature := input.authorityMatches.keysignature.signatures + count(keySignature) == 1 + }`, + }, + { + name: "Rego cluster image policy main policy, fails", + json: cipAttestation, + policyType: "rego", + wantErr: true, + wantErrSub: `failed evaluating rego policy for type Rego cluster image policy main policy, fails: policy is not compliant for query 'isCompliant = data.sigstore.isCompliant'`, + policyFile: `package sigstore + + default isCompliant = false + + isCompliant { + attestationsKeylessATT := input.authorityMatches.keylessatt.attestations + count(attestationsKeylessATT) == 2 + + attestationsKeyATT := input.authorityMatches.keyatt.attestations + count(attestationsKeyATT) == 1 + + keySignature := input.authorityMatches.keysignature.signatures + count(keySignature) == 1 + }`, + }} for _, tc := range tests { ctx := context.Background() err := EvaluatePolicyAgainstJSON(ctx, tc.name, tc.policyType, tc.policyFile, []byte(tc.json))