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 c3a877b70..10d98cd2f 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 + debug bool ) cmd := &cobra.Command{ @@ -51,6 +52,7 @@ evaluates the policy against the provided material or attestation.`, PolicyPath: policyPath, Inputs: parseKeyValue(inputs), AllowedHostnames: allowedHostnames, + Debug: debug, } policyEval, err := action.NewPolicyEval(opts, actionOpts) @@ -74,6 +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, "Include detailed evaluation inputs/outputs in JSON output and enable verbose logging") return cmd } diff --git a/app/cli/documentation/cli-reference.mdx b/app/cli/documentation/cli-reference.mdx index bc59f8b2a..63037ff5b 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 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"] @@ -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/app/cli/internal/action/policy_develop_eval.go b/app/cli/internal/action/policy_develop_eval.go index aa68711b8..708e28446 100644 --- a/app/cli/internal/action/policy_develop_eval.go +++ b/app/cli/internal/action/policy_develop_eval.go @@ -26,13 +26,7 @@ type PolicyEvalOpts struct { PolicyPath string Inputs map[string]string AllowedHostnames []string -} - -type PolicyEvalResult struct { - Violations []string `json:"violations"` - SkipReasons []string `json:"skip_reasons"` - Skipped bool `json:"skipped"` - Ignored bool `json:"ignored,omitempty"` + Debug bool } type PolicyEval struct { @@ -47,7 +41,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, @@ -55,6 +49,7 @@ func (action *PolicyEval) Run() ([]*PolicyEvalResult, error) { MaterialPath: action.opts.MaterialPath, Inputs: action.opts.Inputs, AllowedHostnames: action.opts.AllowedHostnames, + Debug: action.opts.Debug, } // Evaluate policy @@ -63,15 +58,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, - }) - } - - return results, nil + return resp, nil } diff --git a/app/cli/internal/policydevel/eval.go b/app/cli/internal/policydevel/eval.go index ccb997347..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" @@ -35,16 +36,26 @@ type EvalOptions struct { MaterialPath string Inputs map[string]string AllowedHostnames []string + Debug bool } type EvalResult struct { - Skipped bool - SkipReasons []string - Violations []string - Ignored bool + Violations []string `json:"violations"` + SkipReasons []string `json:"skip_reasons"` + Skipped bool `json:"skipped"` } -func Evaluate(opts *EvalOptions, logger zerolog.Logger) ([]*EvalResult, error) { +type EvalSummary struct { + Result *EvalResult `json:"result"` + DebugInfo *EvalSummaryDebugInfo `json:"debug_info,omitempty"` +} + +type EvalSummaryDebugInfo struct { + Inputs []json.RawMessage `json:"inputs"` + RawResults []json.RawMessage `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 { @@ -59,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.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) { @@ -82,41 +93,63 @@ 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, debug bool, allowedHostnames []string, logger *zerolog.Logger) (*EvalSummary, error) { var opts []policies.PolicyVerifierOption 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 { return nil, err } - // no evaluations were returned - 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()) } - 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)), + }, + } - // Collect all violation messages - violations := make([]string, 0, len(policyEv.Violations)) - for _, v := range policyEv.Violations { - violations = append(violations, v.Message) + // Collect violation messages + for _, v := range policyEv.Violations { + summary.Result.Violations = append(summary.Result.Violations, v.Message) + } + + // Include raw debug info if requested + if debug { + summary.DebugInfo = &EvalSummaryDebugInfo{ + Inputs: []json.RawMessage{}, + RawResults: []json.RawMessage{}, } - result.Violations = violations - results = append(results, result) + for _, rr := range policyEv.RawResults { + if rr == nil { + continue + } + // 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)) + } + } } - return results, nil + return summary, nil } func craftMaterial(materialPath, materialKind string, logger *zerolog.Logger) (*v12.Attestation_Material, error) { 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) } } 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..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,6 +280,8 @@ export interface PolicyEvaluation { groupReference?: PolicyEvaluation_Reference; /** List of requirements this policy contributes to satisfy */ requirements: string[]; + /** Raw inputs and outputs from the policy engine, preserved for debugging. */ + rawResults: PolicyEvaluation_RawResult[]; } export interface PolicyEvaluation_AnnotationsEntry { @@ -304,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 <>" */ @@ -2096,6 +2105,7 @@ function createBasePolicyEvaluation(): PolicyEvaluation { policyReference: undefined, groupReference: undefined, requirements: [], + rawResults: [], }; } @@ -2149,6 +2159,9 @@ export const PolicyEvaluation = { for (const v of message.requirements) { writer.uint32(138).string(v!); } + for (const v of message.rawResults) { + PolicyEvaluation_RawResult.encode(v!, writer.uint32(146).fork()).ldelim(); + } return writer; }, @@ -2277,6 +2290,13 @@ export const PolicyEvaluation = { message.requirements.push(reader.string()); continue; + case 18: + if (tag !== 146) { + break; + } + + message.rawResults.push(PolicyEvaluation_RawResult.decode(reader, reader.uint32())); + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -2322,6 +2342,9 @@ export const PolicyEvaluation = { requirements: Array.isArray(object?.requirements) ? object.requirements.map((e: any) => String(e)) : [], + rawResults: Array.isArray(object?.rawResults) + ? object.rawResults.map((e: any) => PolicyEvaluation_RawResult.fromJSON(e)) + : [], }; }, @@ -2373,6 +2396,11 @@ export const PolicyEvaluation = { } else { obj.requirements = []; } + if (message.rawResults) { + obj.rawResults = message.rawResults.map((e) => e ? PolicyEvaluation_RawResult.toJSON(e) : undefined); + } else { + obj.rawResults = []; + } return obj; }, @@ -2415,6 +2443,7 @@ export const PolicyEvaluation = { ? PolicyEvaluation_Reference.fromPartial(object.groupReference) : undefined; message.requirements = object.requirements?.map((e) => e) || []; + message.rawResults = object.rawResults?.map((e) => PolicyEvaluation_RawResult.fromPartial(e)) || []; return message; }, }; @@ -2727,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 8867b710e..670b6763f 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,13 @@ "$ref": "attestation.v1.PolicyEvaluation.Reference.jsonschema.json", "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": "attestation.v1.PolicyEvaluation.RawResult.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 +67,13 @@ "$ref": "attestation.v1.PolicyEvaluation.Reference.jsonschema.json", "description": "Group this evaluated policy belongs to, if any" }, + "rawResults": { + "description": "Raw inputs and outputs from the policy engine, preserved for debugging.", + "items": { + "$ref": "attestation.v1.PolicyEvaluation.RawResult.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..28c95c6a7 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,13 @@ "$ref": "attestation.v1.PolicyEvaluation.Reference.schema.json", "description": "Group this evaluated policy belongs to, if any" }, + "^(rawResults)$": { + "description": "Raw inputs and outputs from the policy engine, preserved for debugging.", + "items": { + "$ref": "attestation.v1.PolicyEvaluation.RawResult.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 +67,13 @@ "$ref": "attestation.v1.PolicyEvaluation.Reference.schema.json", "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": "attestation.v1.PolicyEvaluation.RawResult.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..a38c077d0 100644 --- a/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go +++ b/pkg/attestation/crafter/api/attestation/v1/crafting_state.pb.go @@ -398,6 +398,8 @@ type PolicyEvaluation struct { 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"` + // 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() { @@ -547,6 +549,13 @@ func (x *PolicyEvaluation) GetRequirements() []string { return nil } +func (x *PolicyEvaluation) GetRawResults() []*PolicyEvaluation_RawResult { + if x != nil { + return x.RawResults + } + return nil +} + type Commit struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1821,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 @@ -1833,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) } @@ -1846,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 { @@ -2116,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, 0x85, 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, @@ -2175,131 +2241,140 @@ 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, - 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, + 0x09, 0x52, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, + 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, 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 ( @@ -2315,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 @@ -2342,59 +2417,61 @@ 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 - (*v1.CraftingSchema)(nil), // 30: workflowcontract.v1.CraftingSchema - (*structpb.Struct)(nil), // 31: google.protobuf.Struct - (*wrapperspb.BoolValue)(nil), // 32: google.protobuf.BoolValue + (*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 + (*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 - 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 + 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 + 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 + 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 + 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 + 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() } @@ -2620,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 @@ -2644,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 379c0b6a7..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]; @@ -271,6 +274,13 @@ message PolicyEvaluation { string uri = 3 [(buf.validate.field).string.min_len = 1]; string org_name = 4; } + + 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 294ef051b..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" ) @@ -30,6 +31,11 @@ type EvaluationResult struct { Skipped bool SkipReason string Ignore bool + RawData *RawData +} +type RawData struct { + 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 25806eb45..a71e018fa 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, } } @@ -147,15 +157,36 @@ 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 } + 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 + } + + 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: json.RawMessage(inputBytes), + Output: json.RawMessage(outputBytes), + } + } + // Try the main rule first - if err := executeQuery(mainRule, r.operatingMode == EnvironmentModeRestrictive); err != nil { + if err := executeQuery(getRuleName(parsedModule.Package.Path, mainRule), r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } @@ -163,7 +194,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(getRuleName(parsedModule.Package.Path, deprecatedRule), r.operatingMode == EnvironmentModeRestrictive); err != nil { return nil, err } @@ -171,15 +202,15 @@ func (r *Engine) Verify(ctx context.Context, policy *engine.Policy, input []byte return nil, fmt.Errorf("failed to evaluate policy: neither '%s' nor '%s' rule found", mainRule, deprecatedRule) } - return parseViolationsRule(res, policy) + return parseViolationsRule(res, policy, rawData) } - return parseResultRule(res, policy) + 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) (*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 { @@ -207,12 +238,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 + RawData: rawData, }, nil } // parse `result` rule -func parseResultRule(res rego.ResultSet, policy *engine.Policy) (*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 = rawData for _, exp := range res { for _, val := range exp.Expressions { ruleResult, ok := val.Value.(map[string]any) @@ -257,8 +290,8 @@ 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)) +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) if err != nil { @@ -301,3 +334,22 @@ func (r *Engine) Capabilities() *ast.Capabilities { capabilities.Builtins = enabledBuiltin return capabilities } + +func regoResultSetToRawResults(res rego.ResultSet) map[string]interface{} { + raw := make(map[string]interface{}) + for _, r := range res { + entry := make(map[string]interface{}) + for _, exp := range r.Expressions { + entry[exp.Text] = exp.Value + } + raw = entry + } + 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) +} diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index 875f737ec..d9c72b148 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -65,12 +65,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) @@ -81,13 +83,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 @@ -165,6 +179,7 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme sources := make([]string, 0) evalResults := make([]*engine.EvaluationResult, 0) + rawResults := make([]*engine.RawData, 0) skipped := true reasons := make([]string, 0) for _, script := range scripts { @@ -173,6 +188,10 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme return nil, NewPolicyError(err) } + 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 { continue @@ -229,6 +248,7 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme // Merged "skip_reason" SkipReasons: reasons, Requirements: attachment.Requirements, + RawResults: engineRawResultsToAPIRawResults(rawResults), }, nil } @@ -325,6 +345,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)) @@ -659,3 +683,17 @@ func LogPolicyEvaluations(evaluations []*v12.PolicyEvaluation, logger *zerolog.L } } } + +func engineRawResultsToAPIRawResults(rawResults []*engine.RawData) []*v12.PolicyEvaluation_RawResult { + res := make([]*v12.PolicyEvaluation_RawResult, 0) + for _, r := range rawResults { + if r == nil { + continue + } + res = append(res, &v12.PolicyEvaluation_RawResult{ + Input: r.Input, + Output: r.Output, + }) + } + return res +}