From c903ccce5f25be4717241650398c2c1372106014 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Wed, 13 Aug 2025 15:45:38 +0200 Subject: [PATCH 01/15] add raw flag Signed-off-by: Sylwester Piskozub --- app/cli/cmd/policy_develop_eval.go | 9 + .../internal/action/policy_develop_eval.go | 10 +- app/cli/internal/policydevel/eval.go | 15 + .../frontend/attestation/v1/crafting_state.ts | 19 ++ ...tation.v1.PolicyEvaluation.jsonschema.json | 12 + ...ttestation.v1.PolicyEvaluation.schema.json | 12 + .../api/attestation/v1/crafting_state.pb.go | 317 +++++++++--------- .../api/attestation/v1/crafting_state.proto | 2 + pkg/policies/engine/engine.go | 2 + pkg/policies/engine/rego/rego.go | 109 +++--- pkg/policies/policies.go | 18 + 11 files changed, 331 insertions(+), 194 deletions(-) diff --git a/app/cli/cmd/policy_develop_eval.go b/app/cli/cmd/policy_develop_eval.go index c3a877b70..97695ed38 100644 --- a/app/cli/cmd/policy_develop_eval.go +++ b/app/cli/cmd/policy_develop_eval.go @@ -32,6 +32,7 @@ func newPolicyDevelopEvalCmd() *cobra.Command { policyPath string inputs []string allowedHostnames []string + raw bool ) cmd := &cobra.Command{ @@ -63,6 +64,13 @@ evaluates the policy against the provided material or attestation.`, return err } + if raw { + return encodeJSON(result[0].RawResults) + } + + // Hide skip reasons in non-verbose mode + result[0].RawResults = nil + return encodeJSON(result) }, } @@ -74,6 +82,7 @@ evaluates the policy against the provided material or attestation.`, cmd.Flags().StringVarP(&policyPath, "policy", "p", "policy.yaml", "Path to custom policy file") cmd.Flags().StringSliceVar(&inputs, "input", []string{}, "Key-value pairs of policy inputs (key=value)") cmd.Flags().StringSliceVar(&allowedHostnames, "allowed-hostnames", []string{}, "Additional hostnames allowed for http.send requests in policies") + cmd.Flags().BoolVarP(&raw, "raw", "", false, "Enable raw output") return cmd } diff --git a/app/cli/internal/action/policy_develop_eval.go b/app/cli/internal/action/policy_develop_eval.go index aa68711b8..0c3e43d53 100644 --- a/app/cli/internal/action/policy_develop_eval.go +++ b/app/cli/internal/action/policy_develop_eval.go @@ -29,10 +29,11 @@ type PolicyEvalOpts struct { } type PolicyEvalResult struct { - Violations []string `json:"violations"` - SkipReasons []string `json:"skip_reasons"` - Skipped bool `json:"skipped"` - Ignored bool `json:"ignored,omitempty"` + Violations []string `json:"violations"` + SkipReasons []string `json:"skip_reasons"` + Skipped bool `json:"skipped"` + Ignored bool `json:"ignored,omitempty"` + RawResults []map[string]interface{} `json:"raw_results,omitempty"` } type PolicyEval struct { @@ -70,6 +71,7 @@ func (action *PolicyEval) Run() ([]*PolicyEvalResult, error) { SkipReasons: r.SkipReasons, Skipped: r.Skipped, Ignored: r.Ignored, + RawResults: r.RawResults, }) } diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index ccb997347..cc481f07b 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -23,6 +23,7 @@ import ( "github.com/chainloop-dev/chainloop/pkg/casclient" "github.com/chainloop-dev/chainloop/pkg/policies" "github.com/rs/zerolog" + "google.golang.org/protobuf/types/known/structpb" v12 "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/materials" @@ -42,6 +43,7 @@ type EvalResult struct { SkipReasons []string Violations []string Ignored bool + RawResults []map[string]interface{} } func Evaluate(opts *EvalOptions, logger zerolog.Logger) ([]*EvalResult, error) { @@ -104,6 +106,7 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia Skipped: policyEv.GetSkipped(), SkipReasons: policyEv.SkipReasons, Ignored: false, + RawResults: apiRawResultsToEngineRawResults(policyEv.RawResults), } // Collect all violation messages @@ -166,3 +169,15 @@ func fileNotExists(path string) bool { _, err := os.Stat(path) return os.IsNotExist(err) } + +func apiRawResultsToEngineRawResults(apiResults []*structpb.Struct) []map[string]any { + res := make([]map[string]any, 0) + for _, s := range apiResults { + if s == nil { + continue + } + m := s.AsMap() + res = append(res, m) + } + return res +} diff --git a/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts b/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts index a84266695..cf477d886 100644 --- a/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts +++ b/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts @@ -280,6 +280,7 @@ export interface PolicyEvaluation { groupReference?: PolicyEvaluation_Reference; /** List of requirements this policy contributes to satisfy */ requirements: string[]; + rawResults: { [key: string]: any }[]; } export interface PolicyEvaluation_AnnotationsEntry { @@ -2096,6 +2097,7 @@ function createBasePolicyEvaluation(): PolicyEvaluation { policyReference: undefined, groupReference: undefined, requirements: [], + rawResults: [], }; } @@ -2149,6 +2151,9 @@ export const PolicyEvaluation = { for (const v of message.requirements) { writer.uint32(138).string(v!); } + for (const v of message.rawResults) { + Struct.encode(Struct.wrap(v!), writer.uint32(154).fork()).ldelim(); + } return writer; }, @@ -2277,6 +2282,13 @@ export const PolicyEvaluation = { message.requirements.push(reader.string()); continue; + case 19: + if (tag !== 154) { + break; + } + + message.rawResults.push(Struct.unwrap(Struct.decode(reader, reader.uint32()))); + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -2322,6 +2334,7 @@ export const PolicyEvaluation = { requirements: Array.isArray(object?.requirements) ? object.requirements.map((e: any) => String(e)) : [], + rawResults: Array.isArray(object?.rawResults) ? [...object.rawResults] : [], }; }, @@ -2373,6 +2386,11 @@ export const PolicyEvaluation = { } else { obj.requirements = []; } + if (message.rawResults) { + obj.rawResults = message.rawResults.map((e) => e); + } else { + obj.rawResults = []; + } return obj; }, @@ -2415,6 +2433,7 @@ export const PolicyEvaluation = { ? PolicyEvaluation_Reference.fromPartial(object.groupReference) : undefined; message.requirements = object.requirements?.map((e) => e) || []; + message.rawResults = object.rawResults?.map((e) => e) || []; return message; }, }; diff --git a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.jsonschema.json b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.jsonschema.json index 8867b710e..6cbaa6c83 100644 --- a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.jsonschema.json @@ -14,6 +14,12 @@ "$ref": "attestation.v1.PolicyEvaluation.Reference.jsonschema.json", "description": "Group this evaluated policy belongs to, if any" }, + "^(raw_results)$": { + "items": { + "$ref": "google.protobuf.Struct.jsonschema.json" + }, + "type": "array" + }, "^(reference_digest)$": { "description": "fully qualified reference to the policy\n i.e\n http://my-domain.com/foo.yaml\n file://foo.yaml\n chainloop://my-provider.com/foo@sha256:1234\n NOTE: embedded policies will not have a reference\n Deprecated: use policy_reference instead", "type": "string" @@ -60,6 +66,12 @@ "$ref": "attestation.v1.PolicyEvaluation.Reference.jsonschema.json", "description": "Group this evaluated policy belongs to, if any" }, + "rawResults": { + "items": { + "$ref": "google.protobuf.Struct.jsonschema.json" + }, + "type": "array" + }, "referenceDigest": { "description": "fully qualified reference to the policy\n i.e\n http://my-domain.com/foo.yaml\n file://foo.yaml\n chainloop://my-provider.com/foo@sha256:1234\n NOTE: embedded policies will not have a reference\n Deprecated: use policy_reference instead", "type": "string" diff --git a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.schema.json b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.schema.json index fba98ffb5..171f9eaba 100644 --- a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.schema.json +++ b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.schema.json @@ -14,6 +14,12 @@ "$ref": "attestation.v1.PolicyEvaluation.Reference.schema.json", "description": "Group this evaluated policy belongs to, if any" }, + "^(rawResults)$": { + "items": { + "$ref": "google.protobuf.Struct.schema.json" + }, + "type": "array" + }, "^(referenceDigest)$": { "description": "fully qualified reference to the policy\n i.e\n http://my-domain.com/foo.yaml\n file://foo.yaml\n chainloop://my-provider.com/foo@sha256:1234\n NOTE: embedded policies will not have a reference\n Deprecated: use policy_reference instead", "type": "string" @@ -60,6 +66,12 @@ "$ref": "attestation.v1.PolicyEvaluation.Reference.schema.json", "description": "Group this evaluated policy belongs to, if any" }, + "raw_results": { + "items": { + "$ref": "google.protobuf.Struct.schema.json" + }, + "type": "array" + }, "reference_digest": { "description": "fully qualified reference to the policy\n i.e\n http://my-domain.com/foo.yaml\n file://foo.yaml\n chainloop://my-provider.com/foo@sha256:1234\n NOTE: embedded policies will not have a reference\n Deprecated: use policy_reference instead", "type": "string" diff --git a/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go b/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go index 7d748a046..4c4a00aa7 100644 --- a/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go +++ b/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go @@ -397,7 +397,8 @@ type PolicyEvaluation struct { PolicyReference *PolicyEvaluation_Reference `protobuf:"bytes,15,opt,name=policy_reference,json=policyReference,proto3" json:"policy_reference,omitempty"` GroupReference *PolicyEvaluation_Reference `protobuf:"bytes,16,opt,name=group_reference,json=groupReference,proto3" json:"group_reference,omitempty"` // List of requirements this policy contributes to satisfy - Requirements []string `protobuf:"bytes,17,rep,name=requirements,proto3" json:"requirements,omitempty"` + Requirements []string `protobuf:"bytes,17,rep,name=requirements,proto3" json:"requirements,omitempty"` + RawResults []*structpb.Struct `protobuf:"bytes,19,rep,name=raw_results,json=rawResults,proto3" json:"raw_results,omitempty"` } func (x *PolicyEvaluation) Reset() { @@ -547,6 +548,13 @@ func (x *PolicyEvaluation) GetRequirements() []string { return nil } +func (x *PolicyEvaluation) GetRawResults() []*structpb.Struct { + if x != nil { + return x.RawResults + } + return nil +} + type Commit struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2116,7 +2124,7 @@ var file_attestation_v1_crafting_state_proto_rawDesc = []byte{ 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, - 0x22, 0x85, 0x0b, 0x0a, 0x10, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x22, 0xbf, 0x0b, 0x0a, 0x10, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x82, 0x01, 0xba, 0x48, 0x7f, 0xba, 0x01, 0x7c, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x64, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x32, 0x33, 0x12, 0x3a, 0x6d, 0x75, @@ -2175,131 +2183,135 @@ var file_attestation_v1_crafting_state_proto_rawDesc = []byte{ 0x6e, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x1a, - 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x1a, - 0x37, 0x0a, 0x09, 0x57, 0x69, 0x74, 0x68, 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, 0x1a, 0x4f, 0x0a, 0x09, 0x56, 0x69, 0x6f, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, - 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x20, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, - 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0xfc, 0x01, 0x0a, 0x09, 0x52, 0x65, - 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x82, 0x01, 0xba, 0x48, 0x7f, 0xba, 0x01, 0x7c, 0x0a, - 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x64, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x32, 0x33, 0x12, 0x3a, - 0x6d, 0x75, 0x73, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, - 0x79, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6c, 0x65, 0x74, 0x74, - 0x65, 0x72, 0x73, 0x2c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2e, 0x1a, 0x2f, 0x74, 0x68, 0x69, 0x73, - 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, - 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x2d, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2a, 0x5b, 0x61, - 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, - 0x73, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x19, 0x0a, - 0x08, 0x6f, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x6f, 0x72, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xde, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, - 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, - 0x61, 0x69, 0x6c, 0x12, 0x28, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, - 0x01, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x37, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, - 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0x40, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, - 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0xaf, 0x01, 0x0a, 0x0d, 0x43, 0x72, - 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0c, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x12, 0x3d, 0x0a, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0xa3, 0x03, 0x0a, 0x10, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, - 0x61, 0x6d, 0x12, 0x28, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, - 0x75, 0x6e, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x72, - 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, - 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, - 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, - 0x02, 0x10, 0x01, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x22, 0x7d, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, - 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x72, - 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x61, - 0x73, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0e, 0x6d, 0x61, 0x72, 0x6b, 0x41, 0x73, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, - 0x22, 0xde, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, - 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x46, 0x0a, - 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, - 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x09, 0x52, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x38, 0x0a, 0x0b, 0x72, 0x61, 0x77, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x13, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x72, + 0x61, 0x77, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x1a, 0x37, 0x0a, 0x09, 0x57, 0x69, 0x74, + 0x68, 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, 0x1a, 0x4f, 0x0a, 0x09, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x20, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x12, 0x20, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x1a, 0xfc, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x82, 0x01, 0xba, 0x48, 0x7f, 0xba, 0x01, 0x7c, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x2e, + 0x64, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x32, 0x33, 0x12, 0x3a, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6c, 0x6f, 0x77, 0x65, + 0x72, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68, 0x79, 0x70, 0x68, + 0x65, 0x6e, 0x73, 0x2e, 0x1a, 0x2f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x2d, + 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, + 0x29, 0x3f, 0x24, 0x27, 0x29, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, + 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x03, + 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x67, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x67, 0x4e, 0x61, + 0x6d, 0x65, 0x22, 0xde, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x28, 0x0a, + 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x72, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x74, + 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x1a, 0x40, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, + 0x75, 0x72, 0x6c, 0x22, 0xaf, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x3d, 0x0a, + 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, + 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, + 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0xa3, 0x03, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x12, 0x2b, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1e, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x61, 0x6d, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x61, 0x6d, 0x12, 0x28, 0x0a, 0x0b, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x12, 0x30, + 0x0a, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, + 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, + 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, + 0x0a, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x6f, + 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7d, 0x0a, 0x0e, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6d, 0x61, 0x72, 0x6b, + 0x41, 0x73, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x22, 0xde, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x2e, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x64, - 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, - 0x2b, 0x0a, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, - 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x61, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, - 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, 0x42, 0x4f, 0x5a, 0x4d, 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, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, - 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x46, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x44, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x6f, 0x77, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x1a, 0x39, 0x0a, 0x0b, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 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, 0x42, 0x4f, 0x5a, 0x4d, 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, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2f, 0x63, 0x72, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x74, + 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2347,8 +2359,8 @@ var file_attestation_v1_crafting_state_proto_goTypes = []interface{}{ (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp (v1.CraftingSchema_Runner_RunnerType)(0), // 28: workflowcontract.v1.CraftingSchema.Runner.RunnerType (v1.CraftingSchema_Material_MaterialType)(0), // 29: workflowcontract.v1.CraftingSchema.Material.MaterialType - (*v1.CraftingSchema)(nil), // 30: workflowcontract.v1.CraftingSchema - (*structpb.Struct)(nil), // 31: google.protobuf.Struct + (*structpb.Struct)(nil), // 30: google.protobuf.Struct + (*v1.CraftingSchema)(nil), // 31: workflowcontract.v1.CraftingSchema (*wrapperspb.BoolValue)(nil), // 32: google.protobuf.BoolValue } var file_attestation_v1_crafting_state_proto_depIdxs = []int32{ @@ -2371,30 +2383,31 @@ var file_attestation_v1_crafting_state_proto_depIdxs = []int32{ 29, // 16: attestation.v1.PolicyEvaluation.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType 24, // 17: attestation.v1.PolicyEvaluation.policy_reference:type_name -> attestation.v1.PolicyEvaluation.Reference 24, // 18: attestation.v1.PolicyEvaluation.group_reference:type_name -> attestation.v1.PolicyEvaluation.Reference - 27, // 19: attestation.v1.Commit.date:type_name -> google.protobuf.Timestamp - 25, // 20: attestation.v1.Commit.remotes:type_name -> attestation.v1.Commit.Remote - 30, // 21: attestation.v1.CraftingState.input_schema:type_name -> workflowcontract.v1.CraftingSchema - 1, // 22: attestation.v1.CraftingState.attestation:type_name -> attestation.v1.Attestation - 7, // 23: attestation.v1.WorkflowMetadata.version:type_name -> attestation.v1.ProjectVersion - 26, // 24: attestation.v1.ResourceDescriptor.digest:type_name -> attestation.v1.ResourceDescriptor.DigestEntry - 31, // 25: attestation.v1.ResourceDescriptor.annotations:type_name -> google.protobuf.Struct - 11, // 26: attestation.v1.Attestation.MaterialsEntry.value:type_name -> attestation.v1.Attestation.Material - 16, // 27: attestation.v1.Attestation.Material.string:type_name -> attestation.v1.Attestation.Material.KeyVal - 17, // 28: attestation.v1.Attestation.Material.container_image:type_name -> attestation.v1.Attestation.Material.ContainerImage - 18, // 29: attestation.v1.Attestation.Material.artifact:type_name -> attestation.v1.Attestation.Material.Artifact - 19, // 30: attestation.v1.Attestation.Material.sbom_artifact:type_name -> attestation.v1.Attestation.Material.SBOMArtifact - 27, // 31: attestation.v1.Attestation.Material.added_at:type_name -> google.protobuf.Timestamp - 29, // 32: attestation.v1.Attestation.Material.material_type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 15, // 33: attestation.v1.Attestation.Material.annotations:type_name -> attestation.v1.Attestation.Material.AnnotationsEntry - 0, // 34: attestation.v1.Attestation.Auth.type:type_name -> attestation.v1.Attestation.Auth.AuthType - 32, // 35: attestation.v1.Attestation.Material.ContainerImage.has_latest_tag:type_name -> google.protobuf.BoolValue - 18, // 36: attestation.v1.Attestation.Material.SBOMArtifact.artifact:type_name -> attestation.v1.Attestation.Material.Artifact - 20, // 37: attestation.v1.Attestation.Material.SBOMArtifact.main_component:type_name -> attestation.v1.Attestation.Material.SBOMArtifact.MainComponent - 38, // [38:38] is the sub-list for method output_type - 38, // [38:38] is the sub-list for method input_type - 38, // [38:38] is the sub-list for extension type_name - 38, // [38:38] is the sub-list for extension extendee - 0, // [0:38] is the sub-list for field type_name + 30, // 19: attestation.v1.PolicyEvaluation.raw_results:type_name -> google.protobuf.Struct + 27, // 20: attestation.v1.Commit.date:type_name -> google.protobuf.Timestamp + 25, // 21: attestation.v1.Commit.remotes:type_name -> attestation.v1.Commit.Remote + 31, // 22: attestation.v1.CraftingState.input_schema:type_name -> workflowcontract.v1.CraftingSchema + 1, // 23: attestation.v1.CraftingState.attestation:type_name -> attestation.v1.Attestation + 7, // 24: attestation.v1.WorkflowMetadata.version:type_name -> attestation.v1.ProjectVersion + 26, // 25: attestation.v1.ResourceDescriptor.digest:type_name -> attestation.v1.ResourceDescriptor.DigestEntry + 30, // 26: attestation.v1.ResourceDescriptor.annotations:type_name -> google.protobuf.Struct + 11, // 27: attestation.v1.Attestation.MaterialsEntry.value:type_name -> attestation.v1.Attestation.Material + 16, // 28: attestation.v1.Attestation.Material.string:type_name -> attestation.v1.Attestation.Material.KeyVal + 17, // 29: attestation.v1.Attestation.Material.container_image:type_name -> attestation.v1.Attestation.Material.ContainerImage + 18, // 30: attestation.v1.Attestation.Material.artifact:type_name -> attestation.v1.Attestation.Material.Artifact + 19, // 31: attestation.v1.Attestation.Material.sbom_artifact:type_name -> attestation.v1.Attestation.Material.SBOMArtifact + 27, // 32: attestation.v1.Attestation.Material.added_at:type_name -> google.protobuf.Timestamp + 29, // 33: attestation.v1.Attestation.Material.material_type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 15, // 34: attestation.v1.Attestation.Material.annotations:type_name -> attestation.v1.Attestation.Material.AnnotationsEntry + 0, // 35: attestation.v1.Attestation.Auth.type:type_name -> attestation.v1.Attestation.Auth.AuthType + 32, // 36: attestation.v1.Attestation.Material.ContainerImage.has_latest_tag:type_name -> google.protobuf.BoolValue + 18, // 37: attestation.v1.Attestation.Material.SBOMArtifact.artifact:type_name -> attestation.v1.Attestation.Material.Artifact + 20, // 38: attestation.v1.Attestation.Material.SBOMArtifact.main_component:type_name -> attestation.v1.Attestation.Material.SBOMArtifact.MainComponent + 39, // [39:39] is the sub-list for method output_type + 39, // [39:39] is the sub-list for method input_type + 39, // [39:39] is the sub-list for extension type_name + 39, // [39:39] is the sub-list for extension extendee + 0, // [0:39] is the sub-list for field type_name } func init() { file_attestation_v1_crafting_state_proto_init() } diff --git a/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto b/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto index 379c0b6a7..f8293fcc2 100644 --- a/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto +++ b/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto @@ -271,6 +271,8 @@ message PolicyEvaluation { string uri = 3 [(buf.validate.field).string.min_len = 1]; string org_name = 4; } + + repeated google.protobuf.Struct raw_results = 19; } message Commit { diff --git a/pkg/policies/engine/engine.go b/pkg/policies/engine/engine.go index 294ef051b..c832912f3 100644 --- a/pkg/policies/engine/engine.go +++ b/pkg/policies/engine/engine.go @@ -30,6 +30,8 @@ type EvaluationResult struct { Skipped bool SkipReason string Ignore bool + // contains the raw results from the policy engine + RawResults []map[string]interface{} } // PolicyViolation represents a policy failure diff --git a/pkg/policies/engine/rego/rego.go b/pkg/policies/engine/rego/rego.go index 25806eb45..59de21fcb 100644 --- a/pkg/policies/engine/rego/rego.go +++ b/pkg/policies/engine/rego/rego.go @@ -20,6 +20,7 @@ import ( "context" "encoding/json" "fmt" + "strings" "github.com/chainloop-dev/chainloop/pkg/policies/engine" "github.com/open-policy-agent/opa/ast" @@ -112,6 +113,12 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte return nil, fmt.Errorf("failed to parse rego policy: %w", err) } + // Extract package name + pkgPath := parsedModule.Package.Path.String() + if pkgPath == "" { + return nil, fmt.Errorf("policy has no package declaration") + } + // Decode input as json decoder := json.NewDecoder(bytes.NewReader(input)) decoder.UseNumber() @@ -127,7 +134,7 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte decodedInput = inputMap } - // put arguments embedded in the input object + // put arguments embedded in the input if args != nil { inputMap, ok := decodedInput.(map[string]interface{}) if !ok { @@ -137,44 +144,67 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte decodedInput = inputMap } - // add input - regoInput := rego.Input(decodedInput) + // Prepare rego options + options := []func(*rego.Rego){ + rego.ParsedModule(parsedModule), + rego.Input(decodedInput), + rego.Capabilities(r.Capabilities()), + } - // add module - regoFunc := rego.ParsedModule(parsedModule) + if r.operatingMode == EnvironmentModeRestrictive { + options = append(options, rego.StrictBuiltinErrors(true)) + } - var res rego.ResultSet - // Function to execute the query with appropriate parameters - executeQuery := func(rule string, strict bool) error { - if strict { - res, err = queryRego(ctx, rule, parsedModule, regoInput, regoFunc, rego.Capabilities(r.Capabilities()), rego.StrictBuiltinErrors(true)) - } else { - res, err = queryRego(ctx, rule, parsedModule, regoInput, regoFunc, rego.Capabilities(r.Capabilities())) - } - return err + // First try evaluating the entire package + res, err := r.evaluatePackage(ctx, pkgPath, options) + if err != nil { + return nil, err + } + + // If we got results, parse them + if res != nil { + return parseResultRule(res, policy) } - // Try the main rule first - if err := executeQuery(mainRule, r.operatingMode == EnvironmentModeRestrictive); err != nil { + // Fallback to evaluating specific rules if package evaluation returned nothing + return r.evaluateSpecificRules(ctx, parsedModule, options, policy) +} + +// Evaluate the entire package by querying data. +func (r *Engine) evaluatePackage(ctx context.Context, pkgPath string, options []func(*rego.Rego)) (rego.ResultSet, error) { + query := fmt.Sprintf("data.%s", strings.TrimPrefix(pkgPath, "data.")) + regoEval := rego.New(append(options, rego.Query(query))...) + return regoEval.Eval(ctx) +} + +func (r *Engine) evaluateSpecificRules(ctx context.Context, module *ast.Module, options []func(*rego.Rego), policy *engine.Policy) (*engine.EvaluationResult, error) { + // Try the result rule first + res, err := queryRego(ctx, mainRule, module, options...) + if err != nil { return nil, err } - // If res is nil, it means that the rule hasn't been found - // TODO: Remove when this deprecated rule is not used anymore - if res == nil { - // Try with the deprecated main rule - if err := executeQuery(deprecatedRule, r.operatingMode == EnvironmentModeRestrictive); err != nil { - return nil, err - } + if res != nil { + return parseResultRule(res, policy) + } - if res == nil { - return nil, fmt.Errorf("failed to evaluate policy: neither '%s' nor '%s' rule found", mainRule, deprecatedRule) - } + // Fallback to deprecated violations rule + res, err = queryRego(ctx, deprecatedRule, module, options...) + if err != nil { + return nil, err + } + if res != nil { return parseViolationsRule(res, policy) } - return parseResultRule(res, policy) + return nil, fmt.Errorf("failed to evaluate policy: no results from package or rule evaluation") +} + +func queryRego(ctx context.Context, ruleName string, module *ast.Module, options ...func(*rego.Rego)) (rego.ResultSet, error) { + query := fmt.Sprintf("data.%s.%s", strings.TrimPrefix(module.Package.Path.String(), "data."), ruleName) + regoEval := rego.New(append(options, rego.Query(query))...) + return regoEval.Eval(ctx) } // Parse deprecated list of violations. @@ -207,12 +237,14 @@ func parseViolationsRule(res rego.ResultSet, policy *engine.Policy) (*engine.Eva Skipped: false, // best effort SkipReason: "", Ignore: false, // Assume old rules should not be ignored + RawResults: regoResultSetToRawResults(res), }, nil } // parse `result` rule func parseResultRule(res rego.ResultSet, policy *engine.Policy) (*engine.EvaluationResult, error) { result := &engine.EvaluationResult{Violations: make([]*engine.PolicyViolation, 0)} + result.RawResults = regoResultSetToRawResults(res) for _, exp := range res { for _, val := range exp.Expressions { ruleResult, ok := val.Value.(map[string]any) @@ -257,17 +289,6 @@ func parseResultRule(res rego.ResultSet, policy *engine.Policy) (*engine.Evaluat return result, nil } -func queryRego(ctx context.Context, ruleName string, parsedModule *ast.Module, options ...func(r *rego.Rego)) (rego.ResultSet, error) { - query := rego.Query(fmt.Sprintf("%v.%s\n", parsedModule.Package.Path, ruleName)) - regoEval := rego.New(append(options, query)...) - res, err := regoEval.Eval(ctx) - if err != nil { - return nil, fmt.Errorf("failed to evaluate policy: %w", err) - } - - return res, nil -} - // Capabilities returns the capabilities of the environment based on the mode of operation // defaulting to EnvironmentModeRestrictive if not provided. func (r *Engine) Capabilities() *ast.Capabilities { @@ -301,3 +322,15 @@ func (r *Engine) Capabilities() *ast.Capabilities { capabilities.Builtins = enabledBuiltin return capabilities } + +func regoResultSetToRawResults(res rego.ResultSet) []map[string]interface{} { + raw := make([]map[string]any, 0, len(res)) + for _, r := range res { + entry := make(map[string]any) + for _, exp := range r.Expressions { + entry[exp.Text] = exp.Value + } + raw = append(raw, entry) + } + return raw +} diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index 875f737ec..64f10faeb 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -32,6 +32,7 @@ import ( "github.com/sigstore/cosign/v2/pkg/blob" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/structpb" v1 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" v12 "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" @@ -165,6 +166,7 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme sources := make([]string, 0) evalResults := make([]*engine.EvaluationResult, 0) + rawResults := make([]map[string]interface{}, 0) skipped := true reasons := make([]string, 0) for _, script := range scripts { @@ -173,6 +175,8 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme return nil, NewPolicyError(err) } + rawResults = append(rawResults, r.RawResults...) + // Skip if the script explicitly instructs us to ignore it, effectively preventing it from being added to the evaluation results if r.Ignore { continue @@ -229,6 +233,7 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme // Merged "skip_reason" SkipReasons: reasons, Requirements: attachment.Requirements, + RawResults: engineRawResultsToAPIRawResults(rawResults), }, nil } @@ -659,3 +664,16 @@ func LogPolicyEvaluations(evaluations []*v12.PolicyEvaluation, logger *zerolog.L } } } + +func engineRawResultsToAPIRawResults(rawResults []map[string]interface{}) []*structpb.Struct { + res := make([]*structpb.Struct, 0) + for _, r := range rawResults { + s, err := structpb.NewStruct(r) + if err != nil { + // Skip invalid entries + continue + } + res = append(res, s) + } + return res +} From 5e5f99b8a13accc90b6f4868d58a383c5af60eb2 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 14 Aug 2025 09:56:20 +0200 Subject: [PATCH 02/15] add input info Signed-off-by: Sylwester Piskozub --- app/cli/cmd/policy_develop_eval.go | 8 +---- .../internal/action/policy_develop_eval.go | 2 ++ app/cli/internal/policydevel/eval.go | 10 ++++-- pkg/policies/engine/engine.go | 7 ++-- pkg/policies/engine/rego/rego.go | 32 +++++++++++-------- pkg/policies/policies.go | 15 ++++++--- 6 files changed, 44 insertions(+), 30 deletions(-) diff --git a/app/cli/cmd/policy_develop_eval.go b/app/cli/cmd/policy_develop_eval.go index 97695ed38..d1cae8389 100644 --- a/app/cli/cmd/policy_develop_eval.go +++ b/app/cli/cmd/policy_develop_eval.go @@ -52,6 +52,7 @@ evaluates the policy against the provided material or attestation.`, PolicyPath: policyPath, Inputs: parseKeyValue(inputs), AllowedHostnames: allowedHostnames, + Raw: raw, } policyEval, err := action.NewPolicyEval(opts, actionOpts) @@ -64,13 +65,6 @@ evaluates the policy against the provided material or attestation.`, return err } - if raw { - return encodeJSON(result[0].RawResults) - } - - // Hide skip reasons in non-verbose mode - result[0].RawResults = nil - return encodeJSON(result) }, } diff --git a/app/cli/internal/action/policy_develop_eval.go b/app/cli/internal/action/policy_develop_eval.go index 0c3e43d53..7df08997c 100644 --- a/app/cli/internal/action/policy_develop_eval.go +++ b/app/cli/internal/action/policy_develop_eval.go @@ -26,6 +26,7 @@ type PolicyEvalOpts struct { PolicyPath string Inputs map[string]string AllowedHostnames []string + Raw bool } type PolicyEvalResult struct { @@ -56,6 +57,7 @@ func (action *PolicyEval) Run() ([]*PolicyEvalResult, error) { MaterialPath: action.opts.MaterialPath, Inputs: action.opts.Inputs, AllowedHostnames: action.opts.AllowedHostnames, + Raw: action.opts.Raw, } // Evaluate policy diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index cc481f07b..671095f23 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -36,6 +36,7 @@ type EvalOptions struct { MaterialPath string Inputs map[string]string AllowedHostnames []string + Raw bool } type EvalResult struct { @@ -61,7 +62,7 @@ func Evaluate(opts *EvalOptions, logger zerolog.Logger) ([]*EvalResult, error) { material.Annotations = opts.Annotations // 3. Verify material against policy - result, err := verifyMaterial(schema, material, opts.MaterialPath, opts.AllowedHostnames, &logger) + result, err := verifyMaterial(schema, material, opts.MaterialPath, opts.Raw, opts.AllowedHostnames, &logger) if err != nil { return nil, err } @@ -84,7 +85,7 @@ func createCraftingSchema(policyPath string, inputs map[string]string) (*v1.Craf }, nil } -func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Material, materialPath string, allowedHostnames []string, logger *zerolog.Logger) ([]*EvalResult, error) { +func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Material, materialPath string, raw bool, allowedHostnames []string, logger *zerolog.Logger) ([]*EvalResult, error) { var opts []policies.PolicyVerifierOption if len(allowedHostnames) > 0 { opts = append(opts, policies.WithAllowedHostnames(allowedHostnames...)) @@ -106,7 +107,10 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia Skipped: policyEv.GetSkipped(), SkipReasons: policyEv.SkipReasons, Ignored: false, - RawResults: apiRawResultsToEngineRawResults(policyEv.RawResults), + } + + if raw { + result.RawResults = apiRawResultsToEngineRawResults(policyEv.RawResults) } // Collect all violation messages diff --git a/pkg/policies/engine/engine.go b/pkg/policies/engine/engine.go index c832912f3..5a198854e 100644 --- a/pkg/policies/engine/engine.go +++ b/pkg/policies/engine/engine.go @@ -30,8 +30,11 @@ type EvaluationResult struct { Skipped bool SkipReason string Ignore bool - // contains the raw results from the policy engine - RawResults []map[string]interface{} + RawData *RawData +} +type RawData struct { + Input interface{} + Output map[string]interface{} } // PolicyViolation represents a policy failure diff --git a/pkg/policies/engine/rego/rego.go b/pkg/policies/engine/rego/rego.go index 59de21fcb..d9a1baf17 100644 --- a/pkg/policies/engine/rego/rego.go +++ b/pkg/policies/engine/rego/rego.go @@ -163,11 +163,11 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte // If we got results, parse them if res != nil { - return parseResultRule(res, policy) + return parseResultRule(res, policy, decodedInput) } // Fallback to evaluating specific rules if package evaluation returned nothing - return r.evaluateSpecificRules(ctx, parsedModule, options, policy) + return r.evaluateSpecificRules(ctx, parsedModule, options, policy, decodedInput) } // Evaluate the entire package by querying data. @@ -177,7 +177,7 @@ func (r *Engine) evaluatePackage(ctx context.Context, pkgPath string, options [] return regoEval.Eval(ctx) } -func (r *Engine) evaluateSpecificRules(ctx context.Context, module *ast.Module, options []func(*rego.Rego), policy *engine.Policy) (*engine.EvaluationResult, error) { +func (r *Engine) evaluateSpecificRules(ctx context.Context, module *ast.Module, options []func(*rego.Rego), policy *engine.Policy, decodedInput interface{}) (*engine.EvaluationResult, error) { // Try the result rule first res, err := queryRego(ctx, mainRule, module, options...) if err != nil { @@ -185,7 +185,7 @@ func (r *Engine) evaluateSpecificRules(ctx context.Context, module *ast.Module, } if res != nil { - return parseResultRule(res, policy) + return parseResultRule(res, policy, decodedInput) } // Fallback to deprecated violations rule @@ -195,7 +195,7 @@ func (r *Engine) evaluateSpecificRules(ctx context.Context, module *ast.Module, } if res != nil { - return parseViolationsRule(res, policy) + return parseViolationsRule(res, policy, decodedInput) } return nil, fmt.Errorf("failed to evaluate policy: no results from package or rule evaluation") @@ -209,7 +209,7 @@ func queryRego(ctx context.Context, ruleName string, module *ast.Module, options // Parse deprecated list of violations. // TODO: Remove this path once `result` rule is consolidated -func parseViolationsRule(res rego.ResultSet, policy *engine.Policy) (*engine.EvaluationResult, error) { +func parseViolationsRule(res rego.ResultSet, policy *engine.Policy, decodedInput interface{}) (*engine.EvaluationResult, error) { violations := make([]*engine.PolicyViolation, 0) for _, exp := range res { for _, val := range exp.Expressions { @@ -237,14 +237,20 @@ func parseViolationsRule(res rego.ResultSet, policy *engine.Policy) (*engine.Eva Skipped: false, // best effort SkipReason: "", Ignore: false, // Assume old rules should not be ignored - RawResults: regoResultSetToRawResults(res), + RawData: &engine.RawData{ + Input: decodedInput, + Output: regoResultSetToRawResults(res), + }, }, nil } // parse `result` rule -func parseResultRule(res rego.ResultSet, policy *engine.Policy) (*engine.EvaluationResult, error) { +func parseResultRule(res rego.ResultSet, policy *engine.Policy, decodedInput interface{}) (*engine.EvaluationResult, error) { result := &engine.EvaluationResult{Violations: make([]*engine.PolicyViolation, 0)} - result.RawResults = regoResultSetToRawResults(res) + result.RawData = &engine.RawData{ + Input: decodedInput, + Output: regoResultSetToRawResults(res), + } for _, exp := range res { for _, val := range exp.Expressions { ruleResult, ok := val.Value.(map[string]any) @@ -323,14 +329,14 @@ func (r *Engine) Capabilities() *ast.Capabilities { return capabilities } -func regoResultSetToRawResults(res rego.ResultSet) []map[string]interface{} { - raw := make([]map[string]any, 0, len(res)) +func regoResultSetToRawResults(res rego.ResultSet) map[string]interface{} { + raw := make(map[string]interface{}) for _, r := range res { - entry := make(map[string]any) + entry := make(map[string]interface{}) for _, exp := range r.Expressions { entry[exp.Text] = exp.Value } - raw = append(raw, entry) + raw = entry } return raw } diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index 64f10faeb..daf9bd774 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -166,7 +166,7 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme sources := make([]string, 0) evalResults := make([]*engine.EvaluationResult, 0) - rawResults := make([]map[string]interface{}, 0) + rawResults := make([]*engine.RawData, 0) skipped := true reasons := make([]string, 0) for _, script := range scripts { @@ -175,7 +175,7 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme return nil, NewPolicyError(err) } - rawResults = append(rawResults, r.RawResults...) + rawResults = append(rawResults, r.RawData) // Skip if the script explicitly instructs us to ignore it, effectively preventing it from being added to the evaluation results if r.Ignore { @@ -665,12 +665,17 @@ func LogPolicyEvaluations(evaluations []*v12.PolicyEvaluation, logger *zerolog.L } } -func engineRawResultsToAPIRawResults(rawResults []map[string]interface{}) []*structpb.Struct { +func engineRawResultsToAPIRawResults(rawResults []*engine.RawData) []*structpb.Struct { res := make([]*structpb.Struct, 0) for _, r := range rawResults { - s, err := structpb.NewStruct(r) + // Convert RawData to map + m := map[string]interface{}{ + "input": r.Input, + "output": r.Output, + } + + s, err := structpb.NewStruct(m) if err != nil { - // Skip invalid entries continue } res = append(res, s) From 45c927a9d810e70a780a395dcb4b320151587847 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 14 Aug 2025 13:23:25 +0200 Subject: [PATCH 03/15] add formated output Signed-off-by: Sylwester Piskozub --- app/cli/cmd/policy_develop_eval.go | 11 ++-- .../internal/action/policy_develop_eval.go | 19 ++---- app/cli/internal/policydevel/eval.go | 65 ++++++++++++------- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/app/cli/cmd/policy_develop_eval.go b/app/cli/cmd/policy_develop_eval.go index d1cae8389..8e4db66a2 100644 --- a/app/cli/cmd/policy_develop_eval.go +++ b/app/cli/cmd/policy_develop_eval.go @@ -32,7 +32,7 @@ func newPolicyDevelopEvalCmd() *cobra.Command { policyPath string inputs []string allowedHostnames []string - raw bool + debug bool ) cmd := &cobra.Command{ @@ -52,7 +52,7 @@ evaluates the policy against the provided material or attestation.`, PolicyPath: policyPath, Inputs: parseKeyValue(inputs), AllowedHostnames: allowedHostnames, - Raw: raw, + Debug: debug, } policyEval, err := action.NewPolicyEval(opts, actionOpts) @@ -64,8 +64,11 @@ evaluates the policy against the provided material or attestation.`, if err != nil { return err } + if debug { + return encodeJSON(result) + } - return encodeJSON(result) + return encodeJSON(result.Result) }, } @@ -76,7 +79,7 @@ evaluates the policy against the provided material or attestation.`, cmd.Flags().StringVarP(&policyPath, "policy", "p", "policy.yaml", "Path to custom policy file") cmd.Flags().StringSliceVar(&inputs, "input", []string{}, "Key-value pairs of policy inputs (key=value)") cmd.Flags().StringSliceVar(&allowedHostnames, "allowed-hostnames", []string{}, "Additional hostnames allowed for http.send requests in policies") - cmd.Flags().BoolVarP(&raw, "raw", "", false, "Enable raw output") + cmd.Flags().BoolVarP(&debug, "debug", "", false, "Enable debug/verbose output and logging mode") return cmd } diff --git a/app/cli/internal/action/policy_develop_eval.go b/app/cli/internal/action/policy_develop_eval.go index 7df08997c..0bf223754 100644 --- a/app/cli/internal/action/policy_develop_eval.go +++ b/app/cli/internal/action/policy_develop_eval.go @@ -26,7 +26,7 @@ type PolicyEvalOpts struct { PolicyPath string Inputs map[string]string AllowedHostnames []string - Raw bool + Debug bool } type PolicyEvalResult struct { @@ -49,7 +49,7 @@ func NewPolicyEval(opts *PolicyEvalOpts, actionOpts *ActionsOpts) (*PolicyEval, }, nil } -func (action *PolicyEval) Run() ([]*PolicyEvalResult, error) { +func (action *PolicyEval) Run() (*policydevel.EvalSummary, error) { evalOpts := &policydevel.EvalOptions{ PolicyPath: action.opts.PolicyPath, MaterialKind: action.opts.Kind, @@ -57,7 +57,7 @@ func (action *PolicyEval) Run() ([]*PolicyEvalResult, error) { MaterialPath: action.opts.MaterialPath, Inputs: action.opts.Inputs, AllowedHostnames: action.opts.AllowedHostnames, - Raw: action.opts.Raw, + Debug: action.opts.Debug, } // Evaluate policy @@ -66,16 +66,5 @@ func (action *PolicyEval) Run() ([]*PolicyEvalResult, error) { return nil, err } - results := make([]*PolicyEvalResult, 0, len(resp)) - for _, r := range resp { - results = append(results, &PolicyEvalResult{ - Violations: r.Violations, - SkipReasons: r.SkipReasons, - Skipped: r.Skipped, - Ignored: r.Ignored, - RawResults: r.RawResults, - }) - } - - return results, nil + return resp, nil } diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index 671095f23..40c94e52e 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -36,18 +36,26 @@ type EvalOptions struct { MaterialPath string Inputs map[string]string AllowedHostnames []string - Raw bool + Debug bool } type EvalResult struct { Skipped bool SkipReasons []string Violations []string - Ignored bool - RawResults []map[string]interface{} } -func Evaluate(opts *EvalOptions, logger zerolog.Logger) ([]*EvalResult, error) { +type EvalSummary struct { + Result EvalResult `json:"result"` + DebugInfo EvalSummaryDebugInfo `json:"debug_info"` +} + +type EvalSummaryDebugInfo struct { + Inputs []map[string]interface{} `json:"inputs"` + RawResults []map[string]interface{} `json:"raw_results"` +} + +func Evaluate(opts *EvalOptions, logger zerolog.Logger) (*EvalSummary, error) { // 1. Create crafting schema schema, err := createCraftingSchema(opts.PolicyPath, opts.Inputs) if err != nil { @@ -62,12 +70,12 @@ func Evaluate(opts *EvalOptions, logger zerolog.Logger) ([]*EvalResult, error) { material.Annotations = opts.Annotations // 3. Verify material against policy - result, err := verifyMaterial(schema, material, opts.MaterialPath, opts.Raw, opts.AllowedHostnames, &logger) + summary, err := verifyMaterial(schema, material, opts.MaterialPath, opts.Debug, opts.AllowedHostnames, &logger) if err != nil { return nil, err } - return result, nil + return summary, nil } func createCraftingSchema(policyPath string, inputs map[string]string) (*v1.CraftingSchema, error) { @@ -85,7 +93,7 @@ func createCraftingSchema(policyPath string, inputs map[string]string) (*v1.Craf }, nil } -func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Material, materialPath string, raw bool, allowedHostnames []string, logger *zerolog.Logger) ([]*EvalResult, error) { +func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Material, materialPath string, debug bool, allowedHostnames []string, logger *zerolog.Logger) (*EvalSummary, error) { var opts []policies.PolicyVerifierOption if len(allowedHostnames) > 0 { opts = append(opts, policies.WithAllowedHostnames(allowedHostnames...)) @@ -96,34 +104,43 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia return nil, err } - // no evaluations were returned if len(policyEvs) == 0 { return nil, fmt.Errorf("no execution branch matched for kind %s", material.MaterialType.String()) } - results := make([]*EvalResult, 0, len(policyEvs)) - for _, policyEv := range policyEvs { - result := &EvalResult{ + // Only one evaluation expected for a single policy attachment + policyEv := policyEvs[0] + + summary := &EvalSummary{ + Result: EvalResult{ Skipped: policyEv.GetSkipped(), SkipReasons: policyEv.SkipReasons, - Ignored: false, - } + Violations: make([]string, 0, len(policyEv.Violations)), + }, + DebugInfo: EvalSummaryDebugInfo{ + Inputs: []map[string]interface{}{}, + RawResults: []map[string]interface{}{}, + }, + } - if raw { - result.RawResults = apiRawResultsToEngineRawResults(policyEv.RawResults) - } + // Collect violation messages + for _, v := range policyEv.Violations { + summary.Result.Violations = append(summary.Result.Violations, v.Message) + } - // Collect all violation messages - violations := make([]string, 0, len(policyEv.Violations)) - for _, v := range policyEv.Violations { - violations = append(violations, v.Message) + // Include raw debug info if requested + if debug { + for _, rr := range apiRawResultsToEngineRawResults(policyEv.RawResults) { + if in, ok := rr["input"].(map[string]interface{}); ok { + summary.DebugInfo.Inputs = append(summary.DebugInfo.Inputs, in) + } + if out, ok := rr["output"].(map[string]interface{}); ok { + summary.DebugInfo.RawResults = append(summary.DebugInfo.RawResults, out) + } } - result.Violations = violations - - results = append(results, result) } - return results, nil + return summary, nil } func craftMaterial(materialPath, materialKind string, logger *zerolog.Logger) (*v12.Attestation_Material, error) { From d844a693ce20b2ca7e1806516a51327426d3b511 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 14 Aug 2025 13:26:40 +0200 Subject: [PATCH 04/15] fix tests Signed-off-by: Sylwester Piskozub --- app/cli/internal/policydevel/eval_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/cli/internal/policydevel/eval_test.go b/app/cli/internal/policydevel/eval_test.go index 587d63253..ac62bee3b 100644 --- a/app/cli/internal/policydevel/eval_test.go +++ b/app/cli/internal/policydevel/eval_test.go @@ -55,14 +55,14 @@ func TestEvaluate(t *testing.T) { Annotations: map[string]string{"key": "value"}, } - results, err := Evaluate(opts, logger) + result, err := Evaluate(opts, logger) require.NoError(t, err) - require.NotEmpty(t, results) + require.NotNil(t, result) - if len(results[0].Violations) == 0 { + if len(result.Result.Violations) == 0 { t.Log("Policy evaluation passed (no violations)") } else { - for _, violation := range results[0].Violations { + for _, violation := range result.Result.Violations { t.Logf("Violation: %s", violation) } } @@ -78,14 +78,14 @@ func TestEvaluate(t *testing.T) { Annotations: map[string]string{"key": "value"}, } - results, err := Evaluate(opts, logger) + result, err := Evaluate(opts, logger) require.NoError(t, err) - require.NotEmpty(t, results) + require.NotNil(t, result) - if len(results[0].Violations) == 0 { + if len(result.Result.Violations) == 0 { t.Log("Policy evaluation passed (no violations)") } else { - for _, violation := range results[0].Violations { + for _, violation := range result.Result.Violations { t.Logf("Violation: %s", violation) } } From 4c7a319c60c010164dc9a2f58837911b9dcb836b Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 14 Aug 2025 13:32:55 +0200 Subject: [PATCH 05/15] fix lint and gen ref Signed-off-by: Sylwester Piskozub --- app/cli/documentation/cli-reference.mdx | 2 +- pkg/attestation/crafter/api/attestation/v1/crafting_state.proto | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/cli/documentation/cli-reference.mdx b/app/cli/documentation/cli-reference.mdx index bc59f8b2a..69e78d527 100755 --- a/app/cli/documentation/cli-reference.mdx +++ b/app/cli/documentation/cli-reference.mdx @@ -2847,6 +2847,7 @@ Options ``` --allowed-hostnames strings Additional hostnames allowed for http.send requests in policies --annotation strings Key-value pairs of material annotations (key=value) +--debug Enable debug/verbose output and logging mode -h, --help help for eval --input strings 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"] @@ -2862,7 +2863,6 @@ Options inherited from parent commands -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") diff --git a/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto b/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto index f8293fcc2..977248a91 100644 --- a/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto +++ b/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto @@ -272,7 +272,7 @@ message PolicyEvaluation { string org_name = 4; } - repeated google.protobuf.Struct raw_results = 19; + repeated google.protobuf.Struct raw_results = 19; } message Commit { From c3001cf79585f73643d823cd30ae8eb1c59094af Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 14 Aug 2025 15:06:15 +0200 Subject: [PATCH 06/15] fix tests Signed-off-by: Sylwester Piskozub --- pkg/policies/engine/rego/rego.go | 117 ++++++++++++++----------------- 1 file changed, 51 insertions(+), 66 deletions(-) diff --git a/pkg/policies/engine/rego/rego.go b/pkg/policies/engine/rego/rego.go index d9a1baf17..c0a38a5b0 100644 --- a/pkg/policies/engine/rego/rego.go +++ b/pkg/policies/engine/rego/rego.go @@ -20,7 +20,6 @@ import ( "context" "encoding/json" "fmt" - "strings" "github.com/chainloop-dev/chainloop/pkg/policies/engine" "github.com/open-policy-agent/opa/ast" @@ -92,8 +91,8 @@ const ( EnvironmentModePermissive EnvironmentMode = 1 inputArgs = "args" inputElements = "elements" - deprecatedRule = "violations" - mainRule = "result" + deprecatedRule = ".violations" + mainRule = ".result" ) // builtinFuncNotAllowed is a list of builtin functions that are not allowed in the compiler @@ -113,12 +112,6 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte return nil, fmt.Errorf("failed to parse rego policy: %w", err) } - // Extract package name - pkgPath := parsedModule.Package.Path.String() - if pkgPath == "" { - return nil, fmt.Errorf("policy has no package declaration") - } - // Decode input as json decoder := json.NewDecoder(bytes.NewReader(input)) decoder.UseNumber() @@ -134,7 +127,7 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte decodedInput = inputMap } - // put arguments embedded in the input + // put arguments embedded in the input object if args != nil { inputMap, ok := decodedInput.(map[string]interface{}) if !ok { @@ -144,72 +137,59 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte decodedInput = inputMap } - // Prepare rego options - options := []func(*rego.Rego){ - rego.ParsedModule(parsedModule), - rego.Input(decodedInput), - rego.Capabilities(r.Capabilities()), - } + // add input + regoInput := rego.Input(decodedInput) + + // add module + regoFunc := rego.ParsedModule(parsedModule) - if r.operatingMode == EnvironmentModeRestrictive { - options = append(options, rego.StrictBuiltinErrors(true)) + var res rego.ResultSet + // Function to execute the query with appropriate parameters + executeQuery := func(rule string, strict bool) error { + if strict { + res, err = queryRego(ctx, rule, parsedModule, regoInput, regoFunc, rego.Capabilities(r.Capabilities()), rego.StrictBuiltinErrors(true)) + } else { + res, err = queryRego(ctx, rule, parsedModule, regoInput, regoFunc, rego.Capabilities(r.Capabilities())) + } + return err } - // First try evaluating the entire package - res, err := r.evaluatePackage(ctx, pkgPath, options) - if err != nil { + // Get raw results first + if err := executeQuery("", r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } - // If we got results, parse them - if res != nil { - return parseResultRule(res, policy, decodedInput) + rawData := &engine.RawData{ + Input: decodedInput, + Output: regoResultSetToRawResults(res), } - // Fallback to evaluating specific rules if package evaluation returned nothing - return r.evaluateSpecificRules(ctx, parsedModule, options, policy, decodedInput) -} - -// Evaluate the entire package by querying data. -func (r *Engine) evaluatePackage(ctx context.Context, pkgPath string, options []func(*rego.Rego)) (rego.ResultSet, error) { - query := fmt.Sprintf("data.%s", strings.TrimPrefix(pkgPath, "data.")) - regoEval := rego.New(append(options, rego.Query(query))...) - return regoEval.Eval(ctx) -} - -func (r *Engine) evaluateSpecificRules(ctx context.Context, module *ast.Module, options []func(*rego.Rego), policy *engine.Policy, decodedInput interface{}) (*engine.EvaluationResult, error) { - // Try the result rule first - res, err := queryRego(ctx, mainRule, module, options...) - if err != nil { + // Try the main rule first + if err := executeQuery(mainRule, r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } - if res != nil { - return parseResultRule(res, policy, decodedInput) - } + // If res is nil, it means that the rule hasn't been found + // TODO: Remove when this deprecated rule is not used anymore + if res == nil { + // Try with the deprecated main rule + if err := executeQuery(deprecatedRule, r.operatingMode == EnvironmentModeRestrictive); err != nil { + return nil, err + } - // Fallback to deprecated violations rule - res, err = queryRego(ctx, deprecatedRule, module, options...) - if err != nil { - return nil, err - } + if res == nil { + return nil, fmt.Errorf("failed to evaluate policy: neither '%s' nor '%s' rule found", mainRule, deprecatedRule) + } - if res != nil { - return parseViolationsRule(res, policy, decodedInput) + return parseViolationsRule(res, policy, rawData) } - return nil, fmt.Errorf("failed to evaluate policy: no results from package or rule evaluation") -} - -func queryRego(ctx context.Context, ruleName string, module *ast.Module, options ...func(*rego.Rego)) (rego.ResultSet, error) { - query := fmt.Sprintf("data.%s.%s", strings.TrimPrefix(module.Package.Path.String(), "data."), ruleName) - regoEval := rego.New(append(options, rego.Query(query))...) - return regoEval.Eval(ctx) + return parseResultRule(res, policy, rawData) } // Parse deprecated list of violations. // TODO: Remove this path once `result` rule is consolidated -func parseViolationsRule(res rego.ResultSet, policy *engine.Policy, decodedInput interface{}) (*engine.EvaluationResult, error) { +func parseViolationsRule(res rego.ResultSet, policy *engine.Policy, rawData *engine.RawData) (*engine.EvaluationResult, error) { violations := make([]*engine.PolicyViolation, 0) for _, exp := range res { for _, val := range exp.Expressions { @@ -237,20 +217,14 @@ func parseViolationsRule(res rego.ResultSet, policy *engine.Policy, decodedInput Skipped: false, // best effort SkipReason: "", Ignore: false, // Assume old rules should not be ignored - RawData: &engine.RawData{ - Input: decodedInput, - Output: regoResultSetToRawResults(res), - }, + RawData: rawData, }, nil } // parse `result` rule -func parseResultRule(res rego.ResultSet, policy *engine.Policy, decodedInput interface{}) (*engine.EvaluationResult, error) { +func parseResultRule(res rego.ResultSet, policy *engine.Policy, rawData *engine.RawData) (*engine.EvaluationResult, error) { result := &engine.EvaluationResult{Violations: make([]*engine.PolicyViolation, 0)} - result.RawData = &engine.RawData{ - Input: decodedInput, - Output: regoResultSetToRawResults(res), - } + result.RawData = rawData for _, exp := range res { for _, val := range exp.Expressions { ruleResult, ok := val.Value.(map[string]any) @@ -295,6 +269,17 @@ func parseResultRule(res rego.ResultSet, policy *engine.Policy, decodedInput int return result, nil } +func queryRego(ctx context.Context, ruleName string, parsedModule *ast.Module, options ...func(r *rego.Rego)) (rego.ResultSet, error) { + query := rego.Query(fmt.Sprintf("%v%s\n", parsedModule.Package.Path, ruleName)) + regoEval := rego.New(append(options, query)...) + res, err := regoEval.Eval(ctx) + if err != nil { + return nil, fmt.Errorf("failed to evaluate policy: %w", err) + } + + return res, nil +} + // Capabilities returns the capabilities of the environment based on the mode of operation // defaulting to EnvironmentModeRestrictive if not provided. func (r *Engine) Capabilities() *ast.Capabilities { From 42055c693577b01239e4f6b3e358f000d207fba2 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Thu, 14 Aug 2025 15:18:01 +0200 Subject: [PATCH 07/15] fix tests Signed-off-by: Sylwester Piskozub --- pkg/policies/engine/rego/rego.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/policies/engine/rego/rego.go b/pkg/policies/engine/rego/rego.go index c0a38a5b0..0164f58bf 100644 --- a/pkg/policies/engine/rego/rego.go +++ b/pkg/policies/engine/rego/rego.go @@ -91,8 +91,8 @@ const ( EnvironmentModePermissive EnvironmentMode = 1 inputArgs = "args" inputElements = "elements" - deprecatedRule = ".violations" - mainRule = ".result" + deprecatedRule = "violations" + mainRule = "result" ) // builtinFuncNotAllowed is a list of builtin functions that are not allowed in the compiler @@ -155,7 +155,7 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte } // Get raw results first - if err := executeQuery("", r.operatingMode == EnvironmentModeRestrictive); err != nil { + if err := executeQuery(fmt.Sprintf("%s\n", parsedModule.Package.Path), r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } @@ -165,7 +165,7 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte } // Try the main rule first - if err := executeQuery(mainRule, r.operatingMode == EnvironmentModeRestrictive); err != nil { + if err := executeQuery(fmt.Sprintf("%v.%s\n", parsedModule.Package.Path, mainRule), r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } @@ -173,7 +173,7 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte // TODO: Remove when this deprecated rule is not used anymore if res == nil { // Try with the deprecated main rule - if err := executeQuery(deprecatedRule, r.operatingMode == EnvironmentModeRestrictive); err != nil { + if err := executeQuery(fmt.Sprintf("%v.%s\n", parsedModule.Package.Path, deprecatedRule), r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } @@ -269,8 +269,8 @@ func parseResultRule(res rego.ResultSet, policy *engine.Policy, rawData *engine. return result, nil } -func queryRego(ctx context.Context, ruleName string, parsedModule *ast.Module, options ...func(r *rego.Rego)) (rego.ResultSet, error) { - query := rego.Query(fmt.Sprintf("%v%s\n", parsedModule.Package.Path, ruleName)) +func queryRego(ctx context.Context, fullRuleName string, parsedModule *ast.Module, options ...func(r *rego.Rego)) (rego.ResultSet, error) { + query := rego.Query(fullRuleName) regoEval := rego.New(append(options, query)...) res, err := regoEval.Eval(ctx) if err != nil { From 768b0d202d32e176300672be168cd05e71ceec03 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Sun, 17 Aug 2025 21:24:08 +0200 Subject: [PATCH 08/15] fix linter Signed-off-by: Sylwester Piskozub --- pkg/policies/engine/rego/rego.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/policies/engine/rego/rego.go b/pkg/policies/engine/rego/rego.go index 0164f58bf..13c117455 100644 --- a/pkg/policies/engine/rego/rego.go +++ b/pkg/policies/engine/rego/rego.go @@ -147,9 +147,9 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte // Function to execute the query with appropriate parameters executeQuery := func(rule string, strict bool) error { if strict { - res, err = queryRego(ctx, rule, parsedModule, regoInput, regoFunc, rego.Capabilities(r.Capabilities()), rego.StrictBuiltinErrors(true)) + res, err = queryRego(ctx, rule, regoInput, regoFunc, rego.Capabilities(r.Capabilities()), rego.StrictBuiltinErrors(true)) } else { - res, err = queryRego(ctx, rule, parsedModule, regoInput, regoFunc, rego.Capabilities(r.Capabilities())) + res, err = queryRego(ctx, rule, regoInput, regoFunc, rego.Capabilities(r.Capabilities())) } return err } @@ -269,7 +269,7 @@ func parseResultRule(res rego.ResultSet, policy *engine.Policy, rawData *engine. return result, nil } -func queryRego(ctx context.Context, fullRuleName string, parsedModule *ast.Module, options ...func(r *rego.Rego)) (rego.ResultSet, error) { +func queryRego(ctx context.Context, fullRuleName string, options ...func(r *rego.Rego)) (rego.ResultSet, error) { query := rego.Query(fullRuleName) regoEval := rego.New(append(options, query)...) res, err := regoEval.Eval(ctx) From b8e9fa36b2c3c7ccfead46cb5fc9e68a3c6de0e9 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Mon, 18 Aug 2025 09:38:25 +0200 Subject: [PATCH 09/15] show only one input Signed-off-by: Sylwester Piskozub --- app/cli/internal/policydevel/eval.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index 40c94e52e..caf778e5f 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -132,7 +132,10 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia if debug { for _, rr := range apiRawResultsToEngineRawResults(policyEv.RawResults) { if in, ok := rr["input"].(map[string]interface{}); ok { - summary.DebugInfo.Inputs = append(summary.DebugInfo.Inputs, in) + // Take the first input found, as we only allow one material input + if len(summary.DebugInfo.Inputs) == 0 { + summary.DebugInfo.Inputs = append(summary.DebugInfo.Inputs, in) + } } if out, ok := rr["output"].(map[string]interface{}); ok { summary.DebugInfo.RawResults = append(summary.DebugInfo.RawResults, out) From 4e4a6e25560940d69847a4a514549be4ed6a1bfb Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Mon, 18 Aug 2025 09:53:32 +0200 Subject: [PATCH 10/15] fix non debug output Signed-off-by: Sylwester Piskozub --- app/cli/cmd/policy_develop_eval.go | 5 +---- app/cli/internal/policydevel/eval.go | 15 ++++++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/app/cli/cmd/policy_develop_eval.go b/app/cli/cmd/policy_develop_eval.go index 8e4db66a2..8fab360a3 100644 --- a/app/cli/cmd/policy_develop_eval.go +++ b/app/cli/cmd/policy_develop_eval.go @@ -64,11 +64,8 @@ evaluates the policy against the provided material or attestation.`, if err != nil { return err } - if debug { - return encodeJSON(result) - } - return encodeJSON(result.Result) + return encodeJSON(result) }, } diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index caf778e5f..ea096b2ec 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -46,8 +46,8 @@ type EvalResult struct { } type EvalSummary struct { - Result EvalResult `json:"result"` - DebugInfo EvalSummaryDebugInfo `json:"debug_info"` + Result *EvalResult `json:"result"` + DebugInfo *EvalSummaryDebugInfo `json:"debug_info,omitempty"` } type EvalSummaryDebugInfo struct { @@ -112,15 +112,11 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia policyEv := policyEvs[0] summary := &EvalSummary{ - Result: EvalResult{ + Result: &EvalResult{ Skipped: policyEv.GetSkipped(), SkipReasons: policyEv.SkipReasons, Violations: make([]string, 0, len(policyEv.Violations)), }, - DebugInfo: EvalSummaryDebugInfo{ - Inputs: []map[string]interface{}{}, - RawResults: []map[string]interface{}{}, - }, } // Collect violation messages @@ -130,6 +126,11 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia // Include raw debug info if requested if debug { + summary.DebugInfo = &EvalSummaryDebugInfo{ + Inputs: []map[string]interface{}{}, + RawResults: []map[string]interface{}{}, + } + for _, rr := range apiRawResultsToEngineRawResults(policyEv.RawResults) { if in, ok := rr["input"].(map[string]interface{}); ok { // Take the first input found, as we only allow one material input From be9dc9460424e970c7aaaf0f6ac1d5deb936d9c3 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Tue, 19 Aug 2025 13:35:40 +0200 Subject: [PATCH 11/15] fix json keys; extract rego get rule name function; update debug flag desc Signed-off-by: Sylwester Piskozub --- app/cli/cmd/output.go | 1 - app/cli/cmd/policy_develop_eval.go | 2 +- app/cli/internal/action/policy_develop_eval.go | 8 -------- app/cli/internal/policydevel/eval.go | 6 +++--- pkg/policies/engine/rego/rego.go | 13 ++++++++++--- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/app/cli/cmd/output.go b/app/cli/cmd/output.go index 2a391c72a..a7f4d1434 100644 --- a/app/cli/cmd/output.go +++ b/app/cli/cmd/output.go @@ -55,7 +55,6 @@ type tabulatedData interface { []*action.APITokenItem | *action.AttestationStatusMaterial | *action.ListMembershipResult | - *action.PolicyEvalResult | *action.PolicyLintResult } diff --git a/app/cli/cmd/policy_develop_eval.go b/app/cli/cmd/policy_develop_eval.go index 8fab360a3..10d98cd2f 100644 --- a/app/cli/cmd/policy_develop_eval.go +++ b/app/cli/cmd/policy_develop_eval.go @@ -76,7 +76,7 @@ evaluates the policy against the provided material or attestation.`, cmd.Flags().StringVarP(&policyPath, "policy", "p", "policy.yaml", "Path to custom policy file") cmd.Flags().StringSliceVar(&inputs, "input", []string{}, "Key-value pairs of policy inputs (key=value)") cmd.Flags().StringSliceVar(&allowedHostnames, "allowed-hostnames", []string{}, "Additional hostnames allowed for http.send requests in policies") - cmd.Flags().BoolVarP(&debug, "debug", "", false, "Enable debug/verbose output and logging mode") + cmd.Flags().BoolVarP(&debug, "debug", "", false, "Include detailed evaluation inputs/outputs in JSON output and enable verbose logging") return cmd } diff --git a/app/cli/internal/action/policy_develop_eval.go b/app/cli/internal/action/policy_develop_eval.go index 0bf223754..708e28446 100644 --- a/app/cli/internal/action/policy_develop_eval.go +++ b/app/cli/internal/action/policy_develop_eval.go @@ -29,14 +29,6 @@ type PolicyEvalOpts struct { Debug bool } -type PolicyEvalResult struct { - Violations []string `json:"violations"` - SkipReasons []string `json:"skip_reasons"` - Skipped bool `json:"skipped"` - Ignored bool `json:"ignored,omitempty"` - RawResults []map[string]interface{} `json:"raw_results,omitempty"` -} - type PolicyEval struct { *ActionsOpts opts *PolicyEvalOpts diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index ea096b2ec..754890a89 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -40,9 +40,9 @@ type EvalOptions struct { } type EvalResult struct { - Skipped bool - SkipReasons []string - Violations []string + Violations []string `json:"violations"` + SkipReasons []string `json:"skip_reasons"` + Skipped bool `json:"skipped"` } type EvalSummary struct { diff --git a/pkg/policies/engine/rego/rego.go b/pkg/policies/engine/rego/rego.go index 13c117455..b5706ca0e 100644 --- a/pkg/policies/engine/rego/rego.go +++ b/pkg/policies/engine/rego/rego.go @@ -155,7 +155,7 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte } // Get raw results first - if err := executeQuery(fmt.Sprintf("%s\n", parsedModule.Package.Path), r.operatingMode == EnvironmentModeRestrictive); err != nil { + if err := executeQuery(getRuleName(parsedModule.Package.Path, ""), r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } @@ -165,7 +165,7 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte } // Try the main rule first - if err := executeQuery(fmt.Sprintf("%v.%s\n", parsedModule.Package.Path, mainRule), r.operatingMode == EnvironmentModeRestrictive); err != nil { + if err := executeQuery(getRuleName(parsedModule.Package.Path, mainRule), r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } @@ -173,7 +173,7 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte // TODO: Remove when this deprecated rule is not used anymore if res == nil { // Try with the deprecated main rule - if err := executeQuery(fmt.Sprintf("%v.%s\n", parsedModule.Package.Path, deprecatedRule), r.operatingMode == EnvironmentModeRestrictive); err != nil { + if err := executeQuery(getRuleName(parsedModule.Package.Path, deprecatedRule), r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } @@ -325,3 +325,10 @@ func regoResultSetToRawResults(res rego.ResultSet) map[string]interface{} { } return raw } + +func getRuleName(packagePath ast.Ref, rule string) string { + if rule == "" { + return fmt.Sprintf("%s\n", packagePath) + } + return fmt.Sprintf("%v.%s\n", packagePath, rule) +} From b1a71ca2dac47ae2afcda74b25f8f7d238f936c0 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Tue, 19 Aug 2025 14:50:28 +0200 Subject: [PATCH 12/15] make raw result optional for engine Signed-off-by: Sylwester Piskozub --- app/cli/internal/policydevel/eval.go | 3 +++ pkg/policies/engine/rego/rego.go | 27 ++++++++++++++++++++------- pkg/policies/policies.go | 27 +++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index 754890a89..64cd3f919 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -98,6 +98,9 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia if len(allowedHostnames) > 0 { opts = append(opts, policies.WithAllowedHostnames(allowedHostnames...)) } + + opts = append(opts, policies.WithIncludeRawData(debug)) + v := policies.NewPolicyVerifier(schema, nil, logger, opts...) policyEvs, err := v.VerifyMaterial(context.Background(), material, materialPath) if err != nil { diff --git a/pkg/policies/engine/rego/rego.go b/pkg/policies/engine/rego/rego.go index b5706ca0e..8816c3e96 100644 --- a/pkg/policies/engine/rego/rego.go +++ b/pkg/policies/engine/rego/rego.go @@ -35,6 +35,8 @@ type Engine struct { // allowedNetworkDomains is a list of network domains that are allowed for the compiler to access // when using http.send built-in function allowedNetworkDomains []string + // includeRawData determines whether to collect raw evaluation data + includeRawData bool } type EngineOption func(*newEngineOptions) @@ -51,9 +53,16 @@ func WithAllowedNetworkDomains(domains ...string) EngineOption { } } +func WithIncludeRawData(include bool) EngineOption { + return func(e *newEngineOptions) { + e.includeRawData = include + } +} + type newEngineOptions struct { operatingMode EnvironmentMode allowedNetworkDomains []string + includeRawData bool } // NewEngine creates a new policy engine with the given options @@ -78,6 +87,7 @@ func NewEngine(opts ...EngineOption) *Engine { operatingMode: options.operatingMode, // append base allowed network domains to the user provided ones allowedNetworkDomains: append(baseAllowedNetworkDomains, options.allowedNetworkDomains...), + includeRawData: options.includeRawData, } } @@ -154,14 +164,17 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte return err } - // Get raw results first - if err := executeQuery(getRuleName(parsedModule.Package.Path, ""), r.operatingMode == EnvironmentModeRestrictive); err != nil { - return nil, err - } + var rawData *engine.RawData + // Get raw results first if requested + if r.includeRawData { + if err := executeQuery(getRuleName(parsedModule.Package.Path, ""), r.operatingMode == EnvironmentModeRestrictive); err != nil { + return nil, err + } - rawData := &engine.RawData{ - Input: decodedInput, - Output: regoResultSetToRawResults(res), + rawData = &engine.RawData{ + Input: decodedInput, + Output: regoResultSetToRawResults(res), + } } // Try the main rule first diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index daf9bd774..8b6fd66c3 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -66,12 +66,14 @@ type PolicyVerifier struct { logger *zerolog.Logger client v13.AttestationServiceClient allowedHostnames []string + includeRawData bool } var _ Verifier = (*PolicyVerifier)(nil) type PolicyVerifierOptions struct { AllowedHostnames []string + IncludeRawData bool } type PolicyVerifierOption func(*PolicyVerifierOptions) @@ -82,13 +84,25 @@ func WithAllowedHostnames(hostnames ...string) PolicyVerifierOption { } } +func WithIncludeRawData(include bool) PolicyVerifierOption { + return func(o *PolicyVerifierOptions) { + o.IncludeRawData = include + } +} + func NewPolicyVerifier(schema *v1.CraftingSchema, client v13.AttestationServiceClient, logger *zerolog.Logger, opts ...PolicyVerifierOption) *PolicyVerifier { options := &PolicyVerifierOptions{} for _, opt := range opts { opt(options) } - return &PolicyVerifier{schema: schema, client: client, logger: logger, allowedHostnames: options.AllowedHostnames} + return &PolicyVerifier{ + schema: schema, + client: client, + logger: logger, + allowedHostnames: options.AllowedHostnames, + includeRawData: options.IncludeRawData, + } } // VerifyMaterial applies all required policies to a material @@ -175,7 +189,9 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme return nil, NewPolicyError(err) } - rawResults = append(rawResults, r.RawData) + if r.RawData != nil { + rawResults = append(rawResults, r.RawData) + } // Skip if the script explicitly instructs us to ignore it, effectively preventing it from being added to the evaluation results if r.Ignore { @@ -330,6 +346,10 @@ func (pv *PolicyVerifier) executeScript(ctx context.Context, script *engine.Poli engineOpts = append(engineOpts, rego.WithAllowedNetworkDomains(pv.allowedHostnames...)) } + if pv.includeRawData { + engineOpts = append(engineOpts, rego.WithIncludeRawData(true)) + } + // verify the policy ng := rego.NewEngine(engineOpts...) res, err := ng.Verify(ctx, script, material, getInputArguments(args)) @@ -668,6 +688,9 @@ func LogPolicyEvaluations(evaluations []*v12.PolicyEvaluation, logger *zerolog.L func engineRawResultsToAPIRawResults(rawResults []*engine.RawData) []*structpb.Struct { res := make([]*structpb.Struct, 0) for _, r := range rawResults { + if r == nil { + continue + } // Convert RawData to map m := map[string]interface{}{ "input": r.Input, From c920fdaa58294a953818d108fcfd7e1ef7428ed3 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Tue, 19 Aug 2025 14:55:46 +0200 Subject: [PATCH 13/15] update cli ref 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 69e78d527..63037ff5b 100755 --- a/app/cli/documentation/cli-reference.mdx +++ b/app/cli/documentation/cli-reference.mdx @@ -2847,7 +2847,7 @@ Options ``` --allowed-hostnames strings Additional hostnames allowed for http.send requests in policies --annotation strings Key-value pairs of material annotations (key=value) ---debug Enable debug/verbose output and logging mode +--debug Include detailed evaluation inputs/outputs in JSON output and enable verbose logging -h, --help help for eval --input strings 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"] From ba1b9069a17d2d1916287321ba9389c4cec39dd8 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Wed, 20 Aug 2025 11:28:05 +0200 Subject: [PATCH 14/15] add eval result nil check and proto raw results comment Signed-off-by: Sylwester Piskozub --- app/cli/internal/policydevel/eval.go | 2 +- pkg/attestation/crafter/api/attestation/v1/crafting_state.proto | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index 64cd3f919..d7a87b33a 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -107,7 +107,7 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia return nil, err } - if len(policyEvs) == 0 { + if len(policyEvs) == 0 || policyEvs[0] == nil { return nil, fmt.Errorf("no execution branch matched for kind %s", material.MaterialType.String()) } diff --git a/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto b/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto index 977248a91..d103ef308 100644 --- a/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto +++ b/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto @@ -272,6 +272,7 @@ message PolicyEvaluation { string org_name = 4; } + // Raw inputs and outputs from the policy engine, preserved for debugging. repeated google.protobuf.Struct raw_results = 19; } From c90e1b5d957a8d690392555b3ce591cc45041754 Mon Sep 17 00:00:00 2001 From: Sylwester Piskozub Date: Wed, 20 Aug 2025 12:44:48 +0200 Subject: [PATCH 15/15] add explicit types to raw results Signed-off-by: Sylwester Piskozub --- app/cli/internal/policydevel/eval.go | 40 +- .../frontend/attestation/v1/crafting_state.ts | 99 ++++- ...PolicyEvaluation.RawResult.jsonschema.json | 19 + ....v1.PolicyEvaluation.RawResult.schema.json | 19 + ...tation.v1.PolicyEvaluation.jsonschema.json | 6 +- ...ttestation.v1.PolicyEvaluation.schema.json | 6 +- .../api/attestation/v1/crafting_state.pb.go | 384 +++++++++++------- .../api/attestation/v1/crafting_state.proto | 11 +- pkg/policies/engine/engine.go | 5 +- pkg/policies/engine/rego/rego.go | 12 +- pkg/policies/policies.go | 20 +- 11 files changed, 410 insertions(+), 211 deletions(-) create mode 100644 app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.RawResult.jsonschema.json create mode 100644 app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.RawResult.schema.json diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index d7a87b33a..92fbb177e 100644 --- a/app/cli/internal/policydevel/eval.go +++ b/app/cli/internal/policydevel/eval.go @@ -16,6 +16,7 @@ package policydevel import ( "context" + "encoding/json" "fmt" "os" @@ -23,7 +24,6 @@ import ( "github.com/chainloop-dev/chainloop/pkg/casclient" "github.com/chainloop-dev/chainloop/pkg/policies" "github.com/rs/zerolog" - "google.golang.org/protobuf/types/known/structpb" v12 "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/materials" @@ -51,8 +51,8 @@ type EvalSummary struct { } type EvalSummaryDebugInfo struct { - Inputs []map[string]interface{} `json:"inputs"` - RawResults []map[string]interface{} `json:"raw_results"` + Inputs []json.RawMessage `json:"inputs"` + RawResults []json.RawMessage `json:"raw_results"` } func Evaluate(opts *EvalOptions, logger zerolog.Logger) (*EvalSummary, error) { @@ -130,19 +130,21 @@ func verifyMaterial(schema *v1.CraftingSchema, material *v12.Attestation_Materia // Include raw debug info if requested if debug { summary.DebugInfo = &EvalSummaryDebugInfo{ - Inputs: []map[string]interface{}{}, - RawResults: []map[string]interface{}{}, + Inputs: []json.RawMessage{}, + RawResults: []json.RawMessage{}, } - for _, rr := range apiRawResultsToEngineRawResults(policyEv.RawResults) { - if in, ok := rr["input"].(map[string]interface{}); ok { - // Take the first input found, as we only allow one material input - if len(summary.DebugInfo.Inputs) == 0 { - summary.DebugInfo.Inputs = append(summary.DebugInfo.Inputs, in) - } + for _, rr := range policyEv.RawResults { + if rr == nil { + continue } - if out, ok := rr["output"].(map[string]interface{}); ok { - summary.DebugInfo.RawResults = append(summary.DebugInfo.RawResults, out) + // Take the first input found, as we only allow one material input + if len(summary.DebugInfo.Inputs) == 0 && rr.Input != nil { + summary.DebugInfo.Inputs = append(summary.DebugInfo.Inputs, json.RawMessage(rr.Input)) + } + // Collect all output raw results + if rr.Output != nil { + summary.DebugInfo.RawResults = append(summary.DebugInfo.RawResults, json.RawMessage(rr.Output)) } } } @@ -197,15 +199,3 @@ func fileNotExists(path string) bool { _, err := os.Stat(path) return os.IsNotExist(err) } - -func apiRawResultsToEngineRawResults(apiResults []*structpb.Struct) []map[string]any { - res := make([]map[string]any, 0) - for _, s := range apiResults { - if s == nil { - continue - } - m := s.AsMap() - res = append(res, m) - } - return res -} diff --git a/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts b/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts index cf477d886..7a2fa2794 100644 --- a/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts +++ b/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts @@ -280,7 +280,8 @@ export interface PolicyEvaluation { groupReference?: PolicyEvaluation_Reference; /** List of requirements this policy contributes to satisfy */ requirements: string[]; - rawResults: { [key: string]: any }[]; + /** Raw inputs and outputs from the policy engine, preserved for debugging. */ + rawResults: PolicyEvaluation_RawResult[]; } export interface PolicyEvaluation_AnnotationsEntry { @@ -305,6 +306,13 @@ export interface PolicyEvaluation_Reference { orgName: string; } +export interface PolicyEvaluation_RawResult { + /** Input data provided to the policy engine */ + input: Uint8Array; + /** Output data returned by the policy engine */ + output: Uint8Array; +} + export interface Commit { hash: string; /** Commit authors might not include email i.e "Flux <>" */ @@ -2152,7 +2160,7 @@ export const PolicyEvaluation = { writer.uint32(138).string(v!); } for (const v of message.rawResults) { - Struct.encode(Struct.wrap(v!), writer.uint32(154).fork()).ldelim(); + PolicyEvaluation_RawResult.encode(v!, writer.uint32(146).fork()).ldelim(); } return writer; }, @@ -2282,12 +2290,12 @@ export const PolicyEvaluation = { message.requirements.push(reader.string()); continue; - case 19: - if (tag !== 154) { + case 18: + if (tag !== 146) { break; } - message.rawResults.push(Struct.unwrap(Struct.decode(reader, reader.uint32()))); + message.rawResults.push(PolicyEvaluation_RawResult.decode(reader, reader.uint32())); continue; } if ((tag & 7) === 4 || tag === 0) { @@ -2334,7 +2342,9 @@ export const PolicyEvaluation = { requirements: Array.isArray(object?.requirements) ? object.requirements.map((e: any) => String(e)) : [], - rawResults: Array.isArray(object?.rawResults) ? [...object.rawResults] : [], + rawResults: Array.isArray(object?.rawResults) + ? object.rawResults.map((e: any) => PolicyEvaluation_RawResult.fromJSON(e)) + : [], }; }, @@ -2387,7 +2397,7 @@ export const PolicyEvaluation = { obj.requirements = []; } if (message.rawResults) { - obj.rawResults = message.rawResults.map((e) => e); + obj.rawResults = message.rawResults.map((e) => e ? PolicyEvaluation_RawResult.toJSON(e) : undefined); } else { obj.rawResults = []; } @@ -2433,7 +2443,7 @@ export const PolicyEvaluation = { ? PolicyEvaluation_Reference.fromPartial(object.groupReference) : undefined; message.requirements = object.requirements?.map((e) => e) || []; - message.rawResults = object.rawResults?.map((e) => e) || []; + message.rawResults = object.rawResults?.map((e) => PolicyEvaluation_RawResult.fromPartial(e)) || []; return message; }, }; @@ -2746,6 +2756,79 @@ export const PolicyEvaluation_Reference = { }, }; +function createBasePolicyEvaluation_RawResult(): PolicyEvaluation_RawResult { + return { input: new Uint8Array(0), output: new Uint8Array(0) }; +} + +export const PolicyEvaluation_RawResult = { + encode(message: PolicyEvaluation_RawResult, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.input.length !== 0) { + writer.uint32(10).bytes(message.input); + } + if (message.output.length !== 0) { + writer.uint32(18).bytes(message.output); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluation_RawResult { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicyEvaluation_RawResult(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.input = reader.bytes(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.output = reader.bytes(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PolicyEvaluation_RawResult { + return { + input: isSet(object.input) ? bytesFromBase64(object.input) : new Uint8Array(0), + output: isSet(object.output) ? bytesFromBase64(object.output) : new Uint8Array(0), + }; + }, + + toJSON(message: PolicyEvaluation_RawResult): unknown { + const obj: any = {}; + message.input !== undefined && + (obj.input = base64FromBytes(message.input !== undefined ? message.input : new Uint8Array(0))); + message.output !== undefined && + (obj.output = base64FromBytes(message.output !== undefined ? message.output : new Uint8Array(0))); + return obj; + }, + + create, I>>(base?: I): PolicyEvaluation_RawResult { + return PolicyEvaluation_RawResult.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): PolicyEvaluation_RawResult { + const message = createBasePolicyEvaluation_RawResult(); + message.input = object.input ?? new Uint8Array(0); + message.output = object.output ?? new Uint8Array(0); + return message; + }, +}; + function createBaseCommit(): Commit { return { hash: "", authorEmail: "", authorName: "", message: "", date: undefined, remotes: [], signature: "" }; } diff --git a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.RawResult.jsonschema.json b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.RawResult.jsonschema.json new file mode 100644 index 000000000..2887aeaf3 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.RawResult.jsonschema.json @@ -0,0 +1,19 @@ +{ + "$id": "attestation.v1.PolicyEvaluation.RawResult.jsonschema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "input": { + "description": "Input data provided to the policy engine", + "pattern": "^[A-Za-z0-9+/]*={0,2}$", + "type": "string" + }, + "output": { + "description": "Output data returned by the policy engine", + "pattern": "^[A-Za-z0-9+/]*={0,2}$", + "type": "string" + } + }, + "title": "Raw Result", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.RawResult.schema.json b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.RawResult.schema.json new file mode 100644 index 000000000..2a726b6d9 --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.RawResult.schema.json @@ -0,0 +1,19 @@ +{ + "$id": "attestation.v1.PolicyEvaluation.RawResult.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "input": { + "description": "Input data provided to the policy engine", + "pattern": "^[A-Za-z0-9+/]*={0,2}$", + "type": "string" + }, + "output": { + "description": "Output data returned by the policy engine", + "pattern": "^[A-Za-z0-9+/]*={0,2}$", + "type": "string" + } + }, + "title": "Raw Result", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.jsonschema.json b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.jsonschema.json index 6cbaa6c83..670b6763f 100644 --- a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.jsonschema.json @@ -15,8 +15,9 @@ "description": "Group this evaluated policy belongs to, if any" }, "^(raw_results)$": { + "description": "Raw inputs and outputs from the policy engine, preserved for debugging.", "items": { - "$ref": "google.protobuf.Struct.jsonschema.json" + "$ref": "attestation.v1.PolicyEvaluation.RawResult.jsonschema.json" }, "type": "array" }, @@ -67,8 +68,9 @@ "description": "Group this evaluated policy belongs to, if any" }, "rawResults": { + "description": "Raw inputs and outputs from the policy engine, preserved for debugging.", "items": { - "$ref": "google.protobuf.Struct.jsonschema.json" + "$ref": "attestation.v1.PolicyEvaluation.RawResult.jsonschema.json" }, "type": "array" }, diff --git a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.schema.json b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.schema.json index 171f9eaba..28c95c6a7 100644 --- a/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.schema.json +++ b/app/controlplane/api/gen/jsonschema/attestation.v1.PolicyEvaluation.schema.json @@ -15,8 +15,9 @@ "description": "Group this evaluated policy belongs to, if any" }, "^(rawResults)$": { + "description": "Raw inputs and outputs from the policy engine, preserved for debugging.", "items": { - "$ref": "google.protobuf.Struct.schema.json" + "$ref": "attestation.v1.PolicyEvaluation.RawResult.schema.json" }, "type": "array" }, @@ -67,8 +68,9 @@ "description": "Group this evaluated policy belongs to, if any" }, "raw_results": { + "description": "Raw inputs and outputs from the policy engine, preserved for debugging.", "items": { - "$ref": "google.protobuf.Struct.schema.json" + "$ref": "attestation.v1.PolicyEvaluation.RawResult.schema.json" }, "type": "array" }, diff --git a/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go b/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go index 4c4a00aa7..a38c077d0 100644 --- a/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go +++ b/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go @@ -397,8 +397,9 @@ type PolicyEvaluation struct { PolicyReference *PolicyEvaluation_Reference `protobuf:"bytes,15,opt,name=policy_reference,json=policyReference,proto3" json:"policy_reference,omitempty"` GroupReference *PolicyEvaluation_Reference `protobuf:"bytes,16,opt,name=group_reference,json=groupReference,proto3" json:"group_reference,omitempty"` // List of requirements this policy contributes to satisfy - Requirements []string `protobuf:"bytes,17,rep,name=requirements,proto3" json:"requirements,omitempty"` - RawResults []*structpb.Struct `protobuf:"bytes,19,rep,name=raw_results,json=rawResults,proto3" json:"raw_results,omitempty"` + Requirements []string `protobuf:"bytes,17,rep,name=requirements,proto3" json:"requirements,omitempty"` + // Raw inputs and outputs from the policy engine, preserved for debugging. + RawResults []*PolicyEvaluation_RawResult `protobuf:"bytes,18,rep,name=raw_results,json=rawResults,proto3" json:"raw_results,omitempty"` } func (x *PolicyEvaluation) Reset() { @@ -548,7 +549,7 @@ func (x *PolicyEvaluation) GetRequirements() []string { return nil } -func (x *PolicyEvaluation) GetRawResults() []*structpb.Struct { +func (x *PolicyEvaluation) GetRawResults() []*PolicyEvaluation_RawResult { if x != nil { return x.RawResults } @@ -1829,6 +1830,63 @@ func (x *PolicyEvaluation_Reference) GetOrgName() string { return "" } +type PolicyEvaluation_RawResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Input data provided to the policy engine + Input []byte `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"` + // Output data returned by the policy engine + Output []byte `protobuf:"bytes,2,opt,name=output,proto3" json:"output,omitempty"` +} + +func (x *PolicyEvaluation_RawResult) Reset() { + *x = PolicyEvaluation_RawResult{} + if protoimpl.UnsafeEnabled { + mi := &file_attestation_v1_crafting_state_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PolicyEvaluation_RawResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PolicyEvaluation_RawResult) ProtoMessage() {} + +func (x *PolicyEvaluation_RawResult) ProtoReflect() protoreflect.Message { + mi := &file_attestation_v1_crafting_state_proto_msgTypes[24] + 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 PolicyEvaluation_RawResult.ProtoReflect.Descriptor instead. +func (*PolicyEvaluation_RawResult) Descriptor() ([]byte, []int) { + return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{2, 4} +} + +func (x *PolicyEvaluation_RawResult) GetInput() []byte { + if x != nil { + return x.Input + } + return nil +} + +func (x *PolicyEvaluation_RawResult) GetOutput() []byte { + if x != nil { + return x.Output + } + return nil +} + type Commit_Remote struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1841,7 +1899,7 @@ type Commit_Remote struct { func (x *Commit_Remote) Reset() { *x = Commit_Remote{} if protoimpl.UnsafeEnabled { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[24] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1854,7 +1912,7 @@ func (x *Commit_Remote) String() string { func (*Commit_Remote) ProtoMessage() {} func (x *Commit_Remote) ProtoReflect() protoreflect.Message { - mi := &file_attestation_v1_crafting_state_proto_msgTypes[24] + mi := &file_attestation_v1_crafting_state_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2124,7 +2182,7 @@ var file_attestation_v1_crafting_state_proto_rawDesc = []byte{ 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, - 0x22, 0xbf, 0x0b, 0x0a, 0x10, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, + 0x22, 0x8d, 0x0c, 0x0a, 0x10, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x82, 0x01, 0xba, 0x48, 0x7f, 0xba, 0x01, 0x7c, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x2e, 0x64, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x32, 0x33, 0x12, 0x3a, 0x6d, 0x75, @@ -2184,134 +2242,139 @@ var file_attestation_v1_crafting_state_proto_rawDesc = []byte{ 0x75, 0x70, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, - 0x38, 0x0a, 0x0b, 0x72, 0x61, 0x77, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x13, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0a, 0x72, - 0x61, 0x77, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x4b, 0x0a, 0x0b, 0x72, 0x61, 0x77, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x12, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 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, 0x2e, 0x52, 0x61, 0x77, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x52, 0x0a, 0x72, 0x61, 0x77, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x10, + 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x1a, 0x37, 0x0a, 0x09, + 0x57, 0x69, 0x74, 0x68, 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, 0x1a, 0x4f, 0x0a, 0x09, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x73, 0x75, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x12, 0x20, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0xfc, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x82, 0x01, 0xba, 0x48, 0x7f, 0xba, 0x01, 0x7c, 0x0a, 0x0d, 0x6e, 0x61, + 0x6d, 0x65, 0x2e, 0x64, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x32, 0x33, 0x12, 0x3a, 0x6d, 0x75, 0x73, + 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6c, + 0x6f, 0x77, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, + 0x2c, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68, + 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2e, 0x1a, 0x2f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, + 0x28, 0x5b, 0x2d, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, + 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, + 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, + 0x19, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, + 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, + 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, + 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0x39, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x22, 0xde, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x28, 0x0a, 0x0b, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, + 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, + 0x40, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x75, 0x72, + 0x6c, 0x22, 0xaf, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0b, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x3d, 0x0a, 0x0b, 0x61, + 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, + 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, + 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, + 0x52, 0x75, 0x6e, 0x22, 0xa3, 0x03, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x2b, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x61, 0x6d, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x61, 0x6d, 0x12, 0x28, 0x0a, 0x0b, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2c, + 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x0c, + 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x6f, 0x72, 0x67, + 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7d, 0x0a, 0x0e, 0x50, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, + 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, + 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x28, + 0x0a, 0x10, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6d, 0x61, 0x72, 0x6b, 0x41, 0x73, + 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x22, 0xde, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x46, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x6f, 0x77, 0x6e, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, + 0x0a, 0x0b, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 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, 0x1a, 0x37, 0x0a, 0x09, 0x57, 0x69, 0x74, - 0x68, 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, 0x1a, 0x4f, 0x0a, 0x09, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x20, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x12, 0x20, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x1a, 0xfc, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x82, 0x01, 0xba, 0x48, 0x7f, 0xba, 0x01, 0x7c, 0x0a, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x2e, - 0x64, 0x6e, 0x73, 0x2d, 0x31, 0x31, 0x32, 0x33, 0x12, 0x3a, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6c, 0x6f, 0x77, 0x65, - 0x72, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x68, 0x79, 0x70, 0x68, - 0x65, 0x6e, 0x73, 0x2e, 0x1a, 0x2f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x2d, - 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, - 0x29, 0x3f, 0x24, 0x27, 0x29, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, - 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x03, - 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, - 0x10, 0x01, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x67, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x67, 0x4e, 0x61, - 0x6d, 0x65, 0x22, 0xde, 0x02, 0x0a, 0x06, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1b, 0x0a, - 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x28, 0x0a, - 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, - 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x72, 0x65, - 0x6d, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, 0x74, - 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, - 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x1a, 0x40, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, - 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, - 0x75, 0x72, 0x6c, 0x22, 0xaf, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x77, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x3d, 0x0a, - 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, - 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, - 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0xa3, 0x03, 0x0a, 0x10, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, - 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x12, 0x2b, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1e, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x61, 0x6d, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x61, 0x6d, 0x12, 0x28, 0x0a, 0x0b, - 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, - 0x66, 0x6c, 0x6f, 0x77, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x5f, 0x72, 0x75, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x75, 0x6e, 0x49, 0x64, 0x12, 0x30, - 0x0a, 0x0f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x2c, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, - 0x0a, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x6f, - 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7d, 0x0a, 0x0e, 0x50, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, - 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x72, 0x6b, 0x5f, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x6c, 0x65, - 0x61, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6d, 0x61, 0x72, 0x6b, - 0x41, 0x73, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x22, 0xde, 0x02, 0x0a, 0x12, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x46, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, - 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x44, 0x69, 0x67, 0x65, - 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x6f, 0x77, - 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, - 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x1a, 0x39, 0x0a, 0x0b, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 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, 0x42, 0x4f, 0x5a, 0x4d, 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, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2f, 0x63, 0x72, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x74, - 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x4f, 0x5a, 0x4d, 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, + 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, + 0x63, 0x72, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -2327,7 +2390,7 @@ func file_attestation_v1_crafting_state_proto_rawDescGZIP() []byte { } var file_attestation_v1_crafting_state_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_attestation_v1_crafting_state_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_attestation_v1_crafting_state_proto_msgTypes = make([]protoimpl.MessageInfo, 27) var file_attestation_v1_crafting_state_proto_goTypes = []interface{}{ (Attestation_Auth_AuthType)(0), // 0: attestation.v1.Attestation.Auth.AuthType (*Attestation)(nil), // 1: attestation.v1.Attestation @@ -2354,53 +2417,54 @@ var file_attestation_v1_crafting_state_proto_goTypes = []interface{}{ nil, // 22: attestation.v1.PolicyEvaluation.WithEntry (*PolicyEvaluation_Violation)(nil), // 23: attestation.v1.PolicyEvaluation.Violation (*PolicyEvaluation_Reference)(nil), // 24: attestation.v1.PolicyEvaluation.Reference - (*Commit_Remote)(nil), // 25: attestation.v1.Commit.Remote - nil, // 26: attestation.v1.ResourceDescriptor.DigestEntry - (*timestamppb.Timestamp)(nil), // 27: google.protobuf.Timestamp - (v1.CraftingSchema_Runner_RunnerType)(0), // 28: workflowcontract.v1.CraftingSchema.Runner.RunnerType - (v1.CraftingSchema_Material_MaterialType)(0), // 29: workflowcontract.v1.CraftingSchema.Material.MaterialType - (*structpb.Struct)(nil), // 30: google.protobuf.Struct + (*PolicyEvaluation_RawResult)(nil), // 25: attestation.v1.PolicyEvaluation.RawResult + (*Commit_Remote)(nil), // 26: attestation.v1.Commit.Remote + nil, // 27: attestation.v1.ResourceDescriptor.DigestEntry + (*timestamppb.Timestamp)(nil), // 28: google.protobuf.Timestamp + (v1.CraftingSchema_Runner_RunnerType)(0), // 29: workflowcontract.v1.CraftingSchema.Runner.RunnerType + (v1.CraftingSchema_Material_MaterialType)(0), // 30: workflowcontract.v1.CraftingSchema.Material.MaterialType (*v1.CraftingSchema)(nil), // 31: workflowcontract.v1.CraftingSchema - (*wrapperspb.BoolValue)(nil), // 32: google.protobuf.BoolValue + (*structpb.Struct)(nil), // 32: google.protobuf.Struct + (*wrapperspb.BoolValue)(nil), // 33: google.protobuf.BoolValue } var file_attestation_v1_crafting_state_proto_depIdxs = []int32{ - 27, // 0: attestation.v1.Attestation.initialized_at:type_name -> google.protobuf.Timestamp - 27, // 1: attestation.v1.Attestation.finished_at:type_name -> google.protobuf.Timestamp + 28, // 0: attestation.v1.Attestation.initialized_at:type_name -> google.protobuf.Timestamp + 28, // 1: attestation.v1.Attestation.finished_at:type_name -> google.protobuf.Timestamp 6, // 2: attestation.v1.Attestation.workflow:type_name -> attestation.v1.WorkflowMetadata 9, // 3: attestation.v1.Attestation.materials:type_name -> attestation.v1.Attestation.MaterialsEntry 10, // 4: attestation.v1.Attestation.annotations:type_name -> attestation.v1.Attestation.AnnotationsEntry 12, // 5: attestation.v1.Attestation.env_vars:type_name -> attestation.v1.Attestation.EnvVarsEntry - 28, // 6: attestation.v1.Attestation.runner_type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType + 29, // 6: attestation.v1.Attestation.runner_type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType 4, // 7: attestation.v1.Attestation.head:type_name -> attestation.v1.Commit 3, // 8: attestation.v1.Attestation.policy_evaluations:type_name -> attestation.v1.PolicyEvaluation 14, // 9: attestation.v1.Attestation.signing_options:type_name -> attestation.v1.Attestation.SigningOptions 2, // 10: attestation.v1.Attestation.runner_environment:type_name -> attestation.v1.RunnerEnvironment 13, // 11: attestation.v1.Attestation.auth:type_name -> attestation.v1.Attestation.Auth - 28, // 12: attestation.v1.RunnerEnvironment.type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType + 29, // 12: attestation.v1.RunnerEnvironment.type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType 21, // 13: attestation.v1.PolicyEvaluation.annotations:type_name -> attestation.v1.PolicyEvaluation.AnnotationsEntry 23, // 14: attestation.v1.PolicyEvaluation.violations:type_name -> attestation.v1.PolicyEvaluation.Violation 22, // 15: attestation.v1.PolicyEvaluation.with:type_name -> attestation.v1.PolicyEvaluation.WithEntry - 29, // 16: attestation.v1.PolicyEvaluation.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 30, // 16: attestation.v1.PolicyEvaluation.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType 24, // 17: attestation.v1.PolicyEvaluation.policy_reference:type_name -> attestation.v1.PolicyEvaluation.Reference 24, // 18: attestation.v1.PolicyEvaluation.group_reference:type_name -> attestation.v1.PolicyEvaluation.Reference - 30, // 19: attestation.v1.PolicyEvaluation.raw_results:type_name -> google.protobuf.Struct - 27, // 20: attestation.v1.Commit.date:type_name -> google.protobuf.Timestamp - 25, // 21: attestation.v1.Commit.remotes:type_name -> attestation.v1.Commit.Remote + 25, // 19: attestation.v1.PolicyEvaluation.raw_results:type_name -> attestation.v1.PolicyEvaluation.RawResult + 28, // 20: attestation.v1.Commit.date:type_name -> google.protobuf.Timestamp + 26, // 21: attestation.v1.Commit.remotes:type_name -> attestation.v1.Commit.Remote 31, // 22: attestation.v1.CraftingState.input_schema:type_name -> workflowcontract.v1.CraftingSchema 1, // 23: attestation.v1.CraftingState.attestation:type_name -> attestation.v1.Attestation 7, // 24: attestation.v1.WorkflowMetadata.version:type_name -> attestation.v1.ProjectVersion - 26, // 25: attestation.v1.ResourceDescriptor.digest:type_name -> attestation.v1.ResourceDescriptor.DigestEntry - 30, // 26: attestation.v1.ResourceDescriptor.annotations:type_name -> google.protobuf.Struct + 27, // 25: attestation.v1.ResourceDescriptor.digest:type_name -> attestation.v1.ResourceDescriptor.DigestEntry + 32, // 26: attestation.v1.ResourceDescriptor.annotations:type_name -> google.protobuf.Struct 11, // 27: attestation.v1.Attestation.MaterialsEntry.value:type_name -> attestation.v1.Attestation.Material 16, // 28: attestation.v1.Attestation.Material.string:type_name -> attestation.v1.Attestation.Material.KeyVal 17, // 29: attestation.v1.Attestation.Material.container_image:type_name -> attestation.v1.Attestation.Material.ContainerImage 18, // 30: attestation.v1.Attestation.Material.artifact:type_name -> attestation.v1.Attestation.Material.Artifact 19, // 31: attestation.v1.Attestation.Material.sbom_artifact:type_name -> attestation.v1.Attestation.Material.SBOMArtifact - 27, // 32: attestation.v1.Attestation.Material.added_at:type_name -> google.protobuf.Timestamp - 29, // 33: attestation.v1.Attestation.Material.material_type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 28, // 32: attestation.v1.Attestation.Material.added_at:type_name -> google.protobuf.Timestamp + 30, // 33: attestation.v1.Attestation.Material.material_type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType 15, // 34: attestation.v1.Attestation.Material.annotations:type_name -> attestation.v1.Attestation.Material.AnnotationsEntry 0, // 35: attestation.v1.Attestation.Auth.type:type_name -> attestation.v1.Attestation.Auth.AuthType - 32, // 36: attestation.v1.Attestation.Material.ContainerImage.has_latest_tag:type_name -> google.protobuf.BoolValue + 33, // 36: attestation.v1.Attestation.Material.ContainerImage.has_latest_tag:type_name -> google.protobuf.BoolValue 18, // 37: attestation.v1.Attestation.Material.SBOMArtifact.artifact:type_name -> attestation.v1.Attestation.Material.Artifact 20, // 38: attestation.v1.Attestation.Material.SBOMArtifact.main_component:type_name -> attestation.v1.Attestation.Material.SBOMArtifact.MainComponent 39, // [39:39] is the sub-list for method output_type @@ -2633,6 +2697,18 @@ func file_attestation_v1_crafting_state_proto_init() { } } file_attestation_v1_crafting_state_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicyEvaluation_RawResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_attestation_v1_crafting_state_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Commit_Remote); i { case 0: return &v.state @@ -2657,7 +2733,7 @@ func file_attestation_v1_crafting_state_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_attestation_v1_crafting_state_proto_rawDesc, NumEnums: 1, - NumMessages: 26, + NumMessages: 27, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto b/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto index d103ef308..3012f2884 100644 --- a/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto +++ b/pkg/attestation/crafter/api/attestation/v1/crafting_state.proto @@ -254,6 +254,9 @@ message PolicyEvaluation { // List of requirements this policy contributes to satisfy repeated string requirements = 17; + // Raw inputs and outputs from the policy engine, preserved for debugging. + repeated RawResult raw_results = 18; + message Violation { string subject = 1 [(buf.validate.field).required = true]; string message = 2 [(buf.validate.field).required = true]; @@ -272,8 +275,12 @@ message PolicyEvaluation { string org_name = 4; } - // Raw inputs and outputs from the policy engine, preserved for debugging. - repeated google.protobuf.Struct raw_results = 19; + message RawResult { + // Input data provided to the policy engine + bytes input = 1; + // Output data returned by the policy engine + bytes output = 2; + } } message Commit { diff --git a/pkg/policies/engine/engine.go b/pkg/policies/engine/engine.go index 5a198854e..eb4ae7a1a 100644 --- a/pkg/policies/engine/engine.go +++ b/pkg/policies/engine/engine.go @@ -17,6 +17,7 @@ package engine import ( "context" + "encoding/json" "fmt" ) @@ -33,8 +34,8 @@ type EvaluationResult struct { RawData *RawData } type RawData struct { - Input interface{} - Output map[string]interface{} + Input json.RawMessage + Output json.RawMessage } // PolicyViolation represents a policy failure diff --git a/pkg/policies/engine/rego/rego.go b/pkg/policies/engine/rego/rego.go index 8816c3e96..a71e018fa 100644 --- a/pkg/policies/engine/rego/rego.go +++ b/pkg/policies/engine/rego/rego.go @@ -171,9 +171,17 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte return nil, err } + inputBytes, err := json.Marshal(decodedInput) + if err != nil { + return nil, fmt.Errorf("failed to marshal input for raw data: %w", err) + } + outputBytes, err := json.Marshal(regoResultSetToRawResults(res)) + if err != nil { + return nil, fmt.Errorf("failed to marshal output for raw data: %w", err) + } rawData = &engine.RawData{ - Input: decodedInput, - Output: regoResultSetToRawResults(res), + Input: json.RawMessage(inputBytes), + Output: json.RawMessage(outputBytes), } } diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index 8b6fd66c3..d9c72b148 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -32,7 +32,6 @@ import ( "github.com/sigstore/cosign/v2/pkg/blob" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/structpb" v1 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" v12 "github.com/chainloop-dev/chainloop/pkg/attestation/crafter/api/attestation/v1" @@ -685,23 +684,16 @@ func LogPolicyEvaluations(evaluations []*v12.PolicyEvaluation, logger *zerolog.L } } -func engineRawResultsToAPIRawResults(rawResults []*engine.RawData) []*structpb.Struct { - res := make([]*structpb.Struct, 0) +func engineRawResultsToAPIRawResults(rawResults []*engine.RawData) []*v12.PolicyEvaluation_RawResult { + res := make([]*v12.PolicyEvaluation_RawResult, 0) for _, r := range rawResults { if r == nil { continue } - // Convert RawData to map - m := map[string]interface{}{ - "input": r.Input, - "output": r.Output, - } - - s, err := structpb.NewStruct(m) - if err != nil { - continue - } - res = append(res, s) + res = append(res, &v12.PolicyEvaluation_RawResult{ + Input: r.Input, + Output: r.Output, + }) } return res }