diff --git a/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts b/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts index a880d4a60..f17a8c4ec 100644 --- a/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts +++ b/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts @@ -385,6 +385,15 @@ export interface PolicySpec { */ type: CraftingSchema_Material_MaterialType; policies: PolicySpecV2[]; + /** Describe the supported inputs */ + inputs: PolicyInput[]; +} + +export interface PolicyInput { + name: string; + description: string; + required: boolean; + default: string; } export interface PolicySpecV2 { @@ -408,6 +417,13 @@ export interface PolicySpecV2 { export interface PolicyGroupAttachment { /** Group reference, it might be an URL or a provider reference */ ref: string; + /** group arguments */ + with: { [key: string]: string }; +} + +export interface PolicyGroupAttachment_WithEntry { + key: string; + value: string; } /** Represents a group or policies */ @@ -420,6 +436,7 @@ export interface PolicyGroup { export interface PolicyGroup_PolicyGroupSpec { policies?: PolicyGroup_PolicyGroupPolicies; + inputs: PolicyInput[]; } export interface PolicyGroup_PolicyGroupPolicies { @@ -1471,7 +1488,7 @@ export const Metadata_AnnotationsEntry = { }; function createBasePolicySpec(): PolicySpec { - return { path: undefined, embedded: undefined, type: 0, policies: [] }; + return { path: undefined, embedded: undefined, type: 0, policies: [], inputs: [] }; } export const PolicySpec = { @@ -1488,6 +1505,9 @@ export const PolicySpec = { for (const v of message.policies) { PolicySpecV2.encode(v!, writer.uint32(34).fork()).ldelim(); } + for (const v of message.inputs) { + PolicyInput.encode(v!, writer.uint32(42).fork()).ldelim(); + } return writer; }, @@ -1526,6 +1546,13 @@ export const PolicySpec = { message.policies.push(PolicySpecV2.decode(reader, reader.uint32())); continue; + case 5: + if (tag !== 42) { + break; + } + + message.inputs.push(PolicyInput.decode(reader, reader.uint32())); + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -1541,6 +1568,7 @@ export const PolicySpec = { embedded: isSet(object.embedded) ? String(object.embedded) : undefined, type: isSet(object.type) ? craftingSchema_Material_MaterialTypeFromJSON(object.type) : 0, policies: Array.isArray(object?.policies) ? object.policies.map((e: any) => PolicySpecV2.fromJSON(e)) : [], + inputs: Array.isArray(object?.inputs) ? object.inputs.map((e: any) => PolicyInput.fromJSON(e)) : [], }; }, @@ -1554,6 +1582,11 @@ export const PolicySpec = { } else { obj.policies = []; } + if (message.inputs) { + obj.inputs = message.inputs.map((e) => e ? PolicyInput.toJSON(e) : undefined); + } else { + obj.inputs = []; + } return obj; }, @@ -1567,6 +1600,104 @@ export const PolicySpec = { message.embedded = object.embedded ?? undefined; message.type = object.type ?? 0; message.policies = object.policies?.map((e) => PolicySpecV2.fromPartial(e)) || []; + message.inputs = object.inputs?.map((e) => PolicyInput.fromPartial(e)) || []; + return message; + }, +}; + +function createBasePolicyInput(): PolicyInput { + return { name: "", description: "", required: false, default: "" }; +} + +export const PolicyInput = { + encode(message: PolicyInput, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.name !== "") { + writer.uint32(10).string(message.name); + } + if (message.description !== "") { + writer.uint32(18).string(message.description); + } + if (message.required === true) { + writer.uint32(24).bool(message.required); + } + if (message.default !== "") { + writer.uint32(34).string(message.default); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PolicyInput { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicyInput(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.name = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.description = reader.string(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.required = reader.bool(); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.default = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PolicyInput { + return { + name: isSet(object.name) ? String(object.name) : "", + description: isSet(object.description) ? String(object.description) : "", + required: isSet(object.required) ? Boolean(object.required) : false, + default: isSet(object.default) ? String(object.default) : "", + }; + }, + + toJSON(message: PolicyInput): unknown { + const obj: any = {}; + message.name !== undefined && (obj.name = message.name); + message.description !== undefined && (obj.description = message.description); + message.required !== undefined && (obj.required = message.required); + message.default !== undefined && (obj.default = message.default); + return obj; + }, + + create, I>>(base?: I): PolicyInput { + return PolicyInput.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): PolicyInput { + const message = createBasePolicyInput(); + message.name = object.name ?? ""; + message.description = object.description ?? ""; + message.required = object.required ?? false; + message.default = object.default ?? ""; return message; }, }; @@ -1656,7 +1787,7 @@ export const PolicySpecV2 = { }; function createBasePolicyGroupAttachment(): PolicyGroupAttachment { - return { ref: "" }; + return { ref: "", with: {} }; } export const PolicyGroupAttachment = { @@ -1664,6 +1795,9 @@ export const PolicyGroupAttachment = { if (message.ref !== "") { writer.uint32(10).string(message.ref); } + Object.entries(message.with).forEach(([key, value]) => { + PolicyGroupAttachment_WithEntry.encode({ key: key as any, value }, writer.uint32(18).fork()).ldelim(); + }); return writer; }, @@ -1681,6 +1815,16 @@ export const PolicyGroupAttachment = { message.ref = reader.string(); continue; + case 2: + if (tag !== 18) { + break; + } + + const entry2 = PolicyGroupAttachment_WithEntry.decode(reader, reader.uint32()); + if (entry2.value !== undefined) { + message.with[entry2.key] = entry2.value; + } + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -1691,12 +1835,26 @@ export const PolicyGroupAttachment = { }, fromJSON(object: any): PolicyGroupAttachment { - return { ref: isSet(object.ref) ? String(object.ref) : "" }; + return { + ref: isSet(object.ref) ? String(object.ref) : "", + with: isObject(object.with) + ? Object.entries(object.with).reduce<{ [key: string]: string }>((acc, [key, value]) => { + acc[key] = String(value); + return acc; + }, {}) + : {}, + }; }, toJSON(message: PolicyGroupAttachment): unknown { const obj: any = {}; message.ref !== undefined && (obj.ref = message.ref); + obj.with = {}; + if (message.with) { + Object.entries(message.with).forEach(([k, v]) => { + obj.with[k] = v; + }); + } return obj; }, @@ -1707,6 +1865,82 @@ export const PolicyGroupAttachment = { fromPartial, I>>(object: I): PolicyGroupAttachment { const message = createBasePolicyGroupAttachment(); message.ref = object.ref ?? ""; + message.with = Object.entries(object.with ?? {}).reduce<{ [key: string]: string }>((acc, [key, value]) => { + if (value !== undefined) { + acc[key] = String(value); + } + return acc; + }, {}); + return message; + }, +}; + +function createBasePolicyGroupAttachment_WithEntry(): PolicyGroupAttachment_WithEntry { + return { key: "", value: "" }; +} + +export const PolicyGroupAttachment_WithEntry = { + encode(message: PolicyGroupAttachment_WithEntry, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.value !== "") { + writer.uint32(18).string(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PolicyGroupAttachment_WithEntry { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicyGroupAttachment_WithEntry(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.key = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.value = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PolicyGroupAttachment_WithEntry { + return { key: isSet(object.key) ? String(object.key) : "", value: isSet(object.value) ? String(object.value) : "" }; + }, + + toJSON(message: PolicyGroupAttachment_WithEntry): unknown { + const obj: any = {}; + message.key !== undefined && (obj.key = message.key); + message.value !== undefined && (obj.value = message.value); + return obj; + }, + + create, I>>(base?: I): PolicyGroupAttachment_WithEntry { + return PolicyGroupAttachment_WithEntry.fromPartial(base ?? {}); + }, + + fromPartial, I>>( + object: I, + ): PolicyGroupAttachment_WithEntry { + const message = createBasePolicyGroupAttachment_WithEntry(); + message.key = object.key ?? ""; + message.value = object.value ?? ""; return message; }, }; @@ -1814,7 +2048,7 @@ export const PolicyGroup = { }; function createBasePolicyGroup_PolicyGroupSpec(): PolicyGroup_PolicyGroupSpec { - return { policies: undefined }; + return { policies: undefined, inputs: [] }; } export const PolicyGroup_PolicyGroupSpec = { @@ -1822,6 +2056,9 @@ export const PolicyGroup_PolicyGroupSpec = { if (message.policies !== undefined) { PolicyGroup_PolicyGroupPolicies.encode(message.policies, writer.uint32(10).fork()).ldelim(); } + for (const v of message.inputs) { + PolicyInput.encode(v!, writer.uint32(18).fork()).ldelim(); + } return writer; }, @@ -1839,6 +2076,13 @@ export const PolicyGroup_PolicyGroupSpec = { message.policies = PolicyGroup_PolicyGroupPolicies.decode(reader, reader.uint32()); continue; + case 2: + if (tag !== 18) { + break; + } + + message.inputs.push(PolicyInput.decode(reader, reader.uint32())); + continue; } if ((tag & 7) === 4 || tag === 0) { break; @@ -1849,13 +2093,21 @@ export const PolicyGroup_PolicyGroupSpec = { }, fromJSON(object: any): PolicyGroup_PolicyGroupSpec { - return { policies: isSet(object.policies) ? PolicyGroup_PolicyGroupPolicies.fromJSON(object.policies) : undefined }; + return { + policies: isSet(object.policies) ? PolicyGroup_PolicyGroupPolicies.fromJSON(object.policies) : undefined, + inputs: Array.isArray(object?.inputs) ? object.inputs.map((e: any) => PolicyInput.fromJSON(e)) : [], + }; }, toJSON(message: PolicyGroup_PolicyGroupSpec): unknown { const obj: any = {}; message.policies !== undefined && (obj.policies = message.policies ? PolicyGroup_PolicyGroupPolicies.toJSON(message.policies) : undefined); + if (message.inputs) { + obj.inputs = message.inputs.map((e) => e ? PolicyInput.toJSON(e) : undefined); + } else { + obj.inputs = []; + } return obj; }, @@ -1868,6 +2120,7 @@ export const PolicyGroup_PolicyGroupSpec = { message.policies = (object.policies !== undefined && object.policies !== null) ? PolicyGroup_PolicyGroupPolicies.fromPartial(object.policies) : undefined; + message.inputs = object.inputs?.map((e) => PolicyInput.fromPartial(e)) || []; return message; }, }; diff --git a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroup.PolicyGroupSpec.jsonschema.json b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroup.PolicyGroupSpec.jsonschema.json index bf5bade8c..87743aec3 100644 --- a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroup.PolicyGroupSpec.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroup.PolicyGroupSpec.jsonschema.json @@ -3,6 +3,12 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { + "inputs": { + "items": { + "$ref": "workflowcontract.v1.PolicyInput.jsonschema.json" + }, + "type": "array" + }, "policies": { "$ref": "workflowcontract.v1.PolicyGroup.PolicyGroupPolicies.jsonschema.json" } diff --git a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroup.PolicyGroupSpec.schema.json b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroup.PolicyGroupSpec.schema.json index 4a48bea22..f3154cf56 100644 --- a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroup.PolicyGroupSpec.schema.json +++ b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroup.PolicyGroupSpec.schema.json @@ -3,6 +3,12 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { + "inputs": { + "items": { + "$ref": "workflowcontract.v1.PolicyInput.schema.json" + }, + "type": "array" + }, "policies": { "$ref": "workflowcontract.v1.PolicyGroup.PolicyGroupPolicies.schema.json" } diff --git a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroupAttachment.jsonschema.json b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroupAttachment.jsonschema.json index 8e8ec8221..0ee7d3d85 100644 --- a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroupAttachment.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroupAttachment.jsonschema.json @@ -7,6 +7,16 @@ "ref": { "description": "Group reference, it might be an URL or a provider reference", "type": "string" + }, + "with": { + "additionalProperties": { + "type": "string" + }, + "description": "group arguments", + "propertyNames": { + "type": "string" + }, + "type": "object" } }, "title": "Policy Group Attachment", diff --git a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroupAttachment.schema.json b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroupAttachment.schema.json index bc6ecc28d..a82541a42 100644 --- a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroupAttachment.schema.json +++ b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyGroupAttachment.schema.json @@ -7,6 +7,16 @@ "ref": { "description": "Group reference, it might be an URL or a provider reference", "type": "string" + }, + "with": { + "additionalProperties": { + "type": "string" + }, + "description": "group arguments", + "propertyNames": { + "type": "string" + }, + "type": "object" } }, "title": "Policy Group Attachment", diff --git a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyInput.jsonschema.json b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyInput.jsonschema.json new file mode 100644 index 000000000..5f61fc89d --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyInput.jsonschema.json @@ -0,0 +1,21 @@ +{ + "$id": "workflowcontract.v1.PolicyInput.jsonschema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "default": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "required": { + "type": "boolean" + } + }, + "title": "Policy Input", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyInput.schema.json b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyInput.schema.json new file mode 100644 index 000000000..dceee39bb --- /dev/null +++ b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicyInput.schema.json @@ -0,0 +1,21 @@ +{ + "$id": "workflowcontract.v1.PolicyInput.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "properties": { + "default": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "required": { + "type": "boolean" + } + }, + "title": "Policy Input", + "type": "object" +} diff --git a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicySpec.jsonschema.json b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicySpec.jsonschema.json index 79ccbcef8..66ad707fe 100644 --- a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicySpec.jsonschema.json +++ b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicySpec.jsonschema.json @@ -7,6 +7,13 @@ "description": "embedded source code (only Rego supported currently)", "type": "string" }, + "inputs": { + "description": "Describe the supported inputs", + "items": { + "$ref": "workflowcontract.v1.PolicyInput.jsonschema.json" + }, + "type": "array" + }, "path": { "description": "path to a policy script. It might consist of a URI reference", "type": "string" diff --git a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicySpec.schema.json b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicySpec.schema.json index 7eb9e0f72..f1b7448a1 100644 --- a/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicySpec.schema.json +++ b/app/controlplane/api/gen/jsonschema/workflowcontract.v1.PolicySpec.schema.json @@ -7,6 +7,13 @@ "description": "embedded source code (only Rego supported currently)", "type": "string" }, + "inputs": { + "description": "Describe the supported inputs", + "items": { + "$ref": "workflowcontract.v1.PolicyInput.schema.json" + }, + "type": "array" + }, "path": { "description": "path to a policy script. It might consist of a URI reference", "type": "string" diff --git a/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go b/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go index 2bc3e71f1..a1580d800 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go @@ -708,6 +708,8 @@ type PolicySpec struct { // Deprecated: Marked as deprecated in workflowcontract/v1/crafting_schema.proto. Type CraftingSchema_Material_MaterialType `protobuf:"varint,3,opt,name=type,proto3,enum=workflowcontract.v1.CraftingSchema_Material_MaterialType" json:"type,omitempty"` Policies []*PolicySpecV2 `protobuf:"bytes,4,rep,name=policies,proto3" json:"policies,omitempty"` + // Describe the supported inputs + Inputs []*PolicyInput `protobuf:"bytes,5,rep,name=inputs,proto3" json:"inputs,omitempty"` } func (x *PolicySpec) Reset() { @@ -780,6 +782,13 @@ func (x *PolicySpec) GetPolicies() []*PolicySpecV2 { return nil } +func (x *PolicySpec) GetInputs() []*PolicyInput { + if x != nil { + return x.Inputs + } + return nil +} + type isPolicySpec_Source interface { isPolicySpec_Source() } @@ -802,6 +811,77 @@ func (*PolicySpec_Path) isPolicySpec_Source() {} func (*PolicySpec_Embedded) isPolicySpec_Source() {} +type PolicyInput struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + Required bool `protobuf:"varint,3,opt,name=required,proto3" json:"required,omitempty"` + Default string `protobuf:"bytes,4,opt,name=default,proto3" json:"default,omitempty"` +} + +func (x *PolicyInput) Reset() { + *x = PolicyInput{} + if protoimpl.UnsafeEnabled { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PolicyInput) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PolicyInput) ProtoMessage() {} + +func (x *PolicyInput) ProtoReflect() protoreflect.Message { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[7] + 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 PolicyInput.ProtoReflect.Descriptor instead. +func (*PolicyInput) Descriptor() ([]byte, []int) { + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{7} +} + +func (x *PolicyInput) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *PolicyInput) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *PolicyInput) GetRequired() bool { + if x != nil { + return x.Required + } + return false +} + +func (x *PolicyInput) GetDefault() string { + if x != nil { + return x.Default + } + return "" +} + type PolicySpecV2 struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -821,7 +901,7 @@ type PolicySpecV2 struct { func (x *PolicySpecV2) Reset() { *x = PolicySpecV2{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[7] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -834,7 +914,7 @@ func (x *PolicySpecV2) String() string { func (*PolicySpecV2) ProtoMessage() {} func (x *PolicySpecV2) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[7] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -847,7 +927,7 @@ func (x *PolicySpecV2) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicySpecV2.ProtoReflect.Descriptor instead. func (*PolicySpecV2) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{7} + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{8} } func (m *PolicySpecV2) GetSource() isPolicySpecV2_Source { @@ -904,12 +984,14 @@ type PolicyGroupAttachment struct { // Group reference, it might be an URL or a provider reference Ref string `protobuf:"bytes,1,opt,name=ref,proto3" json:"ref,omitempty"` + // group arguments + With map[string]string `protobuf:"bytes,2,rep,name=with,proto3" json:"with,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *PolicyGroupAttachment) Reset() { *x = PolicyGroupAttachment{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[8] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -922,7 +1004,7 @@ func (x *PolicyGroupAttachment) String() string { func (*PolicyGroupAttachment) ProtoMessage() {} func (x *PolicyGroupAttachment) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[8] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -935,7 +1017,7 @@ func (x *PolicyGroupAttachment) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyGroupAttachment.ProtoReflect.Descriptor instead. func (*PolicyGroupAttachment) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{8} + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{9} } func (x *PolicyGroupAttachment) GetRef() string { @@ -945,6 +1027,13 @@ func (x *PolicyGroupAttachment) GetRef() string { return "" } +func (x *PolicyGroupAttachment) GetWith() map[string]string { + if x != nil { + return x.With + } + return nil +} + // Represents a group or policies type PolicyGroup struct { state protoimpl.MessageState @@ -960,7 +1049,7 @@ type PolicyGroup struct { func (x *PolicyGroup) Reset() { *x = PolicyGroup{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[9] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -973,7 +1062,7 @@ func (x *PolicyGroup) String() string { func (*PolicyGroup) ProtoMessage() {} func (x *PolicyGroup) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[9] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -986,7 +1075,7 @@ func (x *PolicyGroup) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyGroup.ProtoReflect.Descriptor instead. func (*PolicyGroup) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{9} + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{10} } func (x *PolicyGroup) GetApiVersion() string { @@ -1028,7 +1117,7 @@ type CraftingSchema_Runner struct { func (x *CraftingSchema_Runner) Reset() { *x = CraftingSchema_Runner{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[10] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1041,7 +1130,7 @@ func (x *CraftingSchema_Runner) String() string { func (*CraftingSchema_Runner) ProtoMessage() {} func (x *CraftingSchema_Runner) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[10] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1084,7 +1173,7 @@ type CraftingSchema_Material struct { func (x *CraftingSchema_Material) Reset() { *x = CraftingSchema_Material{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[11] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1097,7 +1186,7 @@ func (x *CraftingSchema_Material) String() string { func (*CraftingSchema_Material) ProtoMessage() {} func (x *CraftingSchema_Material) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[11] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1167,7 +1256,7 @@ type PolicyAttachment_MaterialSelector struct { func (x *PolicyAttachment_MaterialSelector) Reset() { *x = PolicyAttachment_MaterialSelector{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[13] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1180,7 +1269,7 @@ func (x *PolicyAttachment_MaterialSelector) String() string { func (*PolicyAttachment_MaterialSelector) ProtoMessage() {} func (x *PolicyAttachment_MaterialSelector) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[13] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1209,12 +1298,13 @@ type PolicyGroup_PolicyGroupSpec struct { unknownFields protoimpl.UnknownFields Policies *PolicyGroup_PolicyGroupPolicies `protobuf:"bytes,1,opt,name=policies,proto3" json:"policies,omitempty"` + Inputs []*PolicyInput `protobuf:"bytes,2,rep,name=inputs,proto3" json:"inputs,omitempty"` } func (x *PolicyGroup_PolicyGroupSpec) Reset() { *x = PolicyGroup_PolicyGroupSpec{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[15] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1227,7 +1317,7 @@ func (x *PolicyGroup_PolicyGroupSpec) String() string { func (*PolicyGroup_PolicyGroupSpec) ProtoMessage() {} func (x *PolicyGroup_PolicyGroupSpec) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[15] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1240,7 +1330,7 @@ func (x *PolicyGroup_PolicyGroupSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyGroup_PolicyGroupSpec.ProtoReflect.Descriptor instead. func (*PolicyGroup_PolicyGroupSpec) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{9, 0} + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{10, 0} } func (x *PolicyGroup_PolicyGroupSpec) GetPolicies() *PolicyGroup_PolicyGroupPolicies { @@ -1250,6 +1340,13 @@ func (x *PolicyGroup_PolicyGroupSpec) GetPolicies() *PolicyGroup_PolicyGroupPoli return nil } +func (x *PolicyGroup_PolicyGroupSpec) GetInputs() []*PolicyInput { + if x != nil { + return x.Inputs + } + return nil +} + type PolicyGroup_PolicyGroupPolicies struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1262,7 +1359,7 @@ type PolicyGroup_PolicyGroupPolicies struct { func (x *PolicyGroup_PolicyGroupPolicies) Reset() { *x = PolicyGroup_PolicyGroupPolicies{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[16] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1275,7 +1372,7 @@ func (x *PolicyGroup_PolicyGroupPolicies) String() string { func (*PolicyGroup_PolicyGroupPolicies) ProtoMessage() {} func (x *PolicyGroup_PolicyGroupPolicies) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[16] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1288,7 +1385,7 @@ func (x *PolicyGroup_PolicyGroupPolicies) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyGroup_PolicyGroupPolicies.ProtoReflect.Descriptor instead. func (*PolicyGroup_PolicyGroupPolicies) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{9, 1} + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{10, 1} } func (x *PolicyGroup_PolicyGroupPolicies) GetMaterials() []*CraftingSchema_Material { @@ -1494,7 +1591,7 @@ var file_workflowcontract_v1_crafting_schema_proto_rawDesc = []byte{ 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, 0x22, 0xff, 0x02, 0x0a, 0x0a, 0x50, 0x6f, 0x6c, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb9, 0x03, 0x0a, 0x0a, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, @@ -1509,31 +1606,59 @@ var file_workflowcontract_v1_crafting_schema_proto_rawDesc = []byte{ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x70, 0x65, 0x63, 0x56, 0x32, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, - 0x73, 0x3a, 0x8c, 0x01, 0xba, 0x48, 0x88, 0x01, 0x1a, 0x85, 0x01, 0x0a, 0x0a, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x73, 0x70, 0x65, 0x63, 0x12, 0x36, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, - 0x73, 0x70, 0x65, 0x63, 0x20, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x6d, - 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x1a, - 0x3f, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x29, 0x20, - 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x6d, 0x62, 0x65, - 0x64, 0x64, 0x65, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, - 0x69, 0x73, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, - 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x0c, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x70, 0x65, 0x63, 0x56, 0x32, 0x12, 0x14, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x12, 0x1c, 0x0a, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, - 0x5b, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x4d, 0x61, 0x74, 0x65, - 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x42, 0x0c, 0xba, 0x48, 0x09, 0x82, 0x01, 0x06, - 0x22, 0x04, 0x01, 0x03, 0x0a, 0x0b, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x42, 0x0f, 0x0a, 0x06, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0x32, 0x0a, - 0x15, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x74, 0x74, 0x61, - 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x72, 0x65, - 0x66, 0x22, 0xa3, 0x04, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, + 0x73, 0x12, 0x38, 0x0a, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x20, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x6e, + 0x70, 0x75, 0x74, 0x52, 0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x3a, 0x8c, 0x01, 0xba, 0x48, + 0x88, 0x01, 0x1a, 0x85, 0x01, 0x0a, 0x0a, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x73, 0x70, 0x65, + 0x63, 0x12, 0x36, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x73, 0x70, 0x65, 0x63, 0x20, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, + 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x1a, 0x3f, 0x68, 0x61, 0x73, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x70, 0x61, 0x74, 0x68, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x29, 0x20, + 0x7c, 0x7c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x69, 0x65, 0x73, 0x29, 0x20, 0x3e, 0x20, 0x30, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x22, 0xff, 0x01, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, + 0x6e, 0x70, 0x75, 0x74, 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, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x22, 0xb0, 0x01, 0x0a, 0x0c, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x53, 0x70, 0x65, 0x63, 0x56, 0x32, 0x12, 0x14, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1c, 0x0a, + 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, 0x5b, 0x0a, 0x04, 0x6b, + 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 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, 0x2e, 0x4d, + 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, + 0x54, 0x79, 0x70, 0x65, 0x42, 0x0c, 0xba, 0x48, 0x09, 0x82, 0x01, 0x06, 0x22, 0x04, 0x01, 0x03, + 0x0a, 0x0b, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x42, 0x0f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x22, 0xb5, 0x01, 0x0a, 0x15, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, + 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x48, + 0x0a, 0x04, 0x77, 0x69, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x74, + 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x04, 0x77, 0x69, 0x74, 0x68, 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, 0x22, 0xde, 0x04, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x49, 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x28, 0xba, 0x48, 0x25, 0x72, 0x23, 0x0a, 0x21, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, @@ -1550,29 +1675,33 @@ var file_workflowcontract_v1_crafting_schema_proto_rawDesc = []byte{ 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x70, 0x65, 0x63, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, - 0x04, 0x73, 0x70, 0x65, 0x63, 0x1a, 0x63, 0x0a, 0x0f, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x70, 0x65, 0x63, 0x12, 0x50, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x1a, 0xaa, 0x01, 0x0a, 0x13, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x09, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, - 0x69, 0x61, 0x6c, 0x52, 0x09, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x47, - 0x0a, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, - 0x64, 0x65, 0x76, 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, - 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x61, 0x63, 0x74, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x04, 0x73, 0x70, 0x65, 0x63, 0x1a, 0x9d, 0x01, 0x0a, 0x0f, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x70, 0x65, 0x63, 0x12, 0x50, 0x0a, 0x08, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, + 0x73, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x06, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x06, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x73, 0x1a, 0xaa, 0x01, 0x0a, 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x4a, 0x0a, + 0x09, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2c, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x52, 0x09, + 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x0b, 0x61, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x74, 0x74, 0x61, 0x63, + 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x4d, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2f, 0x76, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1588,7 +1717,7 @@ func file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP() []byte { } var file_workflowcontract_v1_crafting_schema_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_workflowcontract_v1_crafting_schema_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_workflowcontract_v1_crafting_schema_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_workflowcontract_v1_crafting_schema_proto_goTypes = []interface{}{ (CraftingSchema_Runner_RunnerType)(0), // 0: workflowcontract.v1.CraftingSchema.Runner.RunnerType (CraftingSchema_Material_MaterialType)(0), // 1: workflowcontract.v1.CraftingSchema.Material.MaterialType @@ -1599,48 +1728,53 @@ var file_workflowcontract_v1_crafting_schema_proto_goTypes = []interface{}{ (*Policy)(nil), // 6: workflowcontract.v1.Policy (*Metadata)(nil), // 7: workflowcontract.v1.Metadata (*PolicySpec)(nil), // 8: workflowcontract.v1.PolicySpec - (*PolicySpecV2)(nil), // 9: workflowcontract.v1.PolicySpecV2 - (*PolicyGroupAttachment)(nil), // 10: workflowcontract.v1.PolicyGroupAttachment - (*PolicyGroup)(nil), // 11: workflowcontract.v1.PolicyGroup - (*CraftingSchema_Runner)(nil), // 12: workflowcontract.v1.CraftingSchema.Runner - (*CraftingSchema_Material)(nil), // 13: workflowcontract.v1.CraftingSchema.Material - nil, // 14: workflowcontract.v1.PolicyAttachment.WithEntry - (*PolicyAttachment_MaterialSelector)(nil), // 15: workflowcontract.v1.PolicyAttachment.MaterialSelector - nil, // 16: workflowcontract.v1.Metadata.AnnotationsEntry - (*PolicyGroup_PolicyGroupSpec)(nil), // 17: workflowcontract.v1.PolicyGroup.PolicyGroupSpec - (*PolicyGroup_PolicyGroupPolicies)(nil), // 18: workflowcontract.v1.PolicyGroup.PolicyGroupPolicies + (*PolicyInput)(nil), // 9: workflowcontract.v1.PolicyInput + (*PolicySpecV2)(nil), // 10: workflowcontract.v1.PolicySpecV2 + (*PolicyGroupAttachment)(nil), // 11: workflowcontract.v1.PolicyGroupAttachment + (*PolicyGroup)(nil), // 12: workflowcontract.v1.PolicyGroup + (*CraftingSchema_Runner)(nil), // 13: workflowcontract.v1.CraftingSchema.Runner + (*CraftingSchema_Material)(nil), // 14: workflowcontract.v1.CraftingSchema.Material + nil, // 15: workflowcontract.v1.PolicyAttachment.WithEntry + (*PolicyAttachment_MaterialSelector)(nil), // 16: workflowcontract.v1.PolicyAttachment.MaterialSelector + nil, // 17: workflowcontract.v1.Metadata.AnnotationsEntry + nil, // 18: workflowcontract.v1.PolicyGroupAttachment.WithEntry + (*PolicyGroup_PolicyGroupSpec)(nil), // 19: workflowcontract.v1.PolicyGroup.PolicyGroupSpec + (*PolicyGroup_PolicyGroupPolicies)(nil), // 20: workflowcontract.v1.PolicyGroup.PolicyGroupPolicies } var file_workflowcontract_v1_crafting_schema_proto_depIdxs = []int32{ - 13, // 0: workflowcontract.v1.CraftingSchema.materials:type_name -> workflowcontract.v1.CraftingSchema.Material - 12, // 1: workflowcontract.v1.CraftingSchema.runner:type_name -> workflowcontract.v1.CraftingSchema.Runner + 14, // 0: workflowcontract.v1.CraftingSchema.materials:type_name -> workflowcontract.v1.CraftingSchema.Material + 13, // 1: workflowcontract.v1.CraftingSchema.runner:type_name -> workflowcontract.v1.CraftingSchema.Runner 3, // 2: workflowcontract.v1.CraftingSchema.annotations:type_name -> workflowcontract.v1.Annotation 4, // 3: workflowcontract.v1.CraftingSchema.policies:type_name -> workflowcontract.v1.Policies - 10, // 4: workflowcontract.v1.CraftingSchema.policy_groups:type_name -> workflowcontract.v1.PolicyGroupAttachment + 11, // 4: workflowcontract.v1.CraftingSchema.policy_groups:type_name -> workflowcontract.v1.PolicyGroupAttachment 5, // 5: workflowcontract.v1.Policies.materials:type_name -> workflowcontract.v1.PolicyAttachment 5, // 6: workflowcontract.v1.Policies.attestation:type_name -> workflowcontract.v1.PolicyAttachment 6, // 7: workflowcontract.v1.PolicyAttachment.embedded:type_name -> workflowcontract.v1.Policy - 15, // 8: workflowcontract.v1.PolicyAttachment.selector:type_name -> workflowcontract.v1.PolicyAttachment.MaterialSelector - 14, // 9: workflowcontract.v1.PolicyAttachment.with:type_name -> workflowcontract.v1.PolicyAttachment.WithEntry + 16, // 8: workflowcontract.v1.PolicyAttachment.selector:type_name -> workflowcontract.v1.PolicyAttachment.MaterialSelector + 15, // 9: workflowcontract.v1.PolicyAttachment.with:type_name -> workflowcontract.v1.PolicyAttachment.WithEntry 7, // 10: workflowcontract.v1.Policy.metadata:type_name -> workflowcontract.v1.Metadata 8, // 11: workflowcontract.v1.Policy.spec:type_name -> workflowcontract.v1.PolicySpec - 16, // 12: workflowcontract.v1.Metadata.annotations:type_name -> workflowcontract.v1.Metadata.AnnotationsEntry + 17, // 12: workflowcontract.v1.Metadata.annotations:type_name -> workflowcontract.v1.Metadata.AnnotationsEntry 1, // 13: workflowcontract.v1.PolicySpec.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 9, // 14: workflowcontract.v1.PolicySpec.policies:type_name -> workflowcontract.v1.PolicySpecV2 - 1, // 15: workflowcontract.v1.PolicySpecV2.kind:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 7, // 16: workflowcontract.v1.PolicyGroup.metadata:type_name -> workflowcontract.v1.Metadata - 17, // 17: workflowcontract.v1.PolicyGroup.spec:type_name -> workflowcontract.v1.PolicyGroup.PolicyGroupSpec - 0, // 18: workflowcontract.v1.CraftingSchema.Runner.type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType - 1, // 19: workflowcontract.v1.CraftingSchema.Material.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 3, // 20: workflowcontract.v1.CraftingSchema.Material.annotations:type_name -> workflowcontract.v1.Annotation - 5, // 21: workflowcontract.v1.CraftingSchema.Material.policies:type_name -> workflowcontract.v1.PolicyAttachment - 18, // 22: workflowcontract.v1.PolicyGroup.PolicyGroupSpec.policies:type_name -> workflowcontract.v1.PolicyGroup.PolicyGroupPolicies - 13, // 23: workflowcontract.v1.PolicyGroup.PolicyGroupPolicies.materials:type_name -> workflowcontract.v1.CraftingSchema.Material - 5, // 24: workflowcontract.v1.PolicyGroup.PolicyGroupPolicies.attestation:type_name -> workflowcontract.v1.PolicyAttachment - 25, // [25:25] is the sub-list for method output_type - 25, // [25:25] is the sub-list for method input_type - 25, // [25:25] is the sub-list for extension type_name - 25, // [25:25] is the sub-list for extension extendee - 0, // [0:25] is the sub-list for field type_name + 10, // 14: workflowcontract.v1.PolicySpec.policies:type_name -> workflowcontract.v1.PolicySpecV2 + 9, // 15: workflowcontract.v1.PolicySpec.inputs:type_name -> workflowcontract.v1.PolicyInput + 1, // 16: workflowcontract.v1.PolicySpecV2.kind:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 18, // 17: workflowcontract.v1.PolicyGroupAttachment.with:type_name -> workflowcontract.v1.PolicyGroupAttachment.WithEntry + 7, // 18: workflowcontract.v1.PolicyGroup.metadata:type_name -> workflowcontract.v1.Metadata + 19, // 19: workflowcontract.v1.PolicyGroup.spec:type_name -> workflowcontract.v1.PolicyGroup.PolicyGroupSpec + 0, // 20: workflowcontract.v1.CraftingSchema.Runner.type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType + 1, // 21: workflowcontract.v1.CraftingSchema.Material.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 3, // 22: workflowcontract.v1.CraftingSchema.Material.annotations:type_name -> workflowcontract.v1.Annotation + 5, // 23: workflowcontract.v1.CraftingSchema.Material.policies:type_name -> workflowcontract.v1.PolicyAttachment + 20, // 24: workflowcontract.v1.PolicyGroup.PolicyGroupSpec.policies:type_name -> workflowcontract.v1.PolicyGroup.PolicyGroupPolicies + 9, // 25: workflowcontract.v1.PolicyGroup.PolicyGroupSpec.inputs:type_name -> workflowcontract.v1.PolicyInput + 14, // 26: workflowcontract.v1.PolicyGroup.PolicyGroupPolicies.materials:type_name -> workflowcontract.v1.CraftingSchema.Material + 5, // 27: workflowcontract.v1.PolicyGroup.PolicyGroupPolicies.attestation:type_name -> workflowcontract.v1.PolicyAttachment + 28, // [28:28] is the sub-list for method output_type + 28, // [28:28] is the sub-list for method input_type + 28, // [28:28] is the sub-list for extension type_name + 28, // [28:28] is the sub-list for extension extendee + 0, // [0:28] is the sub-list for field type_name } func init() { file_workflowcontract_v1_crafting_schema_proto_init() } @@ -1734,7 +1868,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicySpecV2); i { + switch v := v.(*PolicyInput); i { case 0: return &v.state case 1: @@ -1746,7 +1880,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicyGroupAttachment); i { + switch v := v.(*PolicySpecV2); i { case 0: return &v.state case 1: @@ -1758,7 +1892,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicyGroup); i { + switch v := v.(*PolicyGroupAttachment); i { case 0: return &v.state case 1: @@ -1770,7 +1904,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CraftingSchema_Runner); i { + switch v := v.(*PolicyGroup); i { case 0: return &v.state case 1: @@ -1782,6 +1916,18 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CraftingSchema_Runner); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_workflowcontract_v1_crafting_schema_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CraftingSchema_Material); i { case 0: return &v.state @@ -1793,7 +1939,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { return nil } } - file_workflowcontract_v1_crafting_schema_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_workflowcontract_v1_crafting_schema_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PolicyAttachment_MaterialSelector); i { case 0: return &v.state @@ -1805,7 +1951,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { return nil } } - file_workflowcontract_v1_crafting_schema_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_workflowcontract_v1_crafting_schema_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PolicyGroup_PolicyGroupSpec); i { case 0: return &v.state @@ -1817,7 +1963,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { return nil } } - file_workflowcontract_v1_crafting_schema_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_workflowcontract_v1_crafting_schema_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PolicyGroup_PolicyGroupPolicies); i { case 0: return &v.state @@ -1838,7 +1984,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { (*PolicySpec_Path)(nil), (*PolicySpec_Embedded)(nil), } - file_workflowcontract_v1_crafting_schema_proto_msgTypes[7].OneofWrappers = []interface{}{ + file_workflowcontract_v1_crafting_schema_proto_msgTypes[8].OneofWrappers = []interface{}{ (*PolicySpecV2_Path)(nil), (*PolicySpecV2_Embedded)(nil), } @@ -1848,7 +1994,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_workflowcontract_v1_crafting_schema_proto_rawDesc, NumEnums: 2, - NumMessages: 17, + NumMessages: 19, NumExtensions: 0, NumServices: 0, }, diff --git a/app/controlplane/api/workflowcontract/v1/crafting_schema.proto b/app/controlplane/api/workflowcontract/v1/crafting_schema.proto index e997b3b1d..25c41c50b 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema.proto +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema.proto @@ -225,6 +225,9 @@ message PolicySpec { repeated PolicySpecV2 policies = 4; + // Describe the supported inputs + repeated PolicyInput inputs = 5; + option (buf.validate.message).cel = { id: "policyspec" message: "either spec source or policies fields must be provided" @@ -232,6 +235,20 @@ message PolicySpec { }; } +message PolicyInput { + string name = 1 [(buf.validate.field) = { + // NOTE: validations can not be shared yet https://github.com/bufbuild/protovalidate/issues/51 + cel: { + message: "must contain only lowercase letters, numbers, and hyphens." + expression: "this.matches('^[a-z0-9]([-a-z0-9]*[a-z0-9])?$')" + id: "name.dns-1123" + } + }]; + string description = 2; + bool required = 3; + string default = 4; +} + message PolicySpecV2 { oneof source { // path to a policy script. It might consist of a URI reference @@ -260,6 +277,8 @@ message PolicySpecV2 { message PolicyGroupAttachment { // Group reference, it might be an URL or a provider reference string ref = 1 [(buf.validate.field).string.min_len = 1]; + // group arguments + map with = 2; } // Represents a group or policies @@ -272,6 +291,7 @@ message PolicyGroup { message PolicyGroupSpec { PolicyGroupPolicies policies = 1; + repeated PolicyInput inputs = 2; } message PolicyGroupPolicies { diff --git a/app/controlplane/api/workflowcontract/v1/crafting_schema_validations.go b/app/controlplane/api/workflowcontract/v1/crafting_schema_validations.go index 96270ba1c..f11428403 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema_validations.go +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema_validations.go @@ -83,8 +83,11 @@ func (schema *CraftingSchema) ValidatePolicyAttachments() error { attachments := append(schema.GetPolicies().GetAttestation(), schema.GetPolicies().GetMaterials()...) for _, att := range attachments { - if err := ValidatePolicyAttachmentRef(att.GetRef()); err != nil { - return fmt.Errorf("invalid reference %q: %w", att.GetRef(), err) + // Validate refs. + if att.GetRef() != "" { + if err := ValidatePolicyAttachmentRef(att.GetRef()); err != nil { + return fmt.Errorf("invalid reference %q: %w", att.GetRef(), err) + } } } diff --git a/app/controlplane/pkg/biz/workflowcontract.go b/app/controlplane/pkg/biz/workflowcontract.go index ddd46e74b..f2c792a87 100644 --- a/app/controlplane/pkg/biz/workflowcontract.go +++ b/app/controlplane/pkg/biz/workflowcontract.go @@ -296,12 +296,12 @@ func (uc *WorkflowContractUseCase) ValidateContractPolicies(rawSchema []byte, to } for _, att := range c.Schema.GetPolicies().GetAttestation() { - if _, err := uc.findPolicy(att, token); err != nil { + if _, err := uc.findAndValidatePolicy(att, token); err != nil { return NewErrValidation(err) } } for _, att := range c.Schema.GetPolicies().GetMaterials() { - if _, err := uc.findPolicy(att, token); err != nil { + if _, err := uc.findAndValidatePolicy(att, token); err != nil { return NewErrValidation(err) } } @@ -314,9 +314,11 @@ func (uc *WorkflowContractUseCase) ValidateContractPolicies(rawSchema []byte, to return nil } -func (uc *WorkflowContractUseCase) findPolicy(att *schemav1.PolicyAttachment, token string) (*schemav1.Policy, error) { +func (uc *WorkflowContractUseCase) findAndValidatePolicy(att *schemav1.PolicyAttachment, token string) (*schemav1.Policy, error) { + var policy *schemav1.Policy + if att.GetEmbedded() != nil { - return att.GetEmbedded(), nil + policy = att.GetEmbedded() } // if it should come from a provider, check that it's available @@ -327,11 +329,22 @@ func (uc *WorkflowContractUseCase) findPolicy(att *schemav1.PolicyAttachment, to if err != nil { return nil, err } - return remotePolicy.Policy, nil + policy = remotePolicy.Policy } - // Otherwise, don't return an error, as it might consist of a local policy, not available in this context - return nil, nil + if policy != nil { + // validate policy arguments + with := att.GetWith() + for _, input := range policy.GetSpec().GetInputs() { + _, ok := with[input.GetName()] + if !ok && input.GetRequired() { + return nil, NewErrValidation(fmt.Errorf("missing required input %q", input.GetName())) + } + } + } + + // return policy or nil, as it might not be available in this context + return policy, nil } func (uc *WorkflowContractUseCase) findPolicyGroup(att *schemav1.PolicyGroupAttachment, token string) (*schemav1.PolicyGroup, error) { @@ -346,6 +359,19 @@ func (uc *WorkflowContractUseCase) findPolicyGroup(att *schemav1.PolicyGroupAtta uc.logger.Warnf("policy group '%s' skipped since it's not found or it might use an old schema version", att.GetRef()) return nil, nil } + if remoteGroup.PolicyGroup != nil { + // validate group arguments + with := att.GetWith() + for _, input := range remoteGroup.PolicyGroup.GetSpec().GetInputs() { + _, ok := with[input.GetName()] + if !ok && input.GetRequired() { + return nil, NewErrValidation(fmt.Errorf("missing required input %q for group", input.GetName())) + } + if input.GetRequired() && input.GetDefault() != "" { + return nil, NewErrValidation(fmt.Errorf("input %s can not be required and have a default at the same time", input.GetName())) + } + } + } return remoteGroup.PolicyGroup, nil } diff --git a/docs/docs/reference/policies.mdx b/docs/docs/reference/policies.mdx index ab216a41c..e7fa1cfdb 100644 --- a/docs/docs/reference/policies.mdx +++ b/docs/docs/reference/policies.mdx @@ -128,7 +128,9 @@ There are two ways to attach a policy to a contract: In the example above, we can see that, when referenced by the `embedded` attribute (1), a full policy can be embedded in the contract. ### Policy arguments -Policies may accept arguments to customize its behaviour. For example, this policy matches a "quality" score against a "threshold" argument: +Policies may accept arguments to customize its behaviour. If defined, the `inputs` section, will be used by Chainloop to know with inputs arguments are supported by the policy + +For example, this policy matches a "quality" score against a "threshold" argument: ```yaml # quality.yaml apiVersion: workflowcontract.chainloop.dev/v1 @@ -139,27 +141,34 @@ metadata: annotations: category: sbom spec: - type: SBOM_CYCLONEDX_JSON - embedded: | - package main + inputs: #(1) + - name: threshold + description: quality threshold + required: true + policies: + - kind: SBOM_CYCLONEDX_JSON + embedded: | + package main - import rego.v1 + import rego.v1 - result := { - "skipped": false, - "violations": violations, - } + result := { + "skipped": false, + "violations": violations, + } - default threshold := 5 - threshold := to_number(input.args.threshold) # (1) + default threshold := 5 + threshold := to_number(input.args.threshold) # (2) - violations contains msg if { - input.score < threshold - msg := sprintf("quality threshold not met %d < %d", [input.score, threshold]) - } + violations contains msg if { + input.score < threshold + msg := sprintf("quality threshold not met %d < %d", [input.score, threshold]) + } ``` +* (1) the `input` section tells Chainloop which parameters should be expected. If missing, the argument will be ignored (an no value will be passed to the policy) +* (2) input parametes are available in the `input.args` rego input field. -It can be instantiated with a custom `threshold` parameter, by adding a `with` property in the policy attachment in the contract: +The above example can be instantiated with a custom `threshold` parameter, by adding a `with` property in the policy attachment in the contract: ```yaml policies: materials: diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index ac46d52a6..e1265d0f7 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -16,13 +16,16 @@ package policies import ( + "bytes" "context" "encoding/base64" "errors" "fmt" "path/filepath" + "regexp" "slices" "strings" + "text/template" "github.com/bufbuild/protovalidate-go" v13 "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" @@ -38,6 +41,8 @@ import ( "github.com/chainloop-dev/chainloop/pkg/policies/engine/rego" ) +var inputsPrefixRegexp = regexp.MustCompile(`{{\s*(inputs.)`) + type PolicyError struct { err error } @@ -103,10 +108,12 @@ func (pv *PolicyVerifier) VerifyMaterial(ctx context.Context, material *v12.Atte type evalOpts struct { name string kind v1.CraftingSchema_Material_MaterialType + // Argument bindings for policy evaluations + bindings map[string]string } func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachment *v1.PolicyAttachment, material []byte, opts *evalOpts) (*v12.PolicyEvaluation, error) { - // 1. load the policy policy + // load the policy policy policy, ref, err := pv.loadPolicySpec(ctx, attachment) if err != nil { return nil, NewPolicyError(err) @@ -131,12 +138,17 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme pv.logger.Info().Msgf("evaluating policy %s against attestation", policy.Metadata.Name) } + args, err := pv.computeArguments(policy.GetSpec().GetInputs(), attachment.GetWith(), opts.bindings) + if err != nil { + return nil, NewPolicyError(err) + } + sources := make([]string, 0) evalResults := make([]*engine.EvaluationResult, 0) skipped := true reasons := make([]string, 0) for _, script := range scripts { - r, err := pv.executeScript(ctx, policy, script, material, attachment) + r, err := pv.executeScript(ctx, policy, script, material, args) if err != nil { return nil, NewPolicyError(err) } @@ -183,6 +195,81 @@ func (pv *PolicyVerifier) evaluatePolicyAttachment(ctx context.Context, attachme }, nil } +func (pv *PolicyVerifier) computeArguments(inputs []*v1.PolicyInput, args map[string]string, bindings map[string]string) (map[string]string, error) { + result := make(map[string]string) + + // Policies without inputs in the spec + // TODO: Remove this in next release, once users have migrated their policies + if len(inputs) == 0 { + result = args + } + + // Check for required inputs + for _, input := range inputs { + // Illegal combination + if input.Required && input.Default != "" { + return nil, fmt.Errorf("input %s can not be required and have a default at the same time", input.Name) + } + if _, ok := args[input.Name]; !ok { + if input.Required { + return nil, fmt.Errorf("missing required input %q", input.Name) + } + // if not required, and it has a default value, let's use it + if args[input.Name] == "" && input.Default != "" { + value, err := applyBinding(input.Default, bindings) + if err != nil { + return nil, err + } + result[input.Name] = value + } + } + } + + // check for provided arguments + for k, v := range args { + expected := slices.ContainsFunc(inputs, func(input *v1.PolicyInput) bool { + return input.Name == k + }) + if !expected { + pv.logger.Warn().Msgf("argument %q will be ignored", k) + continue + } + value, err := applyBinding(v, bindings) + if err != nil { + return nil, err + } + result[k] = value + } + + return result, nil +} + +// renders an input template using bindings in Go templating format +func applyBinding(input string, bindings map[string]string) (string, error) { + if bindings == nil { + return input, nil + } + + // Support both `.inputs.foo` and `inputs.foo` + input = inputsPrefixRegexp.ReplaceAllString(input, "{{ .inputs.") + + tmpl, err := template.New("chainloop").Option("missingkey=zero").Parse(input) + if err != nil { + return "", err + } + + // Only support placeholders that are prefixed with "inputs.", ex `{{ inputs.foo }} + namespacedBinding := map[string]any{"inputs": bindings} + + buffer := new(bytes.Buffer) + err = tmpl.Execute(buffer, namespacedBinding) + if err != nil { + return "", err + } + + return buffer.String(), nil +} + // VerifyStatement verifies that the statement is compliant with the policies present in the schema func (pv *PolicyVerifier) VerifyStatement(ctx context.Context, statement *intoto.Statement) ([]*v12.PolicyEvaluation, error) { result := make([]*v12.PolicyEvaluation, 0) @@ -204,10 +291,10 @@ func (pv *PolicyVerifier) VerifyStatement(ctx context.Context, statement *intoto return result, nil } -func (pv *PolicyVerifier) executeScript(ctx context.Context, policy *v1.Policy, script *engine.Policy, material []byte, att *v1.PolicyAttachment) (*engine.EvaluationResult, error) { +func (pv *PolicyVerifier) executeScript(ctx context.Context, policy *v1.Policy, script *engine.Policy, material []byte, args map[string]string) (*engine.EvaluationResult, error) { // verify the policy ng := getPolicyEngine(policy) - res, err := ng.Verify(ctx, script, material, getInputArguments(att.GetWith())) + res, err := ng.Verify(ctx, script, material, getInputArguments(args)) if err != nil { return nil, fmt.Errorf("failed to execute policy : %w", err) } @@ -280,6 +367,7 @@ func validateResource(m proto.Message) error { return nil } +// transforms input arguments for policy consumption func getInputArguments(inputs map[string]string) map[string]any { args := make(map[string]any) diff --git a/pkg/policies/policies_test.go b/pkg/policies/policies_test.go index e837dc3f1..4d1ac8a1c 100644 --- a/pkg/policies/policies_test.go +++ b/pkg/policies/policies_test.go @@ -762,7 +762,7 @@ func (s *testSuite) TestLoader() { } } -func (s *testSuite) TestInputArguments() { +func (s *testSuite) TestGetInputArguments() { cases := []struct { name string inputs map[string]string @@ -818,6 +818,143 @@ func (s *testSuite) TestInputArguments() { } } +func (s *testSuite) TestComputePolicyArguments() { + cases := []struct { + name string + inputs []*v12.PolicyInput + args map[string]string + bindings map[string]string + expected map[string]string + expectErr bool + errMsg string + }{ + { + name: "all args passed when no inputs present", + inputs: nil, + args: map[string]string{"arg1": "value1", "arg2": "value2"}, + expected: map[string]string{"arg1": "value1", "arg2": "value2"}, + }, + { + name: "required inputs", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + Required: true, + }}, + args: map[string]string{"arg2": "value2"}, + expectErr: true, + errMsg: "missing required input \"arg1\"", + }, + { + name: "default values are set", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + Default: "value1", + }, { + Name: "arg2", + Required: true, + }}, + args: map[string]string{"arg2": "value2"}, + expected: map[string]string{"arg1": "value1", "arg2": "value2"}, + }, + { + name: "unexpected arguments are ignored", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + Default: "value1", + }, { + Name: "arg2", + }}, + args: map[string]string{"arg3": "value3"}, + expected: map[string]string{"arg1": "value1"}, + }, + { + name: "expected arguments with values are respected", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + Default: "value1", + }, { + Name: "arg2", + }}, + args: map[string]string{"arg1": "value1", "arg2": "value2"}, + expected: map[string]string{"arg1": "value1", "arg2": "value2"}, + }, + { + name: "simple bindings", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + }}, + args: map[string]string{"arg1": "Hello {{ .inputs.foo }}"}, + bindings: map[string]string{"foo": "world"}, + expected: map[string]string{"arg1": "Hello world"}, + }, + { + name: "multiple bindings", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + }, { + Name: "arg2", + }}, + args: map[string]string{"arg1": "Hello {{ .inputs.foo }} {{ .inputs.bar }}", "arg2": "Bye {{ .inputs.bar }}"}, + bindings: map[string]string{"foo": "world", "bar": "template"}, + expected: map[string]string{"arg1": "Hello world template", "arg2": "Bye template"}, + }, + { + name: "no variable found in bindings, renders zero value", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + }}, + args: map[string]string{"arg1": "Hello {{ .inputs.foo }}"}, + bindings: map[string]string{"bar": "world"}, + expected: map[string]string{"arg1": "Hello "}, + }, + { + name: "no interpolation needed", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + }}, + args: map[string]string{"arg1": "Hello world"}, + bindings: map[string]string{"foo": "bar"}, + expected: map[string]string{"arg1": "Hello world"}, + }, + { + name: "required and default is illegal", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + Required: true, + Default: "foo", + }}, + args: map[string]string{"arg1": "Hello world"}, + expectErr: true, + errMsg: "input arg1 can not be required and have a default at the same time", + }, + { + name: "inputs prefix without dot", + inputs: []*v12.PolicyInput{{ + Name: "arg1", + }, { + Name: "arg2", + }}, + args: map[string]string{"arg1": "Hello {{inputs.foo }} {{ inputs.bar }}", "arg2": "Bye {{ inputs.bar}}"}, + bindings: map[string]string{"foo": "world", "bar": "template"}, + expected: map[string]string{"arg1": "Hello world template", "arg2": "Bye template"}, + }, + } + + for _, tc := range cases { + s.Run(tc.name, func() { + pv := NewPolicyVerifier(nil, nil, &s.logger) + computed, err := pv.computeArguments(tc.inputs, tc.args, tc.bindings) + if tc.expectErr { + s.Error(err) + s.Contains(err.Error(), tc.errMsg) + return + } + s.NoError(err) + s.Equal(tc.expected, computed) + }) + } +} + func (s *testSuite) TestNewResultFormat() { cases := []struct { name string diff --git a/pkg/policies/policy_groups.go b/pkg/policies/policy_groups.go index b05fcd85d..283c911a1 100644 --- a/pkg/policies/policy_groups.go +++ b/pkg/policies/policy_groups.go @@ -48,26 +48,48 @@ func NewPolicyGroupVerifier(schema *v1.CraftingSchema, client v13.AttestationSer func (pgv *PolicyGroupVerifier) VerifyMaterial(ctx context.Context, material *api.Attestation_Material, path string) ([]*api.PolicyEvaluation, error) { result := make([]*api.PolicyEvaluation, 0) - attachments, err := pgv.requiredPoliciesForMaterial(ctx, material) - if err != nil { - return nil, NewPolicyError(err) - } + groupAtts := pgv.schema.GetPolicyGroups() - for _, attachment := range attachments { - // Load material content - subject, err := material.GetEvaluableContent(path) + for _, groupAtt := range groupAtts { + // 1. load the policy group + group, _, err := LoadPolicyGroup(ctx, groupAtt, &LoadPolicyGroupOptions{ + Client: pgv.client, + Logger: pgv.logger, + }) + if err != nil { + // Temporarily skip if policy groups still use old schema + // TODO: remove this check in next release + pgv.logger.Warn().Msgf("policy group '%s' skipped since it's not found or it might use an old schema version", groupAtt.GetRef()) + return result, nil + } + + policyAtts, err := pgv.requiredPoliciesForMaterial(ctx, material, group) if err != nil { return nil, NewPolicyError(err) } - ev, err := pgv.evaluatePolicyAttachment(ctx, attachment, subject, - &evalOpts{kind: material.MaterialType, name: material.GetID()}, - ) + // compute group arguments + groupArgs, err := pgv.computeArguments(group.GetSpec().GetInputs(), groupAtt.GetWith(), nil) if err != nil { return nil, NewPolicyError(err) } - result = append(result, ev) + for _, policyAtt := range policyAtts { + // Load material content + subject, err := material.GetEvaluableContent(path) + if err != nil { + return nil, NewPolicyError(err) + } + + ev, err := pgv.evaluatePolicyAttachment(ctx, policyAtt, subject, + &evalOpts{kind: material.MaterialType, name: material.GetID(), bindings: groupArgs}, + ) + if err != nil { + return nil, NewPolicyError(err) + } + + result = append(result, ev) + } } return result, nil @@ -87,6 +109,11 @@ func (pgv *PolicyGroupVerifier) VerifyStatement(ctx context.Context, statement * pgv.logger.Warn().Msgf("policy group '%s' skipped since it's not found or it might use an old schema version", groupAtt.GetRef()) continue } + // compute group arguments + groupArgs, err := pgv.computeArguments(group.GetSpec().GetInputs(), groupAtt.GetWith(), nil) + if err != nil { + return nil, NewPolicyError(err) + } for _, attachment := range group.GetSpec().GetPolicies().GetAttestation() { material, err := protojson.Marshal(statement) if err != nil { @@ -94,7 +121,7 @@ func (pgv *PolicyGroupVerifier) VerifyStatement(ctx context.Context, statement * } ev, err := pgv.evaluatePolicyAttachment(ctx, attachment, material, - &evalOpts{kind: v1.CraftingSchema_Material_ATTESTATION}, + &evalOpts{kind: v1.CraftingSchema_Material_ATTESTATION, bindings: groupArgs}, ) if err != nil { return nil, NewPolicyError(err) @@ -159,40 +186,25 @@ func getGroupLoader(attachment *v1.PolicyGroupAttachment, opts *LoadPolicyGroupO return loader, nil } -func (pgv *PolicyGroupVerifier) requiredPoliciesForMaterial(ctx context.Context, material *api.Attestation_Material) ([]*v1.PolicyAttachment, error) { +// Gets the policies that can be applied to a material within a group +func (pgv *PolicyGroupVerifier) requiredPoliciesForMaterial(ctx context.Context, material *api.Attestation_Material, group *v1.PolicyGroup) ([]*v1.PolicyAttachment, error) { result := make([]*v1.PolicyAttachment, 0) - attachments := pgv.schema.GetPolicyGroups() - - for _, attachment := range attachments { - // 1. load the policy group - group, _, err := LoadPolicyGroup(ctx, attachment, &LoadPolicyGroupOptions{ - Client: pgv.client, - Logger: pgv.logger, - }) - if err != nil { - // Temporarily skip if policy groups still use old schema - // TODO: remove this check in next release - pgv.logger.Warn().Msgf("policy group '%s' skipped since it's not found or it might use an old schema version", attachment.GetRef()) + // 2. go through all materials in the group and look for the crafted material + for _, schemaMaterial := range group.GetSpec().GetPolicies().GetMaterials() { + if schemaMaterial.GetName() != material.GetID() { continue } - // 2. go through all materials in the group and look for the crafted material - for _, schemaMaterial := range group.GetSpec().GetPolicies().GetMaterials() { - if schemaMaterial.GetName() != material.GetID() { - continue + // 3. Material found. Let's check its policies + for _, policyAtt := range schemaMaterial.GetPolicies() { + apply, err := pgv.shouldApplyPolicy(ctx, policyAtt, material) + if err != nil { + return nil, err } - // 3. Material found. Let's check its policies - for _, policyAtt := range schemaMaterial.GetPolicies() { - apply, err := pgv.shouldApplyPolicy(ctx, policyAtt, material) - if err != nil { - return nil, err - } - - if apply { - result = append(result, policyAtt) - } + if apply { + result = append(result, policyAtt) } } } diff --git a/pkg/policies/policy_groups_test.go b/pkg/policies/policy_groups_test.go index cffb5c952..a4ab63778 100644 --- a/pkg/policies/policy_groups_test.go +++ b/pkg/policies/policy_groups_test.go @@ -151,7 +151,11 @@ func (s *groupsTestSuite) TestRequiredPoliciesForMaterial() { } v := NewPolicyGroupVerifier(schema, nil, &s.logger) - atts, err := v.requiredPoliciesForMaterial(context.TODO(), material) + group, _, err := new(FileGroupLoader).Load(context.TODO(), &v1.PolicyGroupAttachment{ + Ref: tc.schemaRef, + }) + s.Require().NoError(err) + atts, err := v.requiredPoliciesForMaterial(context.TODO(), material, group) s.Require().NoError(err) s.Len(atts, tc.expected) }) @@ -204,7 +208,7 @@ func (s *groupsTestSuite) TestGroupLoader() { } } -func (s *groupsTestSuite) TestVerifyAttestations() { +func (s *groupsTestSuite) TestVerifyStatement() { cases := []struct { name string schema *v1.CraftingSchema @@ -249,3 +253,59 @@ func (s *groupsTestSuite) TestVerifyAttestations() { }) } } + +func (s *groupsTestSuite) TestGroupInputs() { + cases := []struct { + name string + args map[string]string + wanted string + wantErr bool + errMsg string + }{ + { + name: "group inputs with interpolation, default values", + args: map[string]string{"username": "devel"}, + wanted: "the email is: devel@chainloop.dev", + }, + { + name: "missing username input", + wantErr: true, + errMsg: "missing required input \"username\"", + }, + { + name: "group inputs with interpolation, all values", + args: map[string]string{"username": "foo", "domain": "bar.com"}, + wanted: "the email is: foo@bar.com", + }, + } + + for _, tc := range cases { + schema := &v1.CraftingSchema{ + PolicyGroups: []*v1.PolicyGroupAttachment{ + { + Ref: "file://testdata/group_with_inputs.yaml", + With: tc.args, + }, + }, + } + material := &api.Attestation_Material{ + M: &api.Attestation_Material_Artifact_{Artifact: &api.Attestation_Material_Artifact{Id: "sbom", + Content: []byte(`{}`), // content not validated in this context + }}, + MaterialType: v1.CraftingSchema_Material_SBOM_CYCLONEDX_JSON, + InlineCas: true, + } + s.Run(tc.name, func() { + v := NewPolicyGroupVerifier(schema, nil, &s.logger) + evs, err := v.VerifyMaterial(context.TODO(), material, "") + if tc.wantErr { + s.Error(err) + s.Contains(err.Error(), tc.errMsg) + return + } + s.Require().NoError(err) + s.Len(evs, 1) + s.Equal(tc.wanted, evs[0].SkipReasons[0]) + }) + } +} diff --git a/pkg/policies/testdata/group_with_inputs.yaml b/pkg/policies/testdata/group_with_inputs.yaml new file mode 100644 index 000000000..f85b5794a --- /dev/null +++ b/pkg/policies/testdata/group_with_inputs.yaml @@ -0,0 +1,23 @@ +apiVersion: workflowcontract.chainloop.dev/v1 +kind: PolicyGroup +metadata: + name: group-with-inputs + description: test group + annotations: + category: test +spec: + inputs: + - name: username + required: true + - name: domain + required: false + default: "chainloop.dev" + policies: + materials: + - name: sbom + type: SBOM_CYCLONEDX_JSON + policies: + - ref: file://testdata/policy_with_inputs.yaml + with: + email: "{{inputs.username}}@{{inputs.domain}}" + diff --git a/pkg/policies/testdata/policy_with_inputs.yaml b/pkg/policies/testdata/policy_with_inputs.yaml new file mode 100644 index 000000000..b5868c0be --- /dev/null +++ b/pkg/policies/testdata/policy_with_inputs.yaml @@ -0,0 +1,23 @@ +apiVersion: workflowcontract.chainloop.dev/v1 +kind: Policy +metadata: + name: policy-with-inputs + description: Policy with inputs + annotations: + category: SBOM +spec: + inputs: + - name: email + required: true + policies: + - kind: SBOM_CYCLONEDX_JSON + embedded: | + package main + + import rego.v1 + + result := { + "skipped": true, + "violations": [], + "skip_reason": sprintf("the email is: %s", [input.args.email]), + }