Revert "revert: rego evaluator result" (#15)
This reverts commit 0126ba9a0b.
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
||||
"github.com/google/go-containerregistry/pkg/v1/partial"
|
||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||
"github.com/open-policy-agent/opa/rego"
|
||||
"github.com/secure-systems-lab/go-securesystemslib/dsse"
|
||||
)
|
||||
|
||||
@@ -87,20 +88,33 @@ func GetMockSigner(ctx context.Context) (dsse.SignerVerifier, error) {
|
||||
}
|
||||
|
||||
type MockPolicyEvaluator struct {
|
||||
EvaluateFunc func(ctx context.Context, resolver oci.AttestationResolver, policy []*policy.PolicyFile, input *policy.PolicyInput) error
|
||||
EvaluateFunc func(ctx context.Context, resolver oci.AttestationResolver, policy []*policy.PolicyFile, input *policy.PolicyInput) (*rego.ResultSet, error)
|
||||
}
|
||||
|
||||
func (pe *MockPolicyEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationResolver, policy []*policy.PolicyFile, input *policy.PolicyInput) error {
|
||||
func (pe *MockPolicyEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationResolver, policy []*policy.PolicyFile, input *policy.PolicyInput) (*rego.ResultSet, error) {
|
||||
if pe.EvaluateFunc != nil {
|
||||
return pe.EvaluateFunc(ctx, resolver, policy, input)
|
||||
}
|
||||
return nil
|
||||
return AllowedResult(), nil
|
||||
}
|
||||
|
||||
func GetMockPolicy() policy.PolicyEvaluator {
|
||||
return &MockPolicyEvaluator{
|
||||
EvaluateFunc: func(ctx context.Context, resolver oci.AttestationResolver, policy []*policy.PolicyFile, input *policy.PolicyInput) error {
|
||||
return nil
|
||||
EvaluateFunc: func(ctx context.Context, resolver oci.AttestationResolver, pfs []*policy.PolicyFile, input *policy.PolicyInput) (*rego.ResultSet, error) {
|
||||
return AllowedResult(), nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AllowedResult() *rego.ResultSet {
|
||||
return ®o.ResultSet{
|
||||
{
|
||||
Bindings: rego.Vars{},
|
||||
Expressions: []*rego.ExpressionValue{
|
||||
{
|
||||
Value: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,13 @@ func VerifyAttestations(ctx context.Context, resolver oci.AttestationResolver, f
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = evaluator.Evaluate(ctx, resolver, files, input)
|
||||
rs, err := evaluator.Evaluate(ctx, resolver, files, input)
|
||||
if err != nil {
|
||||
return fmt.Errorf("policy evaluation failed: %w", err)
|
||||
}
|
||||
if !rs.Allowed() {
|
||||
return fmt.Errorf("policy evaluation failed: %s", fmt.Sprint(rs))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/docker/attest/pkg/attestation"
|
||||
"github.com/docker/attest/pkg/oci"
|
||||
"github.com/docker/attest/pkg/policy"
|
||||
"github.com/open-policy-agent/opa/rego"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -43,8 +44,8 @@ func TestVerifyAttestations(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
mockPE := test.MockPolicyEvaluator{
|
||||
EvaluateFunc: func(ctx context.Context, resolver oci.AttestationResolver, pfs []*policy.PolicyFile, input *policy.PolicyInput) error {
|
||||
return tc.policyEvaluationError
|
||||
EvaluateFunc: func(ctx context.Context, resolver oci.AttestationResolver, pfs []*policy.PolicyFile, input *policy.PolicyInput) (*rego.ResultSet, error) {
|
||||
return test.AllowedResult(), tc.policyEvaluationError
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/attest/pkg/oci"
|
||||
"github.com/open-policy-agent/opa/rego"
|
||||
)
|
||||
|
||||
type policyEvaluatorCtxKeyType struct{}
|
||||
@@ -26,5 +27,5 @@ func GetPolicyEvaluator(ctx context.Context) (PolicyEvaluator, error) {
|
||||
}
|
||||
|
||||
type PolicyEvaluator interface {
|
||||
Evaluate(ctx context.Context, resolver oci.AttestationResolver, policy []*PolicyFile, input *PolicyInput) error
|
||||
Evaluate(ctx context.Context, resolver oci.AttestationResolver, policy []*PolicyFile, input *PolicyInput) (*rego.ResultSet, error)
|
||||
}
|
||||
|
||||
@@ -97,11 +97,12 @@ func TestRegoEvaluator_Evaluate(t *testing.T) {
|
||||
|
||||
policyFiles, err := policy.ResolvePolicy(ctx, tc.resolver, tc.policy)
|
||||
assert.NoErrorf(t, err, "failed to resolve policy")
|
||||
err = re.Evaluate(ctx, tc.resolver, policyFiles, tc.input)
|
||||
rs, err := re.Evaluate(ctx, tc.resolver, policyFiles, tc.input)
|
||||
|
||||
if tc.expectSuccess {
|
||||
assert.NoErrorf(t, err, "Evaluate failed")
|
||||
} else {
|
||||
assert.Errorf(t, err, "Evaluate should have failed")
|
||||
assert.False(t, rs.Allowed(), "Evaluate should have failed")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -29,10 +29,11 @@ type regoEvaluator struct {
|
||||
func NewRegoEvaluator(debug bool) PolicyEvaluator {
|
||||
return ®oEvaluator{
|
||||
debug: debug,
|
||||
query: "data.attestations.allow",
|
||||
}
|
||||
}
|
||||
|
||||
func (re *regoEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationResolver, files []*PolicyFile, input *PolicyInput) error {
|
||||
func (re *regoEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationResolver, files []*PolicyFile, input *PolicyInput) (*rego.ResultSet, error) {
|
||||
var regoOpts []func(*rego.Rego)
|
||||
|
||||
// Create a new in-memory store
|
||||
@@ -41,7 +42,7 @@ func (re *regoEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationR
|
||||
params.Write = true
|
||||
txn, err := store.NewTransaction(ctx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, target := range files {
|
||||
@@ -49,11 +50,11 @@ func (re *regoEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationR
|
||||
if filepath.Ext(target.Path) == ".yaml" {
|
||||
yamlData, err := loadYAML(target.Path, target.Content)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
err = store.Write(ctx, txn, storage.AddOp, storage.Path{}, yamlData)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
regoOpts = append(regoOpts, rego.Module(target.Path, string(target.Content)))
|
||||
@@ -63,7 +64,7 @@ func (re *regoEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationR
|
||||
err = store.Commit(ctx, txn)
|
||||
if err != nil {
|
||||
store.Abort(ctx, txn)
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if re.debug {
|
||||
@@ -75,7 +76,7 @@ func (re *regoEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationR
|
||||
}
|
||||
|
||||
regoOpts = append(regoOpts,
|
||||
rego.Query("data.docker.allow"),
|
||||
rego.Query(re.query),
|
||||
rego.StrictBuiltinErrors(true),
|
||||
rego.Input(input),
|
||||
rego.Store(store),
|
||||
@@ -86,15 +87,7 @@ func (re *regoEvaluator) Evaluate(ctx context.Context, resolver oci.AttestationR
|
||||
|
||||
r := rego.New(regoOpts...)
|
||||
rs, err := r.Eval(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error from Eval: %w", err)
|
||||
}
|
||||
|
||||
if !rs.Allowed() {
|
||||
return fmt.Errorf("policy evaluation failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
return &rs, err
|
||||
}
|
||||
|
||||
var dynamicObj = types.NewObject(nil, types.NewDynamicProperty(types.S, types.A))
|
||||
|
||||
Reference in New Issue
Block a user