From caab45b82194e35562215dcf6b437c1e4bb2ba4e Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Sun, 7 Dec 2025 15:51:22 +0100 Subject: [PATCH 1/7] expose generic evaluation Signed-off-by: Sylwester Piskozub --- .../controlplane/v1/policy_evaluation.pb.go | 286 ++++++++++++ .../controlplane/v1/policy_evaluation.proto | 52 +++ .../v1/policy_evaluation_grpc.pb.go | 110 +++++ .../v1/policy_evaluation_http.pb.go | 78 ++++ .../controlplane/v1/policy_evaluation.ts | 416 ++++++++++++++++++ ...tionServiceEvaluateRequest.jsonschema.json | 28 ++ ...aluationServiceEvaluateRequest.schema.json | 28 ++ ...ionServiceEvaluateResponse.jsonschema.json | 12 + ...luationServiceEvaluateResponse.schema.json | 12 + app/controlplane/cmd/wire_gen.go | 3 + app/controlplane/configs/config.devel.yaml | 10 +- app/controlplane/internal/server/grpc.go | 2 + .../internal/service/policyevaluation.go | 58 +++ app/controlplane/internal/service/service.go | 1 + app/controlplane/pkg/biz/biz.go | 1 + app/controlplane/pkg/biz/policyevaluation.go | 117 +++++ pkg/policies/policies.go | 19 + 17 files changed, 1228 insertions(+), 5 deletions(-) create mode 100644 app/controlplane/api/controlplane/v1/policy_evaluation.pb.go create mode 100644 app/controlplane/api/controlplane/v1/policy_evaluation.proto create mode 100644 app/controlplane/api/controlplane/v1/policy_evaluation_grpc.pb.go create mode 100644 app/controlplane/api/controlplane/v1/policy_evaluation_http.pb.go create mode 100644 app/controlplane/api/gen/frontend/controlplane/v1/policy_evaluation.ts create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json create mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json create mode 100644 app/controlplane/internal/service/policyevaluation.go create mode 100644 app/controlplane/pkg/biz/policyevaluation.go diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go b/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go new file mode 100644 index 000000000..c64c356eb --- /dev/null +++ b/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go @@ -0,0 +1,286 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: controlplane/v1/policy_evaluation.proto + +package v1 + +import ( + _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" + v1 "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PolicyEvaluationServiceEvaluateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PolicyReference string `protobuf:"bytes,1,opt,name=policy_reference,json=policyReference,proto3" json:"policy_reference,omitempty"` + Inputs map[string]string `protobuf:"bytes,2,rep,name=inputs,proto3" json:"inputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *PolicyEvaluationServiceEvaluateRequest) Reset() { + *x = PolicyEvaluationServiceEvaluateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_policy_evaluation_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PolicyEvaluationServiceEvaluateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PolicyEvaluationServiceEvaluateRequest) ProtoMessage() {} + +func (x *PolicyEvaluationServiceEvaluateRequest) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_policy_evaluation_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PolicyEvaluationServiceEvaluateRequest.ProtoReflect.Descriptor instead. +func (*PolicyEvaluationServiceEvaluateRequest) Descriptor() ([]byte, []int) { + return file_controlplane_v1_policy_evaluation_proto_rawDescGZIP(), []int{0} +} + +func (x *PolicyEvaluationServiceEvaluateRequest) GetPolicyReference() string { + if x != nil { + return x.PolicyReference + } + return "" +} + +func (x *PolicyEvaluationServiceEvaluateRequest) GetInputs() map[string]string { + if x != nil { + return x.Inputs + } + return nil +} + +type PolicyEvaluationServiceEvaluateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result *v1.PolicyEvaluation `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` +} + +func (x *PolicyEvaluationServiceEvaluateResponse) Reset() { + *x = PolicyEvaluationServiceEvaluateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_controlplane_v1_policy_evaluation_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PolicyEvaluationServiceEvaluateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PolicyEvaluationServiceEvaluateResponse) ProtoMessage() {} + +func (x *PolicyEvaluationServiceEvaluateResponse) ProtoReflect() protoreflect.Message { + mi := &file_controlplane_v1_policy_evaluation_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PolicyEvaluationServiceEvaluateResponse.ProtoReflect.Descriptor instead. +func (*PolicyEvaluationServiceEvaluateResponse) Descriptor() ([]byte, []int) { + return file_controlplane_v1_policy_evaluation_proto_rawDescGZIP(), []int{1} +} + +func (x *PolicyEvaluationServiceEvaluateResponse) GetResult() *v1.PolicyEvaluation { + if x != nil { + return x.Result + } + return nil +} + +var File_controlplane_v1_policy_evaluation_proto protoreflect.FileDescriptor + +var file_controlplane_v1_policy_evaluation_proto_rawDesc = []byte{ + 0x0a, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, + 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x23, 0x61, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x61, 0x66, 0x74, + 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, + 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc9, 0x02, 0x0a, 0x26, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x10, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x06, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x3a, 0x53, 0x92, 0x41, 0x50, 0x0a, 0x4e, 0x2a, 0x26, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x32, 0x24, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0xc1, 0x01, 0x0a, 0x27, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x3a, 0x5c, 0x92, 0x41, + 0x59, 0x0a, 0x57, 0x2a, 0x27, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x2c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, + 0x67, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x32, 0xcc, 0x02, 0x0a, 0x17, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xef, 0x01, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x61, 0x74, 0x65, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, + 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, + 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x92, 0x41, 0x46, 0x12, 0x17, 0x45, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x1a, 0x19, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x73, 0x20, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x3a, + 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, + 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2d, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x1a, 0x3f, 0x92, 0x41, 0x3c, 0x0a, 0x17, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x21, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, + 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, + 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, + 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_controlplane_v1_policy_evaluation_proto_rawDescOnce sync.Once + file_controlplane_v1_policy_evaluation_proto_rawDescData = file_controlplane_v1_policy_evaluation_proto_rawDesc +) + +func file_controlplane_v1_policy_evaluation_proto_rawDescGZIP() []byte { + file_controlplane_v1_policy_evaluation_proto_rawDescOnce.Do(func() { + file_controlplane_v1_policy_evaluation_proto_rawDescData = protoimpl.X.CompressGZIP(file_controlplane_v1_policy_evaluation_proto_rawDescData) + }) + return file_controlplane_v1_policy_evaluation_proto_rawDescData +} + +var file_controlplane_v1_policy_evaluation_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_controlplane_v1_policy_evaluation_proto_goTypes = []interface{}{ + (*PolicyEvaluationServiceEvaluateRequest)(nil), // 0: controlplane.v1.PolicyEvaluationServiceEvaluateRequest + (*PolicyEvaluationServiceEvaluateResponse)(nil), // 1: controlplane.v1.PolicyEvaluationServiceEvaluateResponse + nil, // 2: controlplane.v1.PolicyEvaluationServiceEvaluateRequest.InputsEntry + (*v1.PolicyEvaluation)(nil), // 3: attestation.v1.PolicyEvaluation +} +var file_controlplane_v1_policy_evaluation_proto_depIdxs = []int32{ + 2, // 0: controlplane.v1.PolicyEvaluationServiceEvaluateRequest.inputs:type_name -> controlplane.v1.PolicyEvaluationServiceEvaluateRequest.InputsEntry + 3, // 1: controlplane.v1.PolicyEvaluationServiceEvaluateResponse.result:type_name -> attestation.v1.PolicyEvaluation + 0, // 2: controlplane.v1.PolicyEvaluationService.Evaluate:input_type -> controlplane.v1.PolicyEvaluationServiceEvaluateRequest + 1, // 3: controlplane.v1.PolicyEvaluationService.Evaluate:output_type -> controlplane.v1.PolicyEvaluationServiceEvaluateResponse + 3, // [3:4] is the sub-list for method output_type + 2, // [2:3] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_controlplane_v1_policy_evaluation_proto_init() } +func file_controlplane_v1_policy_evaluation_proto_init() { + if File_controlplane_v1_policy_evaluation_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_controlplane_v1_policy_evaluation_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicyEvaluationServiceEvaluateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controlplane_v1_policy_evaluation_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicyEvaluationServiceEvaluateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_controlplane_v1_policy_evaluation_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_controlplane_v1_policy_evaluation_proto_goTypes, + DependencyIndexes: file_controlplane_v1_policy_evaluation_proto_depIdxs, + MessageInfos: file_controlplane_v1_policy_evaluation_proto_msgTypes, + }.Build() + File_controlplane_v1_policy_evaluation_proto = out.File + file_controlplane_v1_policy_evaluation_proto_rawDesc = nil + file_controlplane_v1_policy_evaluation_proto_goTypes = nil + file_controlplane_v1_policy_evaluation_proto_depIdxs = nil +} diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation.proto b/app/controlplane/api/controlplane/v1/policy_evaluation.proto new file mode 100644 index 000000000..22d6a7a17 --- /dev/null +++ b/app/controlplane/api/controlplane/v1/policy_evaluation.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; + +package controlplane.v1; + +import "attestation/v1/crafting_state.proto"; +import "buf/validate/validate.proto"; +import "google/api/annotations.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; + +option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1;v1"; + +service PolicyEvaluationService { + rpc Evaluate(PolicyEvaluationServiceEvaluateRequest) returns (PolicyEvaluationServiceEvaluateResponse) { + option (google.api.http) = { + post: "/policy-evaluations/evaluate" + body: "*" + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "Evaluate generic policy" + description: "Evaluates generic policy." + produces: ["application/json"] + }; + } + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_tag) = { + name: "PolicyEvaluationService" + description: "Generic policy evaluation service" + }; +} + +message PolicyEvaluationServiceEvaluateRequest { + string policy_reference = 1 [(buf.validate.field).string.min_len = 1]; + map inputs = 2; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + json_schema: { + title: "PolicyEvaluationServiceEvaluateRequest" + description: "Request to evaluate a generic policy" + } + }; +} + +message PolicyEvaluationServiceEvaluateResponse { + attestation.v1.PolicyEvaluation result = 1; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + json_schema: { + title: "PolicyEvaluationServiceEvaluateResponse" + description: "Response containing policy evaluation result" + } + }; +} diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation_grpc.pb.go b/app/controlplane/api/controlplane/v1/policy_evaluation_grpc.pb.go new file mode 100644 index 000000000..06cd0beb8 --- /dev/null +++ b/app/controlplane/api/controlplane/v1/policy_evaluation_grpc.pb.go @@ -0,0 +1,110 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: controlplane/v1/policy_evaluation.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + PolicyEvaluationService_Evaluate_FullMethodName = "/controlplane.v1.PolicyEvaluationService/Evaluate" +) + +// PolicyEvaluationServiceClient is the client API for PolicyEvaluationService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type PolicyEvaluationServiceClient interface { + Evaluate(ctx context.Context, in *PolicyEvaluationServiceEvaluateRequest, opts ...grpc.CallOption) (*PolicyEvaluationServiceEvaluateResponse, error) +} + +type policyEvaluationServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewPolicyEvaluationServiceClient(cc grpc.ClientConnInterface) PolicyEvaluationServiceClient { + return &policyEvaluationServiceClient{cc} +} + +func (c *policyEvaluationServiceClient) Evaluate(ctx context.Context, in *PolicyEvaluationServiceEvaluateRequest, opts ...grpc.CallOption) (*PolicyEvaluationServiceEvaluateResponse, error) { + out := new(PolicyEvaluationServiceEvaluateResponse) + err := c.cc.Invoke(ctx, PolicyEvaluationService_Evaluate_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// PolicyEvaluationServiceServer is the server API for PolicyEvaluationService service. +// All implementations must embed UnimplementedPolicyEvaluationServiceServer +// for forward compatibility +type PolicyEvaluationServiceServer interface { + Evaluate(context.Context, *PolicyEvaluationServiceEvaluateRequest) (*PolicyEvaluationServiceEvaluateResponse, error) + mustEmbedUnimplementedPolicyEvaluationServiceServer() +} + +// UnimplementedPolicyEvaluationServiceServer must be embedded to have forward compatible implementations. +type UnimplementedPolicyEvaluationServiceServer struct { +} + +func (UnimplementedPolicyEvaluationServiceServer) Evaluate(context.Context, *PolicyEvaluationServiceEvaluateRequest) (*PolicyEvaluationServiceEvaluateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Evaluate not implemented") +} +func (UnimplementedPolicyEvaluationServiceServer) mustEmbedUnimplementedPolicyEvaluationServiceServer() { +} + +// UnsafePolicyEvaluationServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to PolicyEvaluationServiceServer will +// result in compilation errors. +type UnsafePolicyEvaluationServiceServer interface { + mustEmbedUnimplementedPolicyEvaluationServiceServer() +} + +func RegisterPolicyEvaluationServiceServer(s grpc.ServiceRegistrar, srv PolicyEvaluationServiceServer) { + s.RegisterService(&PolicyEvaluationService_ServiceDesc, srv) +} + +func _PolicyEvaluationService_Evaluate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PolicyEvaluationServiceEvaluateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PolicyEvaluationServiceServer).Evaluate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PolicyEvaluationService_Evaluate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PolicyEvaluationServiceServer).Evaluate(ctx, req.(*PolicyEvaluationServiceEvaluateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// PolicyEvaluationService_ServiceDesc is the grpc.ServiceDesc for PolicyEvaluationService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var PolicyEvaluationService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "controlplane.v1.PolicyEvaluationService", + HandlerType: (*PolicyEvaluationServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Evaluate", + Handler: _PolicyEvaluationService_Evaluate_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "controlplane/v1/policy_evaluation.proto", +} diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation_http.pb.go b/app/controlplane/api/controlplane/v1/policy_evaluation_http.pb.go new file mode 100644 index 000000000..5c8b7e334 --- /dev/null +++ b/app/controlplane/api/controlplane/v1/policy_evaluation_http.pb.go @@ -0,0 +1,78 @@ +// Code generated by protoc-gen-go-http. DO NOT EDIT. +// versions: +// - protoc-gen-go-http v2.7.1 +// - protoc (unknown) +// source: controlplane/v1/policy_evaluation.proto + +package v1 + +import ( + context "context" + http "github.com/go-kratos/kratos/v2/transport/http" + binding "github.com/go-kratos/kratos/v2/transport/http/binding" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the kratos package it is being compiled against. +var _ = new(context.Context) +var _ = binding.EncodeURL + +const _ = http.SupportPackageIsVersion1 + +const OperationPolicyEvaluationServiceEvaluate = "/controlplane.v1.PolicyEvaluationService/Evaluate" + +type PolicyEvaluationServiceHTTPServer interface { + Evaluate(context.Context, *PolicyEvaluationServiceEvaluateRequest) (*PolicyEvaluationServiceEvaluateResponse, error) +} + +func RegisterPolicyEvaluationServiceHTTPServer(s *http.Server, srv PolicyEvaluationServiceHTTPServer) { + r := s.Route("/") + r.POST("/policy-evaluations/evaluate", _PolicyEvaluationService_Evaluate0_HTTP_Handler(srv)) +} + +func _PolicyEvaluationService_Evaluate0_HTTP_Handler(srv PolicyEvaluationServiceHTTPServer) func(ctx http.Context) error { + return func(ctx http.Context) error { + var in PolicyEvaluationServiceEvaluateRequest + if err := ctx.Bind(&in); err != nil { + return err + } + if err := ctx.BindQuery(&in); err != nil { + return err + } + http.SetOperation(ctx, OperationPolicyEvaluationServiceEvaluate) + h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.Evaluate(ctx, req.(*PolicyEvaluationServiceEvaluateRequest)) + }) + out, err := h(ctx, &in) + if err != nil { + return err + } + reply := out.(*PolicyEvaluationServiceEvaluateResponse) + return ctx.Result(200, reply) + } +} + +type PolicyEvaluationServiceHTTPClient interface { + Evaluate(ctx context.Context, req *PolicyEvaluationServiceEvaluateRequest, opts ...http.CallOption) (rsp *PolicyEvaluationServiceEvaluateResponse, err error) +} + +type PolicyEvaluationServiceHTTPClientImpl struct { + cc *http.Client +} + +func NewPolicyEvaluationServiceHTTPClient(client *http.Client) PolicyEvaluationServiceHTTPClient { + return &PolicyEvaluationServiceHTTPClientImpl{client} +} + +func (c *PolicyEvaluationServiceHTTPClientImpl) Evaluate(ctx context.Context, in *PolicyEvaluationServiceEvaluateRequest, opts ...http.CallOption) (*PolicyEvaluationServiceEvaluateResponse, error) { + var out PolicyEvaluationServiceEvaluateResponse + pattern := "/policy-evaluations/evaluate" + path := binding.EncodeURL(pattern, in, false) + opts = append(opts, http.Operation(OperationPolicyEvaluationServiceEvaluate)) + opts = append(opts, http.PathTemplate(pattern)) + err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) + if err != nil { + return nil, err + } + return &out, err +} diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/policy_evaluation.ts b/app/controlplane/api/gen/frontend/controlplane/v1/policy_evaluation.ts new file mode 100644 index 000000000..47d91d8ad --- /dev/null +++ b/app/controlplane/api/gen/frontend/controlplane/v1/policy_evaluation.ts @@ -0,0 +1,416 @@ +/* eslint-disable */ +import { grpc } from "@improbable-eng/grpc-web"; +import { BrowserHeaders } from "browser-headers"; +import _m0 from "protobufjs/minimal"; +import { PolicyEvaluation } from "../../attestation/v1/crafting_state"; + +export const protobufPackage = "controlplane.v1"; + +export interface PolicyEvaluationServiceEvaluateRequest { + policyReference: string; + inputs: { [key: string]: string }; +} + +export interface PolicyEvaluationServiceEvaluateRequest_InputsEntry { + key: string; + value: string; +} + +export interface PolicyEvaluationServiceEvaluateResponse { + result?: PolicyEvaluation; +} + +function createBasePolicyEvaluationServiceEvaluateRequest(): PolicyEvaluationServiceEvaluateRequest { + return { policyReference: "", inputs: {} }; +} + +export const PolicyEvaluationServiceEvaluateRequest = { + encode(message: PolicyEvaluationServiceEvaluateRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.policyReference !== "") { + writer.uint32(10).string(message.policyReference); + } + Object.entries(message.inputs).forEach(([key, value]) => { + PolicyEvaluationServiceEvaluateRequest_InputsEntry.encode({ key: key as any, value }, writer.uint32(18).fork()) + .ldelim(); + }); + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluationServiceEvaluateRequest { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicyEvaluationServiceEvaluateRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.policyReference = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + const entry2 = PolicyEvaluationServiceEvaluateRequest_InputsEntry.decode(reader, reader.uint32()); + if (entry2.value !== undefined) { + message.inputs[entry2.key] = entry2.value; + } + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PolicyEvaluationServiceEvaluateRequest { + return { + policyReference: isSet(object.policyReference) ? String(object.policyReference) : "", + inputs: isObject(object.inputs) + ? Object.entries(object.inputs).reduce<{ [key: string]: string }>((acc, [key, value]) => { + acc[key] = String(value); + return acc; + }, {}) + : {}, + }; + }, + + toJSON(message: PolicyEvaluationServiceEvaluateRequest): unknown { + const obj: any = {}; + message.policyReference !== undefined && (obj.policyReference = message.policyReference); + obj.inputs = {}; + if (message.inputs) { + Object.entries(message.inputs).forEach(([k, v]) => { + obj.inputs[k] = v; + }); + } + return obj; + }, + + create, I>>( + base?: I, + ): PolicyEvaluationServiceEvaluateRequest { + return PolicyEvaluationServiceEvaluateRequest.fromPartial(base ?? {}); + }, + + fromPartial, I>>( + object: I, + ): PolicyEvaluationServiceEvaluateRequest { + const message = createBasePolicyEvaluationServiceEvaluateRequest(); + message.policyReference = object.policyReference ?? ""; + message.inputs = Object.entries(object.inputs ?? {}).reduce<{ [key: string]: string }>((acc, [key, value]) => { + if (value !== undefined) { + acc[key] = String(value); + } + return acc; + }, {}); + return message; + }, +}; + +function createBasePolicyEvaluationServiceEvaluateRequest_InputsEntry(): PolicyEvaluationServiceEvaluateRequest_InputsEntry { + return { key: "", value: "" }; +} + +export const PolicyEvaluationServiceEvaluateRequest_InputsEntry = { + encode( + message: PolicyEvaluationServiceEvaluateRequest_InputsEntry, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluationServiceEvaluateRequest_InputsEntry { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicyEvaluationServiceEvaluateRequest_InputsEntry(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.key = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.value = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PolicyEvaluationServiceEvaluateRequest_InputsEntry { + return { key: isSet(object.key) ? String(object.key) : "", value: isSet(object.value) ? String(object.value) : "" }; + }, + + toJSON(message: PolicyEvaluationServiceEvaluateRequest_InputsEntry): unknown { + const obj: any = {}; + message.key !== undefined && (obj.key = message.key); + message.value !== undefined && (obj.value = message.value); + return obj; + }, + + create, I>>( + base?: I, + ): PolicyEvaluationServiceEvaluateRequest_InputsEntry { + return PolicyEvaluationServiceEvaluateRequest_InputsEntry.fromPartial(base ?? {}); + }, + + fromPartial, I>>( + object: I, + ): PolicyEvaluationServiceEvaluateRequest_InputsEntry { + const message = createBasePolicyEvaluationServiceEvaluateRequest_InputsEntry(); + message.key = object.key ?? ""; + message.value = object.value ?? ""; + return message; + }, +}; + +function createBasePolicyEvaluationServiceEvaluateResponse(): PolicyEvaluationServiceEvaluateResponse { + return { result: undefined }; +} + +export const PolicyEvaluationServiceEvaluateResponse = { + encode(message: PolicyEvaluationServiceEvaluateResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.result !== undefined) { + PolicyEvaluation.encode(message.result, writer.uint32(10).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluationServiceEvaluateResponse { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicyEvaluationServiceEvaluateResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.result = PolicyEvaluation.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PolicyEvaluationServiceEvaluateResponse { + return { result: isSet(object.result) ? PolicyEvaluation.fromJSON(object.result) : undefined }; + }, + + toJSON(message: PolicyEvaluationServiceEvaluateResponse): unknown { + const obj: any = {}; + message.result !== undefined && (obj.result = message.result ? PolicyEvaluation.toJSON(message.result) : undefined); + return obj; + }, + + create, I>>( + base?: I, + ): PolicyEvaluationServiceEvaluateResponse { + return PolicyEvaluationServiceEvaluateResponse.fromPartial(base ?? {}); + }, + + fromPartial, I>>( + object: I, + ): PolicyEvaluationServiceEvaluateResponse { + const message = createBasePolicyEvaluationServiceEvaluateResponse(); + message.result = (object.result !== undefined && object.result !== null) + ? PolicyEvaluation.fromPartial(object.result) + : undefined; + return message; + }, +}; + +export interface PolicyEvaluationService { + Evaluate( + request: DeepPartial, + metadata?: grpc.Metadata, + ): Promise; +} + +export class PolicyEvaluationServiceClientImpl implements PolicyEvaluationService { + private readonly rpc: Rpc; + + constructor(rpc: Rpc) { + this.rpc = rpc; + this.Evaluate = this.Evaluate.bind(this); + } + + Evaluate( + request: DeepPartial, + metadata?: grpc.Metadata, + ): Promise { + return this.rpc.unary( + PolicyEvaluationServiceEvaluateDesc, + PolicyEvaluationServiceEvaluateRequest.fromPartial(request), + metadata, + ); + } +} + +export const PolicyEvaluationServiceDesc = { serviceName: "controlplane.v1.PolicyEvaluationService" }; + +export const PolicyEvaluationServiceEvaluateDesc: UnaryMethodDefinitionish = { + methodName: "Evaluate", + service: PolicyEvaluationServiceDesc, + requestStream: false, + responseStream: false, + requestType: { + serializeBinary() { + return PolicyEvaluationServiceEvaluateRequest.encode(this).finish(); + }, + } as any, + responseType: { + deserializeBinary(data: Uint8Array) { + const value = PolicyEvaluationServiceEvaluateResponse.decode(data); + return { + ...value, + toObject() { + return value; + }, + }; + }, + } as any, +}; + +interface UnaryMethodDefinitionishR extends grpc.UnaryMethodDefinition { + requestStream: any; + responseStream: any; +} + +type UnaryMethodDefinitionish = UnaryMethodDefinitionishR; + +interface Rpc { + unary( + methodDesc: T, + request: any, + metadata: grpc.Metadata | undefined, + ): Promise; +} + +export class GrpcWebImpl { + private host: string; + private options: { + transport?: grpc.TransportFactory; + + debug?: boolean; + metadata?: grpc.Metadata; + upStreamRetryCodes?: number[]; + }; + + constructor( + host: string, + options: { + transport?: grpc.TransportFactory; + + debug?: boolean; + metadata?: grpc.Metadata; + upStreamRetryCodes?: number[]; + }, + ) { + this.host = host; + this.options = options; + } + + unary( + methodDesc: T, + _request: any, + metadata: grpc.Metadata | undefined, + ): Promise { + const request = { ..._request, ...methodDesc.requestType }; + const maybeCombinedMetadata = metadata && this.options.metadata + ? new BrowserHeaders({ ...this.options?.metadata.headersMap, ...metadata?.headersMap }) + : metadata || this.options.metadata; + return new Promise((resolve, reject) => { + grpc.unary(methodDesc, { + request, + host: this.host, + metadata: maybeCombinedMetadata, + transport: this.options.transport, + debug: this.options.debug, + onEnd: function (response) { + if (response.status === grpc.Code.OK) { + resolve(response.message!.toObject()); + } else { + const err = new GrpcWebError(response.statusMessage, response.status, response.trailers); + reject(err); + } + }, + }); + }); + } +} + +declare var self: any | undefined; +declare var window: any | undefined; +declare var global: any | undefined; +var tsProtoGlobalThis: any = (() => { + if (typeof globalThis !== "undefined") { + return globalThis; + } + if (typeof self !== "undefined") { + return self; + } + if (typeof window !== "undefined") { + return window; + } + if (typeof global !== "undefined") { + return global; + } + throw "Unable to locate global object"; +})(); + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends Array ? Array> : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +function isObject(value: any): boolean { + return typeof value === "object" && value !== null; +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export class GrpcWebError extends tsProtoGlobalThis.Error { + constructor(message: string, public code: grpc.Code, public metadata: grpc.Metadata) { + super(message); + } +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json new file mode 100644 index 000000000..c126f5e18 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json @@ -0,0 +1,28 @@ +{ + "$id": "controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "patternProperties": { + "^(policy_reference)$": { + "minLength": 1, + "type": "string" + } + }, + "properties": { + "inputs": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "policyReference": { + "minLength": 1, + "type": "string" + } + }, + "title": "Policy Evaluation Service Evaluate Request", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json new file mode 100644 index 000000000..3997fe5e4 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json @@ -0,0 +1,28 @@ +{ + "$id": "controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "patternProperties": { + "^(policyReference)$": { + "minLength": 1, + "type": "string" + } + }, + "properties": { + "inputs": { + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "policy_reference": { + "minLength": 1, + "type": "string" + } + }, + "title": "Policy Evaluation Service Evaluate Request", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json new file mode 100644 index 000000000..8eb64eb4d --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json @@ -0,0 +1,12 @@ +{ + "$id": "controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "result": { + "$ref": "attestation.v1.PolicyEvaluation.jsonschema.json" + } + }, + "title": "Policy Evaluation Service Evaluate Response", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json new file mode 100644 index 000000000..0efa4d9b3 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json @@ -0,0 +1,12 @@ +{ + "$id": "controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "result": { + "$ref": "attestation.v1.PolicyEvaluation.schema.json" + } + }, + "title": "Policy Evaluation Service Evaluate Response", + "type": "object" +} diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index 436700e5e..702a0b630 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -238,6 +238,8 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l prometheusService := service.NewPrometheusService(organizationUseCase, prometheusUseCase, v5...) groupService := service.NewGroupService(groupUseCase, v5...) projectService := service.NewProjectService(v5...) + policyEvaluationUseCase := biz.NewPolicyEvaluationUseCase(organizationRepo, logger) + policyEvaluationService := service.NewPolicyEvaluationService(policyEvaluationUseCase, v5...) federatedAuthentication := bootstrap.FederatedAuthentication validator, err := newProtoValidator() if err != nil { @@ -278,6 +280,7 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l PrometheusSvc: prometheusService, GroupSvc: groupService, ProjectSvc: projectService, + PolicyEvaluationSvc: policyEvaluationService, Logger: logger, ServerConfig: confServer, AuthConfig: auth, diff --git a/app/controlplane/configs/config.devel.yaml b/app/controlplane/configs/config.devel.yaml index e7acbe0ec..1ad793322 100644 --- a/app/controlplane/configs/config.devel.yaml +++ b/app/controlplane/configs/config.devel.yaml @@ -97,11 +97,11 @@ auth: prometheus_integration: - org_name: "development" -# Policy providers configuration -# policy_providers: -# - name: chainloop -# default: true -# url: http://localhost:8002/v1 +# Policy providers configuration +policy_providers: + - name: chainloop + default: true + url: http://localhost:8002/v1 enable_profiler: true # federated_authentication: diff --git a/app/controlplane/internal/server/grpc.go b/app/controlplane/internal/server/grpc.go index 2a830b2dc..8d4a952a8 100644 --- a/app/controlplane/internal/server/grpc.go +++ b/app/controlplane/internal/server/grpc.go @@ -84,6 +84,7 @@ type Opts struct { PrometheusSvc *service.PrometheusService GroupSvc *service.GroupService ProjectSvc *service.ProjectService + PolicyEvaluationSvc *service.PolicyEvaluationService // Utils Logger log.Logger ServerConfig *conf.Server @@ -155,6 +156,7 @@ func NewGRPCServer(opts *Opts) (*grpc.Server, error) { v1.RegisterSigningServiceServer(srv, opts.SigningSvc) v1.RegisterGroupServiceServer(srv, opts.GroupSvc) v1.RegisterProjectServiceServer(srv, opts.ProjectSvc) + v1.RegisterPolicyEvaluationServiceServer(srv, opts.PolicyEvaluationSvc) // Register Prometheus metrics grpc_prometheus.Register(srv.Server) diff --git a/app/controlplane/internal/service/policyevaluation.go b/app/controlplane/internal/service/policyevaluation.go new file mode 100644 index 000000000..ada1e80b2 --- /dev/null +++ b/app/controlplane/internal/service/policyevaluation.go @@ -0,0 +1,58 @@ +// +// Copyright 2025 The Chainloop Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package service + +import ( + "context" + + pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" + "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" +) + +type PolicyEvaluationService struct { + pb.UnimplementedPolicyEvaluationServiceServer + *service + + uc *biz.PolicyEvaluationUseCase +} + +func NewPolicyEvaluationService(uc *biz.PolicyEvaluationUseCase, opts ...NewOpt) *PolicyEvaluationService { + return &PolicyEvaluationService{ + service: newService(opts...), + uc: uc, + } +} + +func (s *PolicyEvaluationService) Evaluate(ctx context.Context, req *pb.PolicyEvaluationServiceEvaluateRequest) (*pb.PolicyEvaluationServiceEvaluateResponse, error) { + // Verify current org is set (middleware handles this) + _, err := requireCurrentOrg(ctx) + if err != nil { + return nil, err + } + + // Call business layer to evaluate the policy + result, err := s.uc.Evaluate(ctx, &biz.PolicyEvaluationEvaluateOpts{ + PolicyReference: req.PolicyReference, + Inputs: req.Inputs, + }) + if err != nil { + return nil, handleUseCaseErr(err, s.log) + } + + return &pb.PolicyEvaluationServiceEvaluateResponse{ + Result: result, + }, nil +} diff --git a/app/controlplane/internal/service/service.go b/app/controlplane/internal/service/service.go index 06275775d..77d8714d1 100644 --- a/app/controlplane/internal/service/service.go +++ b/app/controlplane/internal/service/service.go @@ -60,6 +60,7 @@ var ProviderSet = wire.NewSet( NewPrometheusService, NewGroupService, NewProjectService, + NewPolicyEvaluationService, wire.Struct(new(NewWorkflowRunServiceOpts), "*"), wire.Struct(new(NewAttestationServiceOpts), "*"), wire.Struct(new(NewAttestationStateServiceOpt), "*"), diff --git a/app/controlplane/pkg/biz/biz.go b/app/controlplane/pkg/biz/biz.go index f8484b2ad..c3e61343b 100644 --- a/app/controlplane/pkg/biz/biz.go +++ b/app/controlplane/pkg/biz/biz.go @@ -58,6 +58,7 @@ var ProviderSet = wire.NewSet( NewGroupUseCase, NewCASBackendChecker, NewAuthzUseCase, + NewPolicyEvaluationUseCase, wire.Bind(new(PromObservable), new(*PrometheusUseCase)), wire.Struct(new(NewIntegrationUseCaseOpts), "*"), wire.Struct(new(NewUserUseCaseParams), "*"), diff --git a/app/controlplane/pkg/biz/policyevaluation.go b/app/controlplane/pkg/biz/policyevaluation.go new file mode 100644 index 000000000..147785b10 --- /dev/null +++ b/app/controlplane/pkg/biz/policyevaluation.go @@ -0,0 +1,117 @@ +// +// Copyright 2025 The Chainloop Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package biz + +import ( + "context" + "fmt" + + "github.com/chainloop-dev/chainloop/app/controlplane/internal/usercontext/entities" + "github.com/chainloop-dev/chainloop/pkg/policies" + "github.com/go-kratos/kratos/v2/log" + "github.com/google/uuid" + "github.com/rs/zerolog" + + schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" + crafterAPI "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" +) + +type PolicyEvaluationUseCase struct { + orgRepo OrganizationRepo + logger *log.Helper +} + +func NewPolicyEvaluationUseCase( + orgRepo OrganizationRepo, + logger log.Logger, +) *PolicyEvaluationUseCase { + return &PolicyEvaluationUseCase{ + orgRepo: orgRepo, + logger: log.NewHelper(logger), + } +} + +// Evaluate executes a generic policy evaluation without material context and returns the result +func (uc *PolicyEvaluationUseCase) Evaluate(ctx context.Context, opts *PolicyEvaluationEvaluateOpts) (*crafterAPI.PolicyEvaluation, error) { + // Get current organization + currentOrg := entities.CurrentOrg(ctx) + if currentOrg == nil { + return nil, NewErrNotFound("organization") + } + + // Load full organization details to get policies_allowed_hostnames + orgUUID, err := uuid.Parse(currentOrg.ID) + if err != nil { + return nil, fmt.Errorf("invalid organization ID: %w", err) + } + + org, err := uc.orgRepo.FindByID(ctx, orgUUID) + if err != nil { + return nil, err + } + + // Create policy attachment for evaluation + ref := opts.PolicyReference + scheme, _ := policies.RefParts(opts.PolicyReference) + if scheme == "" { + // If no scheme, assume it's a file path and add file:// prefix + ref = fmt.Sprintf("file://%s", opts.PolicyReference) + } + + attachment := &schemaapi.PolicyAttachment{ + Policy: &schemaapi.PolicyAttachment_Ref{Ref: ref}, + With: opts.Inputs, + } + + // Create policy verifier with organization's allowed hostnames + zlog := zerolog.Ctx(ctx) + if zlog == nil || zlog.GetLevel() == zerolog.Disabled { + l := zerolog.New(zerolog.NewConsoleWriter()) + zlog = &l + } + + verifierOpts := []policies.PolicyVerifierOption{ + policies.WithIncludeRawData(false), + } + if len(org.PoliciesAllowedHostnames) > 0 { + verifierOpts = append(verifierOpts, policies.WithAllowedHostnames(org.PoliciesAllowedHostnames...)) + } + + pol := &schemaapi.Policies{} + verifier := policies.NewPolicyVerifier(pol, nil, zlog, verifierOpts...) + + // Evaluate the policy + policyEv, err := verifier.EvaluateGeneric(ctx, attachment) + if err != nil { + return nil, fmt.Errorf("evaluating policy: %w", err) + } + + if policyEv == nil { + return nil, fmt.Errorf("no execution branch matched, or all of them were ignored") + } + + // Check if violations should block + if len(policyEv.Violations) > 0 && org.BlockOnPolicyViolation { + return policyEv, fmt.Errorf("policy evaluation failed with %d violation(s)", len(policyEv.Violations)) + } + + return policyEv, nil +} + +type PolicyEvaluationEvaluateOpts struct { + PolicyReference string + Inputs map[string]string +} diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index d82170c2b..f436c6241 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -159,6 +159,25 @@ func (pv *PolicyVerifier) VerifyMaterial(ctx context.Context, material *v12.Atte return result, nil } +// EvaluateGeneric evaluates a single policy attachment. +func (pv *PolicyVerifier) EvaluateGeneric(ctx context.Context, attachment *v1.PolicyAttachment) (*v12.PolicyEvaluation, error) { + // Use empty JSON as material input + input := []byte("{}") + + // Evaluate without material context + ev, err := pv.evaluatePolicyAttachment(ctx, attachment, input, + &evalOpts{ + kind: v1.CraftingSchema_Material_MATERIAL_TYPE_UNSPECIFIED, + name: "", + }, + ) + if err != nil { + return nil, NewPolicyError(err) + } + + return ev, nil +} + type evalOpts struct { name string kind v1.CraftingSchema_Material_MaterialType From 3b129c0e0c6f0e11fc5787864cf67e9829f1dd91 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 11 Dec 2025 13:48:22 +0100 Subject: [PATCH 2/7] add policy eval command Signed-off-by: Sylwester Piskozub --- app/cli/cmd/policy.go | 2 +- app/cli/cmd/policy_eval.go | 80 ++++++++ app/cli/documentation/cli-reference.mdx | 55 ++++++ app/cli/pkg/action/policy_eval.go | 179 ++++++++++++++++++ .../controlplane/v1/policy_evaluation.pb.go | 101 ++++------ .../controlplane/v1/policy_evaluation.proto | 33 +--- 6 files changed, 352 insertions(+), 98 deletions(-) create mode 100644 app/cli/cmd/policy_eval.go create mode 100644 app/cli/pkg/action/policy_eval.go diff --git a/app/cli/cmd/policy.go b/app/cli/cmd/policy.go index db34a4425..e7dcb308e 100644 --- a/app/cli/cmd/policy.go +++ b/app/cli/cmd/policy.go @@ -25,6 +25,6 @@ func newPolicyCmd() *cobra.Command { Short: "Craft chainloop policies", } - cmd.AddCommand(newPolicyDevelopCmd()) + cmd.AddCommand(newPolicyEvalCmd(), newPolicyDevelopCmd()) return cmd } diff --git a/app/cli/cmd/policy_eval.go b/app/cli/cmd/policy_eval.go new file mode 100644 index 000000000..62224e277 --- /dev/null +++ b/app/cli/cmd/policy_eval.go @@ -0,0 +1,80 @@ +// +// Copyright 2025 The Chainloop Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "fmt" + + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" + "github.com/chainloop-dev/chainloop/app/cli/pkg/action" + schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" + "github.com/spf13/cobra" +) + +func newPolicyEvalCmd() *cobra.Command { + var ( + materialPath string + kind string + annotations []string + policyPath string + inputs []string + ) + + cmd := &cobra.Command{ + Use: "eval", + Short: "Evaluate a policy", + Long: `Evaluate a policy. + +This command uses organization context to evaluate policies. + +For offline development and testing with debug capabilities, use 'chainloop policy develop eval' instead.`, + Example: ` + chainloop policy eval --policy policy.yaml --input digest=sha256:80058e45a56daa50ae2a130bd1bd13b1fb9aff13a55b2d98615fff6eb3b0fffb`, + Annotations: map[string]string{ + useAPIToken: trueString, + }, + RunE: func(cmd *cobra.Command, _ []string) error { + opts := &action.PolicyEvaluateOpts{ + MaterialPath: materialPath, + Kind: kind, + Annotations: parseKeyValue(annotations), + PolicyPath: policyPath, + Inputs: parseKeyValue(inputs), + } + + policyEval, err := action.NewPolicyEvaluate(opts, ActionOpts) + if err != nil { + return err + } + + result, err := policyEval.Run(cmd.Context()) + if err != nil { + return err + } + + return output.EncodeJSON(result) + }, + } + + cmd.Flags().StringVar(&materialPath, "material", "", "Path to material or attestation file") + cmd.Flags().StringVar(&kind, "kind", "", fmt.Sprintf("Kind of the material: %q", schemaapi.ListAvailableMaterialKind())) + cmd.Flags().StringSliceVar(&annotations, "annotation", []string{}, "Key-value pairs of material annotations (key=value)") + cmd.Flags().StringVarP(&policyPath, "policy", "p", "", "Policy reference (./my-policy.yaml, https://my-domain.com/my-policy.yaml)") + cobra.CheckErr(cmd.MarkFlagRequired("policy")) + cmd.Flags().StringArrayVar(&inputs, "input", []string{}, "Key-value pairs of policy inputs (key=value)") + + return cmd +} diff --git a/app/cli/documentation/cli-reference.mdx b/app/cli/documentation/cli-reference.mdx index 21c14c386..b2b5e4679 100755 --- a/app/cli/documentation/cli-reference.mdx +++ b/app/cli/documentation/cli-reference.mdx @@ -3017,6 +3017,61 @@ Options inherited from parent commands -y, --yes Skip confirmation ``` +### chainloop policy eval + +Evaluate policy using control plane + +Synopsis + +Evaluate a policy using the control plane. + +This command connects to your Chainloop control plane to evaluate policies +with your organization's security settings (allowed hostnames, etc.). + +For offline development and testing with debug capabilities, use 'chainloop policy develop eval' instead. + +``` +chainloop policy eval [flags] +``` + +Examples + +``` + +Evaluate a generic policy with inputs +chainloop policy eval --policy ./my-policy.yaml --input key1=value1,key2=value2 + +Evaluate a remote policy +chainloop policy eval --policy https://my-domain.com/policy.yaml --input env=prod +``` + +Options + +``` +--annotation strings Key-value pairs of material annotations (not yet supported, use 'policy develop eval' for material evaluation) +-h, --help help for eval +--input stringArray Key-value pairs of policy inputs (key=value) +--kind string Kind of the material (not yet supported, use 'policy develop eval' for material evaluation) +--material string Path to material or attestation file (not yet supported, use 'policy develop eval' for material evaluation) +-p, --policy string Policy reference (./my-policy.yaml, https://my-domain.com/my-policy.yaml) +``` + +Options inherited from parent commands + +``` +--artifact-cas string URL for the Artifacts Content Addressable Storage API ($CHAINLOOP_ARTIFACT_CAS_API) (default "api.cas.chainloop.dev:443") +--artifact-cas-ca string CUSTOM CA file for the Artifacts CAS API (optional) ($CHAINLOOP_ARTIFACT_CAS_API_CA) +-c, --config string Path to an existing config file (default is $HOME/.config/chainloop/config.toml) +--control-plane string URL for the Control Plane API ($CHAINLOOP_CONTROL_PLANE_API) (default "api.cp.chainloop.dev:443") +--control-plane-ca string CUSTOM CA file for the Control Plane API (optional) ($CHAINLOOP_CONTROL_PLANE_API_CA) +--debug Enable debug/verbose logging mode +-i, --insecure Skip TLS transport during connection to the control plane ($CHAINLOOP_API_INSECURE) +-n, --org string organization name +-o, --output string Output format, valid options are json and table (default "table") +-t, --token string API token. NOTE: Alternatively use the env variable CHAINLOOP_TOKEN +-y, --yes Skip confirmation +``` + ### chainloop policy help Help about any command diff --git a/app/cli/pkg/action/policy_eval.go b/app/cli/pkg/action/policy_eval.go new file mode 100644 index 000000000..54a5c6546 --- /dev/null +++ b/app/cli/pkg/action/policy_eval.go @@ -0,0 +1,179 @@ +// +// Copyright 2025 The Chainloop Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package action + +import ( + "context" + "fmt" + + pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" + schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" + attestationapi "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" + "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/materials" + "github.com/chainloop-dev/chainloop/pkg/casclient" + "github.com/chainloop-dev/chainloop/pkg/policies" +) + +type PolicyEvaluateOpts struct { + MaterialPath string + Kind string + Annotations map[string]string + PolicyPath string + Inputs map[string]string +} + +type PolicyEvaluate struct { + *ActionsOpts + opts *PolicyEvaluateOpts +} + +func NewPolicyEvaluate(opts *PolicyEvaluateOpts, actionOpts *ActionsOpts) (*PolicyEvaluate, error) { + if actionOpts.CPConnection == nil { + return nil, fmt.Errorf("control plane connection is required") + } + + return &PolicyEvaluate{ + ActionsOpts: actionOpts, + opts: opts, + }, nil +} + +func (action *PolicyEvaluate) Run(ctx context.Context) (*attestationapi.PolicyEvaluation, error) { + // 1. Get organization settings + contextClient := pb.NewContextServiceClient(action.CPConnection) + contextResp, err := contextClient.Current(ctx, &pb.ContextServiceCurrentRequest{}) + if err != nil { + return nil, fmt.Errorf("fetching organization settings: %w", err) + } + + if contextResp.Result == nil || contextResp.Result.CurrentMembership == nil || contextResp.Result.CurrentMembership.Org == nil { + return nil, fmt.Errorf("no organization context found") + } + + org := contextResp.Result.CurrentMembership.Org + allowedHostnames := org.PolicyAllowedHostnames + + // 2. Create policy attachment + ref := action.opts.PolicyPath + scheme, _ := policies.RefParts(action.opts.PolicyPath) + if scheme == "" { + // If no scheme, assume it's a file path and add file:// prefix + ref = fmt.Sprintf("file://%s", action.opts.PolicyPath) + } + + policyAttachment := &schemaapi.PolicyAttachment{ + Policy: &schemaapi.PolicyAttachment_Ref{Ref: ref}, + With: action.opts.Inputs, + } + + // 3. Create policies structure based on whether we have a material + var pol *schemaapi.Policies + if action.opts.MaterialPath != "" { + // Material-based evaluation + pol = &schemaapi.Policies{ + Materials: []*schemaapi.PolicyAttachment{policyAttachment}, + } + } else { + // Generic evaluation + pol = &schemaapi.Policies{} + } + + // 4. Create policy verifier with organization's allowed hostnames + verifierOpts := []policies.PolicyVerifierOption{ + policies.WithIncludeRawData(false), + policies.WithEnablePrint(false), + policies.WithGRPCConn(action.CPConnection), + } + if len(allowedHostnames) > 0 { + verifierOpts = append(verifierOpts, policies.WithAllowedHostnames(allowedHostnames...)) + } + + attClient := pb.NewAttestationServiceClient(action.CPConnection) + verifier := policies.NewPolicyVerifier(pol, attClient, &action.Logger, verifierOpts...) + + // 5. Evaluate: either material-based or generic + if action.opts.MaterialPath != "" { + // Material-based evaluation + material, err := action.craftMaterial(ctx) + if err != nil { + return nil, fmt.Errorf("crafting material: %w", err) + } + material.Annotations = action.opts.Annotations + + policyEvs, err := verifier.VerifyMaterial(ctx, material, action.opts.MaterialPath) + if err != nil { + return nil, fmt.Errorf("evaluating policy against material: %w", err) + } + + if len(policyEvs) == 0 || policyEvs[0] == nil { + return nil, fmt.Errorf("no execution branch matched, or all of them were ignored, for kind %s", material.MaterialType.String()) + } + + return policyEvs[0], nil + } + + // Generic evaluation + policyEv, err := verifier.EvaluateGeneric(ctx, policyAttachment) + if err != nil { + return nil, fmt.Errorf("evaluating policy: %w", err) + } + + if policyEv == nil { + return nil, fmt.Errorf("no execution branch matched, or all of them were ignored") + } + + return policyEv, nil +} + +func (action *PolicyEvaluate) craftMaterial(ctx context.Context) (*attestationapi.Attestation_Material, error) { + backend := &casclient.CASBackend{ + Name: "backend", + MaxSize: 0, + Uploader: nil, // Skip uploads + } + + // Explicit kind + if action.opts.Kind != "" { + kind, ok := schemaapi.CraftingSchema_Material_MaterialType_value[action.opts.Kind] + if !ok { + return nil, fmt.Errorf("invalid material kind: %s", action.opts.Kind) + } + return action.craft(ctx, schemaapi.CraftingSchema_Material_MaterialType(kind), "material", backend) + } + + // Auto-detect kind + for _, kind := range schemaapi.CraftingMaterialInValidationOrder { + m, err := action.craft(ctx, kind, "auto-detected-material", backend) + if err == nil { + return m, nil + } + } + + return nil, fmt.Errorf("could not auto-detect material kind for: %s", action.opts.MaterialPath) +} + +func (action *PolicyEvaluate) craft(ctx context.Context, kind schemaapi.CraftingSchema_Material_MaterialType, name string, backend *casclient.CASBackend) (*attestationapi.Attestation_Material, error) { + materialSchema := &schemaapi.CraftingSchema_Material{ + Type: kind, + Name: name, + } + + m, err := materials.Craft(ctx, materialSchema, action.opts.MaterialPath, backend, nil, &action.Logger) + if err != nil { + return nil, fmt.Errorf("failed to craft material (kind=%s): %w", kind.String(), err) + } + return m, nil +} diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go b/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go index c64c356eb..0215016e2 100644 --- a/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go +++ b/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go @@ -9,8 +9,6 @@ package v1 import ( _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" v1 "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" - _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" - _ "google.golang.org/genproto/googleapis/api/annotations" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -136,71 +134,44 @@ var file_controlplane_v1_policy_evaluation_proto_rawDesc = []byte{ 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, - 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc9, 0x02, 0x0a, 0x26, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x10, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x06, 0x69, 0x6e, 0x70, - 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf4, 0x01, 0x0a, + 0x26, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x10, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x06, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x49, 0x6e, 0x70, 0x75, + 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x63, 0x0a, 0x27, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, + 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, + 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, + 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, + 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x32, 0x98, 0x01, 0x0a, 0x17, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x7d, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, + 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x3a, 0x53, 0x92, 0x41, 0x50, 0x0a, 0x4e, 0x2a, 0x26, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x32, 0x24, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x65, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0xc1, 0x01, 0x0a, 0x27, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x3a, 0x5c, 0x92, 0x41, - 0x59, 0x0a, 0x57, 0x2a, 0x27, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, - 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x2c, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x69, 0x6e, - 0x67, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x32, 0xcc, 0x02, 0x0a, 0x17, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xef, 0x01, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, - 0x61, 0x74, 0x65, 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, - 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, - 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x92, 0x41, 0x46, 0x12, 0x17, 0x45, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x1a, 0x19, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x73, 0x20, - 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x3a, - 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, - 0x6e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2d, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, - 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x1a, 0x3f, 0x92, 0x41, 0x3c, 0x0a, 0x17, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x21, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, - 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, - 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, - 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation.proto b/app/controlplane/api/controlplane/v1/policy_evaluation.proto index 22d6a7a17..5ab2ac028 100644 --- a/app/controlplane/api/controlplane/v1/policy_evaluation.proto +++ b/app/controlplane/api/controlplane/v1/policy_evaluation.proto @@ -4,49 +4,18 @@ package controlplane.v1; import "attestation/v1/crafting_state.proto"; import "buf/validate/validate.proto"; -import "google/api/annotations.proto"; -import "protoc-gen-openapiv2/options/annotations.proto"; option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1;v1"; service PolicyEvaluationService { - rpc Evaluate(PolicyEvaluationServiceEvaluateRequest) returns (PolicyEvaluationServiceEvaluateResponse) { - option (google.api.http) = { - post: "/policy-evaluations/evaluate" - body: "*" - }; - option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { - summary: "Evaluate generic policy" - description: "Evaluates generic policy." - produces: ["application/json"] - }; - } - - option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_tag) = { - name: "PolicyEvaluationService" - description: "Generic policy evaluation service" - }; + rpc Evaluate(PolicyEvaluationServiceEvaluateRequest) returns (PolicyEvaluationServiceEvaluateResponse); } message PolicyEvaluationServiceEvaluateRequest { string policy_reference = 1 [(buf.validate.field).string.min_len = 1]; map inputs = 2; - - option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { - json_schema: { - title: "PolicyEvaluationServiceEvaluateRequest" - description: "Request to evaluate a generic policy" - } - }; } message PolicyEvaluationServiceEvaluateResponse { attestation.v1.PolicyEvaluation result = 1; - - option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { - json_schema: { - title: "PolicyEvaluationServiceEvaluateResponse" - description: "Response containing policy evaluation result" - } - }; } From 3b85c577f432b5bd2ddc02499f3ff816d2dc85c5 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 11 Dec 2025 13:59:34 +0100 Subject: [PATCH 3/7] missing cli ref Signed-off-by: Sylwester Piskozub --- app/cli/documentation/cli-reference.mdx | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/app/cli/documentation/cli-reference.mdx b/app/cli/documentation/cli-reference.mdx index b2b5e4679..c3f87d30f 100755 --- a/app/cli/documentation/cli-reference.mdx +++ b/app/cli/documentation/cli-reference.mdx @@ -3019,14 +3019,13 @@ Options inherited from parent commands ### chainloop policy eval -Evaluate policy using control plane +Evaluate a policy Synopsis -Evaluate a policy using the control plane. +Evaluate a policy. -This command connects to your Chainloop control plane to evaluate policies -with your organization's security settings (allowed hostnames, etc.). +This command uses organization context to evaluate policies. For offline development and testing with debug capabilities, use 'chainloop policy develop eval' instead. @@ -3038,21 +3037,17 @@ Examples ``` -Evaluate a generic policy with inputs -chainloop policy eval --policy ./my-policy.yaml --input key1=value1,key2=value2 - -Evaluate a remote policy -chainloop policy eval --policy https://my-domain.com/policy.yaml --input env=prod +chainloop policy eval --policy policy.yaml --input digest=sha256:80058e45a56daa50ae2a130bd1bd13b1fb9aff13a55b2d98615fff6eb3b0fffb ``` Options ``` ---annotation strings Key-value pairs of material annotations (not yet supported, use 'policy develop eval' for material evaluation) +--annotation strings Key-value pairs of material annotations (key=value) -h, --help help for eval --input stringArray Key-value pairs of policy inputs (key=value) ---kind string Kind of the material (not yet supported, use 'policy develop eval' for material evaluation) ---material string Path to material or attestation file (not yet supported, use 'policy develop eval' for material evaluation) +--kind string Kind of the material: ["ARTIFACT" "ATTESTATION" "BLACKDUCK_SCA_JSON" "CHAINLOOP_RUNNER_CONTEXT" "CONTAINER_IMAGE" "CSAF_INFORMATIONAL_ADVISORY" "CSAF_SECURITY_ADVISORY" "CSAF_SECURITY_INCIDENT_RESPONSE" "CSAF_VEX" "EVIDENCE" "GHAS_CODE_SCAN" "GHAS_DEPENDENCY_SCAN" "GHAS_SECRET_SCAN" "GITLAB_SECURITY_REPORT" "HELM_CHART" "JACOCO_XML" "JUNIT_XML" "OPENVEX" "SARIF" "SBOM_CYCLONEDX_JSON" "SBOM_SPDX_JSON" "SLSA_PROVENANCE" "STRING" "TWISTCLI_SCAN_JSON" "ZAP_DAST_ZIP"] +--material string Path to material or attestation file -p, --policy string Policy reference (./my-policy.yaml, https://my-domain.com/my-policy.yaml) ``` From 4c1b31319b2936bd60f5d900fef1ed46edeeb4a2 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Tue, 16 Dec 2025 12:28:28 +0100 Subject: [PATCH 4/7] fix accidental config push Signed-off-by: Sylwester Piskozub --- app/controlplane/configs/config.devel.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/controlplane/configs/config.devel.yaml b/app/controlplane/configs/config.devel.yaml index 1ad793322..e7acbe0ec 100644 --- a/app/controlplane/configs/config.devel.yaml +++ b/app/controlplane/configs/config.devel.yaml @@ -97,11 +97,11 @@ auth: prometheus_integration: - org_name: "development" -# Policy providers configuration -policy_providers: - - name: chainloop - default: true - url: http://localhost:8002/v1 +# Policy providers configuration +# policy_providers: +# - name: chainloop +# default: true +# url: http://localhost:8002/v1 enable_profiler: true # federated_authentication: From 8659bef086184e03aa436aff5acb8258c9739e68 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Tue, 16 Dec 2025 13:00:07 +0100 Subject: [PATCH 5/7] clean up and refactor Signed-off-by: Sylwester Piskozub --- app/cli/internal/policydevel/eval.go | 6 +- app/cli/pkg/action/policy_eval.go | 45 +- .../controlplane/v1/policy_evaluation.pb.go | 257 ----------- .../controlplane/v1/policy_evaluation.proto | 21 - .../v1/policy_evaluation_grpc.pb.go | 110 ----- .../v1/policy_evaluation_http.pb.go | 78 ---- .../controlplane/v1/policy_evaluation.ts | 416 ------------------ ...tionServiceEvaluateRequest.jsonschema.json | 28 -- ...aluationServiceEvaluateRequest.schema.json | 28 -- ...ionServiceEvaluateResponse.jsonschema.json | 12 - ...luationServiceEvaluateResponse.schema.json | 12 - app/controlplane/cmd/wire_gen.go | 3 - app/controlplane/internal/server/grpc.go | 2 - .../internal/service/policyevaluation.go | 58 --- app/controlplane/internal/service/service.go | 1 - app/controlplane/pkg/biz/biz.go | 1 - app/controlplane/pkg/biz/policyevaluation.go | 117 ----- 17 files changed, 6 insertions(+), 1189 deletions(-) delete mode 100644 app/controlplane/api/controlplane/v1/policy_evaluation.pb.go delete mode 100644 app/controlplane/api/controlplane/v1/policy_evaluation.proto delete mode 100644 app/controlplane/api/controlplane/v1/policy_evaluation_grpc.pb.go delete mode 100644 app/controlplane/api/controlplane/v1/policy_evaluation_http.pb.go delete mode 100644 app/controlplane/api/gen/frontend/controlplane/v1/policy_evaluation.ts delete mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json delete mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json delete mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json delete mode 100644 app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json delete mode 100644 app/controlplane/internal/service/policyevaluation.go delete mode 100644 app/controlplane/pkg/biz/policyevaluation.go diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index 8f1ab3100..b08849977 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -70,7 +70,7 @@ func Evaluate(opts *EvalOptions, logger zerolog.Logger) (*EvalSummary, error) { } // 2. Craft material with annotations - material, err := craftMaterial(opts.MaterialPath, opts.MaterialKind, &logger) + material, err := CraftMaterial(opts.MaterialPath, opts.MaterialKind, &logger) if err != nil { return nil, err } @@ -166,7 +166,9 @@ func verifyMaterial(pol *v1.Policies, material *v12.Attestation_Material, materi return summary, nil } -func craftMaterial(materialPath, materialKind string, logger *zerolog.Logger) (*v12.Attestation_Material, error) { +// CraftMaterial creates an attestation material from a file path, with optional explicit kind or auto-detection. +// This is a shared utility function used by both policy eval and policy devel eval commands. +func CraftMaterial(materialPath, materialKind string, logger *zerolog.Logger) (*v12.Attestation_Material, error) { backend := &casclient.CASBackend{ Name: "backend", MaxSize: 0, diff --git a/app/cli/pkg/action/policy_eval.go b/app/cli/pkg/action/policy_eval.go index 54a5c6546..331a102e9 100644 --- a/app/cli/pkg/action/policy_eval.go +++ b/app/cli/pkg/action/policy_eval.go @@ -19,11 +19,10 @@ import ( "context" "fmt" + "github.com/chainloop-dev/chainloop/app/cli/internal/policydevel" pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" attestationapi "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" - "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/materials" - "github.com/chainloop-dev/chainloop/pkg/casclient" "github.com/chainloop-dev/chainloop/pkg/policies" ) @@ -107,7 +106,7 @@ func (action *PolicyEvaluate) Run(ctx context.Context) (*attestationapi.PolicyEv // 5. Evaluate: either material-based or generic if action.opts.MaterialPath != "" { // Material-based evaluation - material, err := action.craftMaterial(ctx) + material, err := policydevel.CraftMaterial(action.opts.MaterialPath, action.opts.Kind, &action.Logger) if err != nil { return nil, fmt.Errorf("crafting material: %w", err) } @@ -137,43 +136,3 @@ func (action *PolicyEvaluate) Run(ctx context.Context) (*attestationapi.PolicyEv return policyEv, nil } - -func (action *PolicyEvaluate) craftMaterial(ctx context.Context) (*attestationapi.Attestation_Material, error) { - backend := &casclient.CASBackend{ - Name: "backend", - MaxSize: 0, - Uploader: nil, // Skip uploads - } - - // Explicit kind - if action.opts.Kind != "" { - kind, ok := schemaapi.CraftingSchema_Material_MaterialType_value[action.opts.Kind] - if !ok { - return nil, fmt.Errorf("invalid material kind: %s", action.opts.Kind) - } - return action.craft(ctx, schemaapi.CraftingSchema_Material_MaterialType(kind), "material", backend) - } - - // Auto-detect kind - for _, kind := range schemaapi.CraftingMaterialInValidationOrder { - m, err := action.craft(ctx, kind, "auto-detected-material", backend) - if err == nil { - return m, nil - } - } - - return nil, fmt.Errorf("could not auto-detect material kind for: %s", action.opts.MaterialPath) -} - -func (action *PolicyEvaluate) craft(ctx context.Context, kind schemaapi.CraftingSchema_Material_MaterialType, name string, backend *casclient.CASBackend) (*attestationapi.Attestation_Material, error) { - materialSchema := &schemaapi.CraftingSchema_Material{ - Type: kind, - Name: name, - } - - m, err := materials.Craft(ctx, materialSchema, action.opts.MaterialPath, backend, nil, &action.Logger) - if err != nil { - return nil, fmt.Errorf("failed to craft material (kind=%s): %w", kind.String(), err) - } - return m, nil -} diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go b/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go deleted file mode 100644 index 0215016e2..000000000 --- a/app/controlplane/api/controlplane/v1/policy_evaluation.pb.go +++ /dev/null @@ -1,257 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: controlplane/v1/policy_evaluation.proto - -package v1 - -import ( - _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" - v1 "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type PolicyEvaluationServiceEvaluateRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PolicyReference string `protobuf:"bytes,1,opt,name=policy_reference,json=policyReference,proto3" json:"policy_reference,omitempty"` - Inputs map[string]string `protobuf:"bytes,2,rep,name=inputs,proto3" json:"inputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *PolicyEvaluationServiceEvaluateRequest) Reset() { - *x = PolicyEvaluationServiceEvaluateRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_policy_evaluation_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PolicyEvaluationServiceEvaluateRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PolicyEvaluationServiceEvaluateRequest) ProtoMessage() {} - -func (x *PolicyEvaluationServiceEvaluateRequest) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_policy_evaluation_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PolicyEvaluationServiceEvaluateRequest.ProtoReflect.Descriptor instead. -func (*PolicyEvaluationServiceEvaluateRequest) Descriptor() ([]byte, []int) { - return file_controlplane_v1_policy_evaluation_proto_rawDescGZIP(), []int{0} -} - -func (x *PolicyEvaluationServiceEvaluateRequest) GetPolicyReference() string { - if x != nil { - return x.PolicyReference - } - return "" -} - -func (x *PolicyEvaluationServiceEvaluateRequest) GetInputs() map[string]string { - if x != nil { - return x.Inputs - } - return nil -} - -type PolicyEvaluationServiceEvaluateResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Result *v1.PolicyEvaluation `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` -} - -func (x *PolicyEvaluationServiceEvaluateResponse) Reset() { - *x = PolicyEvaluationServiceEvaluateResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_controlplane_v1_policy_evaluation_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PolicyEvaluationServiceEvaluateResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PolicyEvaluationServiceEvaluateResponse) ProtoMessage() {} - -func (x *PolicyEvaluationServiceEvaluateResponse) ProtoReflect() protoreflect.Message { - mi := &file_controlplane_v1_policy_evaluation_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PolicyEvaluationServiceEvaluateResponse.ProtoReflect.Descriptor instead. -func (*PolicyEvaluationServiceEvaluateResponse) Descriptor() ([]byte, []int) { - return file_controlplane_v1_policy_evaluation_proto_rawDescGZIP(), []int{1} -} - -func (x *PolicyEvaluationServiceEvaluateResponse) GetResult() *v1.PolicyEvaluation { - if x != nil { - return x.Result - } - return nil -} - -var File_controlplane_v1_policy_evaluation_proto protoreflect.FileDescriptor - -var file_controlplane_v1_policy_evaluation_proto_rawDesc = []byte{ - 0x0a, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, - 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x23, 0x61, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x61, 0x66, 0x74, - 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf4, 0x01, 0x0a, - 0x26, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x10, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0f, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x06, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x49, 0x6e, 0x70, 0x75, - 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0x63, 0x0a, 0x27, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, - 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, - 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, - 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, - 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x32, 0x98, 0x01, 0x0a, 0x17, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x7d, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, - 0x12, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x76, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_controlplane_v1_policy_evaluation_proto_rawDescOnce sync.Once - file_controlplane_v1_policy_evaluation_proto_rawDescData = file_controlplane_v1_policy_evaluation_proto_rawDesc -) - -func file_controlplane_v1_policy_evaluation_proto_rawDescGZIP() []byte { - file_controlplane_v1_policy_evaluation_proto_rawDescOnce.Do(func() { - file_controlplane_v1_policy_evaluation_proto_rawDescData = protoimpl.X.CompressGZIP(file_controlplane_v1_policy_evaluation_proto_rawDescData) - }) - return file_controlplane_v1_policy_evaluation_proto_rawDescData -} - -var file_controlplane_v1_policy_evaluation_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_controlplane_v1_policy_evaluation_proto_goTypes = []interface{}{ - (*PolicyEvaluationServiceEvaluateRequest)(nil), // 0: controlplane.v1.PolicyEvaluationServiceEvaluateRequest - (*PolicyEvaluationServiceEvaluateResponse)(nil), // 1: controlplane.v1.PolicyEvaluationServiceEvaluateResponse - nil, // 2: controlplane.v1.PolicyEvaluationServiceEvaluateRequest.InputsEntry - (*v1.PolicyEvaluation)(nil), // 3: attestation.v1.PolicyEvaluation -} -var file_controlplane_v1_policy_evaluation_proto_depIdxs = []int32{ - 2, // 0: controlplane.v1.PolicyEvaluationServiceEvaluateRequest.inputs:type_name -> controlplane.v1.PolicyEvaluationServiceEvaluateRequest.InputsEntry - 3, // 1: controlplane.v1.PolicyEvaluationServiceEvaluateResponse.result:type_name -> attestation.v1.PolicyEvaluation - 0, // 2: controlplane.v1.PolicyEvaluationService.Evaluate:input_type -> controlplane.v1.PolicyEvaluationServiceEvaluateRequest - 1, // 3: controlplane.v1.PolicyEvaluationService.Evaluate:output_type -> controlplane.v1.PolicyEvaluationServiceEvaluateResponse - 3, // [3:4] is the sub-list for method output_type - 2, // [2:3] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_controlplane_v1_policy_evaluation_proto_init() } -func file_controlplane_v1_policy_evaluation_proto_init() { - if File_controlplane_v1_policy_evaluation_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_controlplane_v1_policy_evaluation_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicyEvaluationServiceEvaluateRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_controlplane_v1_policy_evaluation_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicyEvaluationServiceEvaluateResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_controlplane_v1_policy_evaluation_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_controlplane_v1_policy_evaluation_proto_goTypes, - DependencyIndexes: file_controlplane_v1_policy_evaluation_proto_depIdxs, - MessageInfos: file_controlplane_v1_policy_evaluation_proto_msgTypes, - }.Build() - File_controlplane_v1_policy_evaluation_proto = out.File - file_controlplane_v1_policy_evaluation_proto_rawDesc = nil - file_controlplane_v1_policy_evaluation_proto_goTypes = nil - file_controlplane_v1_policy_evaluation_proto_depIdxs = nil -} diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation.proto b/app/controlplane/api/controlplane/v1/policy_evaluation.proto deleted file mode 100644 index 5ab2ac028..000000000 --- a/app/controlplane/api/controlplane/v1/policy_evaluation.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; - -package controlplane.v1; - -import "attestation/v1/crafting_state.proto"; -import "buf/validate/validate.proto"; - -option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1;v1"; - -service PolicyEvaluationService { - rpc Evaluate(PolicyEvaluationServiceEvaluateRequest) returns (PolicyEvaluationServiceEvaluateResponse); -} - -message PolicyEvaluationServiceEvaluateRequest { - string policy_reference = 1 [(buf.validate.field).string.min_len = 1]; - map inputs = 2; -} - -message PolicyEvaluationServiceEvaluateResponse { - attestation.v1.PolicyEvaluation result = 1; -} diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation_grpc.pb.go b/app/controlplane/api/controlplane/v1/policy_evaluation_grpc.pb.go deleted file mode 100644 index 06cd0beb8..000000000 --- a/app/controlplane/api/controlplane/v1/policy_evaluation_grpc.pb.go +++ /dev/null @@ -1,110 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc (unknown) -// source: controlplane/v1/policy_evaluation.proto - -package v1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -const ( - PolicyEvaluationService_Evaluate_FullMethodName = "/controlplane.v1.PolicyEvaluationService/Evaluate" -) - -// PolicyEvaluationServiceClient is the client API for PolicyEvaluationService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type PolicyEvaluationServiceClient interface { - Evaluate(ctx context.Context, in *PolicyEvaluationServiceEvaluateRequest, opts ...grpc.CallOption) (*PolicyEvaluationServiceEvaluateResponse, error) -} - -type policyEvaluationServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewPolicyEvaluationServiceClient(cc grpc.ClientConnInterface) PolicyEvaluationServiceClient { - return &policyEvaluationServiceClient{cc} -} - -func (c *policyEvaluationServiceClient) Evaluate(ctx context.Context, in *PolicyEvaluationServiceEvaluateRequest, opts ...grpc.CallOption) (*PolicyEvaluationServiceEvaluateResponse, error) { - out := new(PolicyEvaluationServiceEvaluateResponse) - err := c.cc.Invoke(ctx, PolicyEvaluationService_Evaluate_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// PolicyEvaluationServiceServer is the server API for PolicyEvaluationService service. -// All implementations must embed UnimplementedPolicyEvaluationServiceServer -// for forward compatibility -type PolicyEvaluationServiceServer interface { - Evaluate(context.Context, *PolicyEvaluationServiceEvaluateRequest) (*PolicyEvaluationServiceEvaluateResponse, error) - mustEmbedUnimplementedPolicyEvaluationServiceServer() -} - -// UnimplementedPolicyEvaluationServiceServer must be embedded to have forward compatible implementations. -type UnimplementedPolicyEvaluationServiceServer struct { -} - -func (UnimplementedPolicyEvaluationServiceServer) Evaluate(context.Context, *PolicyEvaluationServiceEvaluateRequest) (*PolicyEvaluationServiceEvaluateResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Evaluate not implemented") -} -func (UnimplementedPolicyEvaluationServiceServer) mustEmbedUnimplementedPolicyEvaluationServiceServer() { -} - -// UnsafePolicyEvaluationServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to PolicyEvaluationServiceServer will -// result in compilation errors. -type UnsafePolicyEvaluationServiceServer interface { - mustEmbedUnimplementedPolicyEvaluationServiceServer() -} - -func RegisterPolicyEvaluationServiceServer(s grpc.ServiceRegistrar, srv PolicyEvaluationServiceServer) { - s.RegisterService(&PolicyEvaluationService_ServiceDesc, srv) -} - -func _PolicyEvaluationService_Evaluate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PolicyEvaluationServiceEvaluateRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(PolicyEvaluationServiceServer).Evaluate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: PolicyEvaluationService_Evaluate_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(PolicyEvaluationServiceServer).Evaluate(ctx, req.(*PolicyEvaluationServiceEvaluateRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// PolicyEvaluationService_ServiceDesc is the grpc.ServiceDesc for PolicyEvaluationService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var PolicyEvaluationService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "controlplane.v1.PolicyEvaluationService", - HandlerType: (*PolicyEvaluationServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Evaluate", - Handler: _PolicyEvaluationService_Evaluate_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "controlplane/v1/policy_evaluation.proto", -} diff --git a/app/controlplane/api/controlplane/v1/policy_evaluation_http.pb.go b/app/controlplane/api/controlplane/v1/policy_evaluation_http.pb.go deleted file mode 100644 index 5c8b7e334..000000000 --- a/app/controlplane/api/controlplane/v1/policy_evaluation_http.pb.go +++ /dev/null @@ -1,78 +0,0 @@ -// Code generated by protoc-gen-go-http. DO NOT EDIT. -// versions: -// - protoc-gen-go-http v2.7.1 -// - protoc (unknown) -// source: controlplane/v1/policy_evaluation.proto - -package v1 - -import ( - context "context" - http "github.com/go-kratos/kratos/v2/transport/http" - binding "github.com/go-kratos/kratos/v2/transport/http/binding" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the kratos package it is being compiled against. -var _ = new(context.Context) -var _ = binding.EncodeURL - -const _ = http.SupportPackageIsVersion1 - -const OperationPolicyEvaluationServiceEvaluate = "/controlplane.v1.PolicyEvaluationService/Evaluate" - -type PolicyEvaluationServiceHTTPServer interface { - Evaluate(context.Context, *PolicyEvaluationServiceEvaluateRequest) (*PolicyEvaluationServiceEvaluateResponse, error) -} - -func RegisterPolicyEvaluationServiceHTTPServer(s *http.Server, srv PolicyEvaluationServiceHTTPServer) { - r := s.Route("/") - r.POST("/policy-evaluations/evaluate", _PolicyEvaluationService_Evaluate0_HTTP_Handler(srv)) -} - -func _PolicyEvaluationService_Evaluate0_HTTP_Handler(srv PolicyEvaluationServiceHTTPServer) func(ctx http.Context) error { - return func(ctx http.Context) error { - var in PolicyEvaluationServiceEvaluateRequest - if err := ctx.Bind(&in); err != nil { - return err - } - if err := ctx.BindQuery(&in); err != nil { - return err - } - http.SetOperation(ctx, OperationPolicyEvaluationServiceEvaluate) - h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.Evaluate(ctx, req.(*PolicyEvaluationServiceEvaluateRequest)) - }) - out, err := h(ctx, &in) - if err != nil { - return err - } - reply := out.(*PolicyEvaluationServiceEvaluateResponse) - return ctx.Result(200, reply) - } -} - -type PolicyEvaluationServiceHTTPClient interface { - Evaluate(ctx context.Context, req *PolicyEvaluationServiceEvaluateRequest, opts ...http.CallOption) (rsp *PolicyEvaluationServiceEvaluateResponse, err error) -} - -type PolicyEvaluationServiceHTTPClientImpl struct { - cc *http.Client -} - -func NewPolicyEvaluationServiceHTTPClient(client *http.Client) PolicyEvaluationServiceHTTPClient { - return &PolicyEvaluationServiceHTTPClientImpl{client} -} - -func (c *PolicyEvaluationServiceHTTPClientImpl) Evaluate(ctx context.Context, in *PolicyEvaluationServiceEvaluateRequest, opts ...http.CallOption) (*PolicyEvaluationServiceEvaluateResponse, error) { - var out PolicyEvaluationServiceEvaluateResponse - pattern := "/policy-evaluations/evaluate" - path := binding.EncodeURL(pattern, in, false) - opts = append(opts, http.Operation(OperationPolicyEvaluationServiceEvaluate)) - opts = append(opts, http.PathTemplate(pattern)) - err := c.cc.Invoke(ctx, "POST", path, in, &out, opts...) - if err != nil { - return nil, err - } - return &out, err -} diff --git a/app/controlplane/api/gen/frontend/controlplane/v1/policy_evaluation.ts b/app/controlplane/api/gen/frontend/controlplane/v1/policy_evaluation.ts deleted file mode 100644 index 47d91d8ad..000000000 --- a/app/controlplane/api/gen/frontend/controlplane/v1/policy_evaluation.ts +++ /dev/null @@ -1,416 +0,0 @@ -/* eslint-disable */ -import { grpc } from "@improbable-eng/grpc-web"; -import { BrowserHeaders } from "browser-headers"; -import _m0 from "protobufjs/minimal"; -import { PolicyEvaluation } from "../../attestation/v1/crafting_state"; - -export const protobufPackage = "controlplane.v1"; - -export interface PolicyEvaluationServiceEvaluateRequest { - policyReference: string; - inputs: { [key: string]: string }; -} - -export interface PolicyEvaluationServiceEvaluateRequest_InputsEntry { - key: string; - value: string; -} - -export interface PolicyEvaluationServiceEvaluateResponse { - result?: PolicyEvaluation; -} - -function createBasePolicyEvaluationServiceEvaluateRequest(): PolicyEvaluationServiceEvaluateRequest { - return { policyReference: "", inputs: {} }; -} - -export const PolicyEvaluationServiceEvaluateRequest = { - encode(message: PolicyEvaluationServiceEvaluateRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.policyReference !== "") { - writer.uint32(10).string(message.policyReference); - } - Object.entries(message.inputs).forEach(([key, value]) => { - PolicyEvaluationServiceEvaluateRequest_InputsEntry.encode({ key: key as any, value }, writer.uint32(18).fork()) - .ldelim(); - }); - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluationServiceEvaluateRequest { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBasePolicyEvaluationServiceEvaluateRequest(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.policyReference = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - const entry2 = PolicyEvaluationServiceEvaluateRequest_InputsEntry.decode(reader, reader.uint32()); - if (entry2.value !== undefined) { - message.inputs[entry2.key] = entry2.value; - } - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): PolicyEvaluationServiceEvaluateRequest { - return { - policyReference: isSet(object.policyReference) ? String(object.policyReference) : "", - inputs: isObject(object.inputs) - ? Object.entries(object.inputs).reduce<{ [key: string]: string }>((acc, [key, value]) => { - acc[key] = String(value); - return acc; - }, {}) - : {}, - }; - }, - - toJSON(message: PolicyEvaluationServiceEvaluateRequest): unknown { - const obj: any = {}; - message.policyReference !== undefined && (obj.policyReference = message.policyReference); - obj.inputs = {}; - if (message.inputs) { - Object.entries(message.inputs).forEach(([k, v]) => { - obj.inputs[k] = v; - }); - } - return obj; - }, - - create, I>>( - base?: I, - ): PolicyEvaluationServiceEvaluateRequest { - return PolicyEvaluationServiceEvaluateRequest.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): PolicyEvaluationServiceEvaluateRequest { - const message = createBasePolicyEvaluationServiceEvaluateRequest(); - message.policyReference = object.policyReference ?? ""; - message.inputs = Object.entries(object.inputs ?? {}).reduce<{ [key: string]: string }>((acc, [key, value]) => { - if (value !== undefined) { - acc[key] = String(value); - } - return acc; - }, {}); - return message; - }, -}; - -function createBasePolicyEvaluationServiceEvaluateRequest_InputsEntry(): PolicyEvaluationServiceEvaluateRequest_InputsEntry { - return { key: "", value: "" }; -} - -export const PolicyEvaluationServiceEvaluateRequest_InputsEntry = { - encode( - message: PolicyEvaluationServiceEvaluateRequest_InputsEntry, - writer: _m0.Writer = _m0.Writer.create(), - ): _m0.Writer { - if (message.key !== "") { - writer.uint32(10).string(message.key); - } - if (message.value !== "") { - writer.uint32(18).string(message.value); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluationServiceEvaluateRequest_InputsEntry { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBasePolicyEvaluationServiceEvaluateRequest_InputsEntry(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.key = reader.string(); - continue; - case 2: - if (tag !== 18) { - break; - } - - message.value = reader.string(); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): PolicyEvaluationServiceEvaluateRequest_InputsEntry { - return { key: isSet(object.key) ? String(object.key) : "", value: isSet(object.value) ? String(object.value) : "" }; - }, - - toJSON(message: PolicyEvaluationServiceEvaluateRequest_InputsEntry): unknown { - const obj: any = {}; - message.key !== undefined && (obj.key = message.key); - message.value !== undefined && (obj.value = message.value); - return obj; - }, - - create, I>>( - base?: I, - ): PolicyEvaluationServiceEvaluateRequest_InputsEntry { - return PolicyEvaluationServiceEvaluateRequest_InputsEntry.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): PolicyEvaluationServiceEvaluateRequest_InputsEntry { - const message = createBasePolicyEvaluationServiceEvaluateRequest_InputsEntry(); - message.key = object.key ?? ""; - message.value = object.value ?? ""; - return message; - }, -}; - -function createBasePolicyEvaluationServiceEvaluateResponse(): PolicyEvaluationServiceEvaluateResponse { - return { result: undefined }; -} - -export const PolicyEvaluationServiceEvaluateResponse = { - encode(message: PolicyEvaluationServiceEvaluateResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { - if (message.result !== undefined) { - PolicyEvaluation.encode(message.result, writer.uint32(10).fork()).ldelim(); - } - return writer; - }, - - decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluationServiceEvaluateResponse { - const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); - let end = length === undefined ? reader.len : reader.pos + length; - const message = createBasePolicyEvaluationServiceEvaluateResponse(); - while (reader.pos < end) { - const tag = reader.uint32(); - switch (tag >>> 3) { - case 1: - if (tag !== 10) { - break; - } - - message.result = PolicyEvaluation.decode(reader, reader.uint32()); - continue; - } - if ((tag & 7) === 4 || tag === 0) { - break; - } - reader.skipType(tag & 7); - } - return message; - }, - - fromJSON(object: any): PolicyEvaluationServiceEvaluateResponse { - return { result: isSet(object.result) ? PolicyEvaluation.fromJSON(object.result) : undefined }; - }, - - toJSON(message: PolicyEvaluationServiceEvaluateResponse): unknown { - const obj: any = {}; - message.result !== undefined && (obj.result = message.result ? PolicyEvaluation.toJSON(message.result) : undefined); - return obj; - }, - - create, I>>( - base?: I, - ): PolicyEvaluationServiceEvaluateResponse { - return PolicyEvaluationServiceEvaluateResponse.fromPartial(base ?? {}); - }, - - fromPartial, I>>( - object: I, - ): PolicyEvaluationServiceEvaluateResponse { - const message = createBasePolicyEvaluationServiceEvaluateResponse(); - message.result = (object.result !== undefined && object.result !== null) - ? PolicyEvaluation.fromPartial(object.result) - : undefined; - return message; - }, -}; - -export interface PolicyEvaluationService { - Evaluate( - request: DeepPartial, - metadata?: grpc.Metadata, - ): Promise; -} - -export class PolicyEvaluationServiceClientImpl implements PolicyEvaluationService { - private readonly rpc: Rpc; - - constructor(rpc: Rpc) { - this.rpc = rpc; - this.Evaluate = this.Evaluate.bind(this); - } - - Evaluate( - request: DeepPartial, - metadata?: grpc.Metadata, - ): Promise { - return this.rpc.unary( - PolicyEvaluationServiceEvaluateDesc, - PolicyEvaluationServiceEvaluateRequest.fromPartial(request), - metadata, - ); - } -} - -export const PolicyEvaluationServiceDesc = { serviceName: "controlplane.v1.PolicyEvaluationService" }; - -export const PolicyEvaluationServiceEvaluateDesc: UnaryMethodDefinitionish = { - methodName: "Evaluate", - service: PolicyEvaluationServiceDesc, - requestStream: false, - responseStream: false, - requestType: { - serializeBinary() { - return PolicyEvaluationServiceEvaluateRequest.encode(this).finish(); - }, - } as any, - responseType: { - deserializeBinary(data: Uint8Array) { - const value = PolicyEvaluationServiceEvaluateResponse.decode(data); - return { - ...value, - toObject() { - return value; - }, - }; - }, - } as any, -}; - -interface UnaryMethodDefinitionishR extends grpc.UnaryMethodDefinition { - requestStream: any; - responseStream: any; -} - -type UnaryMethodDefinitionish = UnaryMethodDefinitionishR; - -interface Rpc { - unary( - methodDesc: T, - request: any, - metadata: grpc.Metadata | undefined, - ): Promise; -} - -export class GrpcWebImpl { - private host: string; - private options: { - transport?: grpc.TransportFactory; - - debug?: boolean; - metadata?: grpc.Metadata; - upStreamRetryCodes?: number[]; - }; - - constructor( - host: string, - options: { - transport?: grpc.TransportFactory; - - debug?: boolean; - metadata?: grpc.Metadata; - upStreamRetryCodes?: number[]; - }, - ) { - this.host = host; - this.options = options; - } - - unary( - methodDesc: T, - _request: any, - metadata: grpc.Metadata | undefined, - ): Promise { - const request = { ..._request, ...methodDesc.requestType }; - const maybeCombinedMetadata = metadata && this.options.metadata - ? new BrowserHeaders({ ...this.options?.metadata.headersMap, ...metadata?.headersMap }) - : metadata || this.options.metadata; - return new Promise((resolve, reject) => { - grpc.unary(methodDesc, { - request, - host: this.host, - metadata: maybeCombinedMetadata, - transport: this.options.transport, - debug: this.options.debug, - onEnd: function (response) { - if (response.status === grpc.Code.OK) { - resolve(response.message!.toObject()); - } else { - const err = new GrpcWebError(response.statusMessage, response.status, response.trailers); - reject(err); - } - }, - }); - }); - } -} - -declare var self: any | undefined; -declare var window: any | undefined; -declare var global: any | undefined; -var tsProtoGlobalThis: any = (() => { - if (typeof globalThis !== "undefined") { - return globalThis; - } - if (typeof self !== "undefined") { - return self; - } - if (typeof window !== "undefined") { - return window; - } - if (typeof global !== "undefined") { - return global; - } - throw "Unable to locate global object"; -})(); - -type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; - -export type DeepPartial = T extends Builtin ? T - : T extends Array ? Array> : T extends ReadonlyArray ? ReadonlyArray> - : T extends {} ? { [K in keyof T]?: DeepPartial } - : Partial; - -type KeysOfUnion = T extends T ? keyof T : never; -export type Exact = P extends Builtin ? P - : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; - -function isObject(value: any): boolean { - return typeof value === "object" && value !== null; -} - -function isSet(value: any): boolean { - return value !== null && value !== undefined; -} - -export class GrpcWebError extends tsProtoGlobalThis.Error { - constructor(message: string, public code: grpc.Code, public metadata: grpc.Metadata) { - super(message); - } -} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json deleted file mode 100644 index c126f5e18..000000000 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "$id": "controlplane.v1.PolicyEvaluationServiceEvaluateRequest.jsonschema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": false, - "patternProperties": { - "^(policy_reference)$": { - "minLength": 1, - "type": "string" - } - }, - "properties": { - "inputs": { - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "policyReference": { - "minLength": 1, - "type": "string" - } - }, - "title": "Policy Evaluation Service Evaluate Request", - "type": "object" -} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json deleted file mode 100644 index 3997fe5e4..000000000 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "$id": "controlplane.v1.PolicyEvaluationServiceEvaluateRequest.schema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": false, - "patternProperties": { - "^(policyReference)$": { - "minLength": 1, - "type": "string" - } - }, - "properties": { - "inputs": { - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "type": "string" - }, - "type": "object" - }, - "policy_reference": { - "minLength": 1, - "type": "string" - } - }, - "title": "Policy Evaluation Service Evaluate Request", - "type": "object" -} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json deleted file mode 100644 index 8eb64eb4d..000000000 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$id": "controlplane.v1.PolicyEvaluationServiceEvaluateResponse.jsonschema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": false, - "properties": { - "result": { - "$ref": "attestation.v1.PolicyEvaluation.jsonschema.json" - } - }, - "title": "Policy Evaluation Service Evaluate Response", - "type": "object" -} diff --git a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json b/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json deleted file mode 100644 index 0efa4d9b3..000000000 --- a/app/controlplane/api/gen/jsonschema/controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$id": "controlplane.v1.PolicyEvaluationServiceEvaluateResponse.schema.json", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "additionalProperties": false, - "properties": { - "result": { - "$ref": "attestation.v1.PolicyEvaluation.schema.json" - } - }, - "title": "Policy Evaluation Service Evaluate Response", - "type": "object" -} diff --git a/app/controlplane/cmd/wire_gen.go b/app/controlplane/cmd/wire_gen.go index 702a0b630..436700e5e 100644 --- a/app/controlplane/cmd/wire_gen.go +++ b/app/controlplane/cmd/wire_gen.go @@ -238,8 +238,6 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l prometheusService := service.NewPrometheusService(organizationUseCase, prometheusUseCase, v5...) groupService := service.NewGroupService(groupUseCase, v5...) projectService := service.NewProjectService(v5...) - policyEvaluationUseCase := biz.NewPolicyEvaluationUseCase(organizationRepo, logger) - policyEvaluationService := service.NewPolicyEvaluationService(policyEvaluationUseCase, v5...) federatedAuthentication := bootstrap.FederatedAuthentication validator, err := newProtoValidator() if err != nil { @@ -280,7 +278,6 @@ func wireApp(bootstrap *conf.Bootstrap, readerWriter credentials.ReaderWriter, l PrometheusSvc: prometheusService, GroupSvc: groupService, ProjectSvc: projectService, - PolicyEvaluationSvc: policyEvaluationService, Logger: logger, ServerConfig: confServer, AuthConfig: auth, diff --git a/app/controlplane/internal/server/grpc.go b/app/controlplane/internal/server/grpc.go index 8d4a952a8..2a830b2dc 100644 --- a/app/controlplane/internal/server/grpc.go +++ b/app/controlplane/internal/server/grpc.go @@ -84,7 +84,6 @@ type Opts struct { PrometheusSvc *service.PrometheusService GroupSvc *service.GroupService ProjectSvc *service.ProjectService - PolicyEvaluationSvc *service.PolicyEvaluationService // Utils Logger log.Logger ServerConfig *conf.Server @@ -156,7 +155,6 @@ func NewGRPCServer(opts *Opts) (*grpc.Server, error) { v1.RegisterSigningServiceServer(srv, opts.SigningSvc) v1.RegisterGroupServiceServer(srv, opts.GroupSvc) v1.RegisterProjectServiceServer(srv, opts.ProjectSvc) - v1.RegisterPolicyEvaluationServiceServer(srv, opts.PolicyEvaluationSvc) // Register Prometheus metrics grpc_prometheus.Register(srv.Server) diff --git a/app/controlplane/internal/service/policyevaluation.go b/app/controlplane/internal/service/policyevaluation.go deleted file mode 100644 index ada1e80b2..000000000 --- a/app/controlplane/internal/service/policyevaluation.go +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright 2025 The Chainloop Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package service - -import ( - "context" - - pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" - "github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz" -) - -type PolicyEvaluationService struct { - pb.UnimplementedPolicyEvaluationServiceServer - *service - - uc *biz.PolicyEvaluationUseCase -} - -func NewPolicyEvaluationService(uc *biz.PolicyEvaluationUseCase, opts ...NewOpt) *PolicyEvaluationService { - return &PolicyEvaluationService{ - service: newService(opts...), - uc: uc, - } -} - -func (s *PolicyEvaluationService) Evaluate(ctx context.Context, req *pb.PolicyEvaluationServiceEvaluateRequest) (*pb.PolicyEvaluationServiceEvaluateResponse, error) { - // Verify current org is set (middleware handles this) - _, err := requireCurrentOrg(ctx) - if err != nil { - return nil, err - } - - // Call business layer to evaluate the policy - result, err := s.uc.Evaluate(ctx, &biz.PolicyEvaluationEvaluateOpts{ - PolicyReference: req.PolicyReference, - Inputs: req.Inputs, - }) - if err != nil { - return nil, handleUseCaseErr(err, s.log) - } - - return &pb.PolicyEvaluationServiceEvaluateResponse{ - Result: result, - }, nil -} diff --git a/app/controlplane/internal/service/service.go b/app/controlplane/internal/service/service.go index 77d8714d1..06275775d 100644 --- a/app/controlplane/internal/service/service.go +++ b/app/controlplane/internal/service/service.go @@ -60,7 +60,6 @@ var ProviderSet = wire.NewSet( NewPrometheusService, NewGroupService, NewProjectService, - NewPolicyEvaluationService, wire.Struct(new(NewWorkflowRunServiceOpts), "*"), wire.Struct(new(NewAttestationServiceOpts), "*"), wire.Struct(new(NewAttestationStateServiceOpt), "*"), diff --git a/app/controlplane/pkg/biz/biz.go b/app/controlplane/pkg/biz/biz.go index c3e61343b..f8484b2ad 100644 --- a/app/controlplane/pkg/biz/biz.go +++ b/app/controlplane/pkg/biz/biz.go @@ -58,7 +58,6 @@ var ProviderSet = wire.NewSet( NewGroupUseCase, NewCASBackendChecker, NewAuthzUseCase, - NewPolicyEvaluationUseCase, wire.Bind(new(PromObservable), new(*PrometheusUseCase)), wire.Struct(new(NewIntegrationUseCaseOpts), "*"), wire.Struct(new(NewUserUseCaseParams), "*"), diff --git a/app/controlplane/pkg/biz/policyevaluation.go b/app/controlplane/pkg/biz/policyevaluation.go deleted file mode 100644 index 147785b10..000000000 --- a/app/controlplane/pkg/biz/policyevaluation.go +++ /dev/null @@ -1,117 +0,0 @@ -// -// Copyright 2025 The Chainloop Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package biz - -import ( - "context" - "fmt" - - "github.com/chainloop-dev/chainloop/app/controlplane/internal/usercontext/entities" - "github.com/chainloop-dev/chainloop/pkg/policies" - "github.com/go-kratos/kratos/v2/log" - "github.com/google/uuid" - "github.com/rs/zerolog" - - schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" - crafterAPI "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" -) - -type PolicyEvaluationUseCase struct { - orgRepo OrganizationRepo - logger *log.Helper -} - -func NewPolicyEvaluationUseCase( - orgRepo OrganizationRepo, - logger log.Logger, -) *PolicyEvaluationUseCase { - return &PolicyEvaluationUseCase{ - orgRepo: orgRepo, - logger: log.NewHelper(logger), - } -} - -// Evaluate executes a generic policy evaluation without material context and returns the result -func (uc *PolicyEvaluationUseCase) Evaluate(ctx context.Context, opts *PolicyEvaluationEvaluateOpts) (*crafterAPI.PolicyEvaluation, error) { - // Get current organization - currentOrg := entities.CurrentOrg(ctx) - if currentOrg == nil { - return nil, NewErrNotFound("organization") - } - - // Load full organization details to get policies_allowed_hostnames - orgUUID, err := uuid.Parse(currentOrg.ID) - if err != nil { - return nil, fmt.Errorf("invalid organization ID: %w", err) - } - - org, err := uc.orgRepo.FindByID(ctx, orgUUID) - if err != nil { - return nil, err - } - - // Create policy attachment for evaluation - ref := opts.PolicyReference - scheme, _ := policies.RefParts(opts.PolicyReference) - if scheme == "" { - // If no scheme, assume it's a file path and add file:// prefix - ref = fmt.Sprintf("file://%s", opts.PolicyReference) - } - - attachment := &schemaapi.PolicyAttachment{ - Policy: &schemaapi.PolicyAttachment_Ref{Ref: ref}, - With: opts.Inputs, - } - - // Create policy verifier with organization's allowed hostnames - zlog := zerolog.Ctx(ctx) - if zlog == nil || zlog.GetLevel() == zerolog.Disabled { - l := zerolog.New(zerolog.NewConsoleWriter()) - zlog = &l - } - - verifierOpts := []policies.PolicyVerifierOption{ - policies.WithIncludeRawData(false), - } - if len(org.PoliciesAllowedHostnames) > 0 { - verifierOpts = append(verifierOpts, policies.WithAllowedHostnames(org.PoliciesAllowedHostnames...)) - } - - pol := &schemaapi.Policies{} - verifier := policies.NewPolicyVerifier(pol, nil, zlog, verifierOpts...) - - // Evaluate the policy - policyEv, err := verifier.EvaluateGeneric(ctx, attachment) - if err != nil { - return nil, fmt.Errorf("evaluating policy: %w", err) - } - - if policyEv == nil { - return nil, fmt.Errorf("no execution branch matched, or all of them were ignored") - } - - // Check if violations should block - if len(policyEv.Violations) > 0 && org.BlockOnPolicyViolation { - return policyEv, fmt.Errorf("policy evaluation failed with %d violation(s)", len(policyEv.Violations)) - } - - return policyEv, nil -} - -type PolicyEvaluationEvaluateOpts struct { - PolicyReference string - Inputs map[string]string -} From d5ed56055349da3a5e65fa832d5c96cc404be301 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Tue, 16 Dec 2025 13:16:47 +0100 Subject: [PATCH 6/7] cli ref Signed-off-by: Sylwester Piskozub --- app/cli/cmd/policy_eval.go | 2 +- app/cli/documentation/cli-reference.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/cli/cmd/policy_eval.go b/app/cli/cmd/policy_eval.go index 62224e277..a648c444f 100644 --- a/app/cli/cmd/policy_eval.go +++ b/app/cli/cmd/policy_eval.go @@ -36,7 +36,7 @@ func newPolicyEvalCmd() *cobra.Command { cmd := &cobra.Command{ Use: "eval", Short: "Evaluate a policy", - Long: `Evaluate a policy. + Long: `Evaluate a policy with organization settings. This command uses organization context to evaluate policies. diff --git a/app/cli/documentation/cli-reference.mdx b/app/cli/documentation/cli-reference.mdx index c3f87d30f..8e42eb273 100755 --- a/app/cli/documentation/cli-reference.mdx +++ b/app/cli/documentation/cli-reference.mdx @@ -3023,7 +3023,7 @@ Evaluate a policy Synopsis -Evaluate a policy. +Evaluate a policy with organization settings. This command uses organization context to evaluate policies. From bd39b27376b11143db8b299d5e01b5c8c4fc1f22 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Tue, 16 Dec 2025 14:10:40 +0100 Subject: [PATCH 7/7] missing new kind Signed-off-by: Sylwester Piskozub --- app/cli/documentation/cli-reference.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/cli/documentation/cli-reference.mdx b/app/cli/documentation/cli-reference.mdx index 8e42eb273..03048b4e2 100755 --- a/app/cli/documentation/cli-reference.mdx +++ b/app/cli/documentation/cli-reference.mdx @@ -3046,7 +3046,7 @@ Options --annotation strings Key-value pairs of material annotations (key=value) -h, --help help for eval --input stringArray Key-value pairs of policy inputs (key=value) ---kind string Kind of the material: ["ARTIFACT" "ATTESTATION" "BLACKDUCK_SCA_JSON" "CHAINLOOP_RUNNER_CONTEXT" "CONTAINER_IMAGE" "CSAF_INFORMATIONAL_ADVISORY" "CSAF_SECURITY_ADVISORY" "CSAF_SECURITY_INCIDENT_RESPONSE" "CSAF_VEX" "EVIDENCE" "GHAS_CODE_SCAN" "GHAS_DEPENDENCY_SCAN" "GHAS_SECRET_SCAN" "GITLAB_SECURITY_REPORT" "HELM_CHART" "JACOCO_XML" "JUNIT_XML" "OPENVEX" "SARIF" "SBOM_CYCLONEDX_JSON" "SBOM_SPDX_JSON" "SLSA_PROVENANCE" "STRING" "TWISTCLI_SCAN_JSON" "ZAP_DAST_ZIP"] +--kind string Kind of the material: ["ARTIFACT" "ATTESTATION" "BLACKDUCK_SCA_JSON" "CHAINLOOP_PR_INFO" "CHAINLOOP_RUNNER_CONTEXT" "CONTAINER_IMAGE" "CSAF_INFORMATIONAL_ADVISORY" "CSAF_SECURITY_ADVISORY" "CSAF_SECURITY_INCIDENT_RESPONSE" "CSAF_VEX" "EVIDENCE" "GHAS_CODE_SCAN" "GHAS_DEPENDENCY_SCAN" "GHAS_SECRET_SCAN" "GITLAB_SECURITY_REPORT" "HELM_CHART" "JACOCO_XML" "JUNIT_XML" "OPENVEX" "SARIF" "SBOM_CYCLONEDX_JSON" "SBOM_SPDX_JSON" "SLSA_PROVENANCE" "STRING" "TWISTCLI_SCAN_JSON" "ZAP_DAST_ZIP"] --material string Path to material or attestation file -p, --policy string Policy reference (./my-policy.yaml, https://my-domain.com/my-policy.yaml) ```