...

Source file src/github.com/sigstore/cosign/v2/pkg/policy/eval.go

Documentation: github.com/sigstore/cosign/v2/pkg/policy

     1  //
     2  // Copyright 2022 The Sigstore Authors.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package policy
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  
    22  	"cuelang.org/go/cue/cuecontext"
    23  	"github.com/sigstore/cosign/v2/pkg/cosign/rego"
    24  )
    25  
    26  // EvaluatePolicyAgainstJson is used to run a policy engine against JSON bytes.
    27  // These bytes can be for example Attestations, or ClusterImagePolicy result
    28  // types.
    29  // name - which attestation are we evaluating
    30  // policyType - cue|rego
    31  // policyBody - String representing either cue or rego language
    32  // jsonBytes - Bytes to evaluate against the policyBody in the given language
    33  func EvaluatePolicyAgainstJSON(ctx context.Context, name, policyType string, policyBody string, jsonBytes []byte) (warnings error, errors error) {
    34  	switch policyType {
    35  	case "cue":
    36  		cueValidationErr := evaluateCue(ctx, jsonBytes, policyBody)
    37  		if cueValidationErr != nil {
    38  			return nil, &EvaluationFailure{
    39  				fmt.Errorf("failed evaluating cue policy for %s: %w", name, cueValidationErr),
    40  			}
    41  		}
    42  	case "rego":
    43  		regoValidationWarn, regoValidationErr := evaluateRego(ctx, jsonBytes, policyBody)
    44  		if regoValidationErr != nil {
    45  			return regoValidationWarn, &EvaluationFailure{
    46  				fmt.Errorf("failed evaluating rego policy for type %s: %w", name, regoValidationErr),
    47  			}
    48  		}
    49  		// It is possible to return warning messages when the policy is compliant
    50  		return regoValidationWarn, regoValidationErr
    51  	default:
    52  		return nil, fmt.Errorf("sorry Type %s is not supported yet", policyType)
    53  	}
    54  	return nil, nil
    55  }
    56  
    57  // evaluateCue evaluates a cue policy `evaluator` against `attestation`
    58  func evaluateCue(_ context.Context, attestation []byte, evaluator string) error {
    59  	cueCtx := cuecontext.New()
    60  	cueEvaluator := cueCtx.CompileString(evaluator)
    61  	if cueEvaluator.Err() != nil {
    62  		return fmt.Errorf("failed to compile the cue policy with error: %w", cueEvaluator.Err())
    63  	}
    64  	cueAtt := cueCtx.CompileBytes(attestation)
    65  	if cueAtt.Err() != nil {
    66  		return fmt.Errorf("failed to compile the attestation data with error: %w", cueAtt.Err())
    67  	}
    68  	result := cueEvaluator.Unify(cueAtt)
    69  	if err := result.Validate(); err != nil {
    70  		return fmt.Errorf("failed to evaluate the policy with error: %w", err)
    71  	}
    72  	return nil
    73  }
    74  
    75  // evaluateRego evaluates a rego policy `evaluator` against `attestation`
    76  func evaluateRego(_ context.Context, attestation []byte, evaluator string) (warnings error, errors error) {
    77  	return rego.ValidateJSONWithModuleInput(attestation, evaluator)
    78  }
    79  

View as plain text