diff --git a/app/cli/internal/action/attestation_push.go b/app/cli/internal/action/attestation_push.go index 9a8da31d6..15956f77a 100644 --- a/app/cli/internal/action/attestation_push.go +++ b/app/cli/internal/action/attestation_push.go @@ -143,13 +143,14 @@ func (action *AttestationPush) Run(ctx context.Context, attestationID string, ru if err != nil { return nil, fmt.Errorf("creating signer: %w", err) } + renderer, err := renderer.NewAttestationRenderer(action.c.CraftingState, action.cliVersion, action.cliDigest, sig, renderer.WithLogger(action.Logger), renderer.WithBundleOutputPath(action.bundlePath)) if err != nil { return nil, err } - envelope, err := renderer.Render() + envelope, err := renderer.Render(ctx) if err != nil { return nil, err } 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 c8de72c81..3856bab71 100644 --- a/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts +++ b/app/controlplane/api/gen/frontend/attestation/v1/crafting_state.ts @@ -9,7 +9,6 @@ import { CraftingSchema_Runner_RunnerType, craftingSchema_Runner_RunnerTypeFromJSON, craftingSchema_Runner_RunnerTypeToJSON, - PolicyAttachment, } from "../../workflowcontract/v1/crafting_schema"; export const protobufPackage = "attestation.v1"; @@ -27,8 +26,8 @@ export interface Attestation { runnerType: CraftingSchema_Runner_RunnerType; /** Head Commit of the environment where the attestation was executed (optional) */ head?: Commit; - /** Policies that this attestation was validated against */ - policies: Policy[]; + /** Policies that materials in this attestation were validated against */ + policyEvaluations: PolicyEvaluation[]; } export interface Attestation_MaterialsEntry { @@ -100,19 +99,18 @@ export interface Attestation_EnvVarsEntry { value: string; } -/** A policy executed against an attestation */ -export interface Policy { +/** A policy executed against an attestation or material */ +export interface PolicyEvaluation { /** The policy name from the policy spec */ name: string; - /** The attachment as in the contract, with arguments and any other metadata */ - attachment?: PolicyAttachment; - /** The policy script body (rego) */ + materialName: string; + /** The body script of the policy */ body: string; /** The policy violations, if any */ - violations: Policy_Violation[]; + violations: PolicyEvaluation_Violation[]; } -export interface Policy_Violation { +export interface PolicyEvaluation_Violation { subject: string; message: string; } @@ -161,7 +159,7 @@ function createBaseAttestation(): Attestation { runnerUrl: "", runnerType: 0, head: undefined, - policies: [], + policyEvaluations: [], }; } @@ -194,8 +192,8 @@ export const Attestation = { if (message.head !== undefined) { Commit.encode(message.head, writer.uint32(74).fork()).ldelim(); } - for (const v of message.policies) { - Policy.encode(v!, writer.uint32(82).fork()).ldelim(); + for (const v of message.policyEvaluations) { + PolicyEvaluation.encode(v!, writer.uint32(82).fork()).ldelim(); } return writer; }, @@ -284,7 +282,7 @@ export const Attestation = { break; } - message.policies.push(Policy.decode(reader, reader.uint32())); + message.policyEvaluations.push(PolicyEvaluation.decode(reader, reader.uint32())); continue; } if ((tag & 7) === 4 || tag === 0) { @@ -321,7 +319,9 @@ export const Attestation = { runnerUrl: isSet(object.runnerUrl) ? String(object.runnerUrl) : "", runnerType: isSet(object.runnerType) ? craftingSchema_Runner_RunnerTypeFromJSON(object.runnerType) : 0, head: isSet(object.head) ? Commit.fromJSON(object.head) : undefined, - policies: Array.isArray(object?.policies) ? object.policies.map((e: any) => Policy.fromJSON(e)) : [], + policyEvaluations: Array.isArray(object?.policyEvaluations) + ? object.policyEvaluations.map((e: any) => PolicyEvaluation.fromJSON(e)) + : [], }; }, @@ -352,10 +352,10 @@ export const Attestation = { message.runnerUrl !== undefined && (obj.runnerUrl = message.runnerUrl); message.runnerType !== undefined && (obj.runnerType = craftingSchema_Runner_RunnerTypeToJSON(message.runnerType)); message.head !== undefined && (obj.head = message.head ? Commit.toJSON(message.head) : undefined); - if (message.policies) { - obj.policies = message.policies.map((e) => e ? Policy.toJSON(e) : undefined); + if (message.policyEvaluations) { + obj.policyEvaluations = message.policyEvaluations.map((e) => e ? PolicyEvaluation.toJSON(e) : undefined); } else { - obj.policies = []; + obj.policyEvaluations = []; } return obj; }, @@ -398,7 +398,7 @@ export const Attestation = { message.runnerUrl = object.runnerUrl ?? ""; message.runnerType = object.runnerType ?? 0; message.head = (object.head !== undefined && object.head !== null) ? Commit.fromPartial(object.head) : undefined; - message.policies = object.policies?.map((e) => Policy.fromPartial(e)) || []; + message.policyEvaluations = object.policyEvaluations?.map((e) => PolicyEvaluation.fromPartial(e)) || []; return message; }, }; @@ -1171,31 +1171,31 @@ export const Attestation_EnvVarsEntry = { }, }; -function createBasePolicy(): Policy { - return { name: "", attachment: undefined, body: "", violations: [] }; +function createBasePolicyEvaluation(): PolicyEvaluation { + return { name: "", materialName: "", body: "", violations: [] }; } -export const Policy = { - encode(message: Policy, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { +export const PolicyEvaluation = { + encode(message: PolicyEvaluation, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { if (message.name !== "") { writer.uint32(10).string(message.name); } - if (message.attachment !== undefined) { - PolicyAttachment.encode(message.attachment, writer.uint32(18).fork()).ldelim(); + if (message.materialName !== "") { + writer.uint32(18).string(message.materialName); } if (message.body !== "") { writer.uint32(26).string(message.body); } for (const v of message.violations) { - Policy_Violation.encode(v!, writer.uint32(34).fork()).ldelim(); + PolicyEvaluation_Violation.encode(v!, writer.uint32(34).fork()).ldelim(); } return writer; }, - decode(input: _m0.Reader | Uint8Array, length?: number): Policy { + decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluation { const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); let end = length === undefined ? reader.len : reader.pos + length; - const message = createBasePolicy(); + const message = createBasePolicyEvaluation(); while (reader.pos < end) { const tag = reader.uint32(); switch (tag >>> 3) { @@ -1211,7 +1211,7 @@ export const Policy = { break; } - message.attachment = PolicyAttachment.decode(reader, reader.uint32()); + message.materialName = reader.string(); continue; case 3: if (tag !== 26) { @@ -1225,7 +1225,7 @@ export const Policy = { break; } - message.violations.push(Policy_Violation.decode(reader, reader.uint32())); + message.violations.push(PolicyEvaluation_Violation.decode(reader, reader.uint32())); continue; } if ((tag & 7) === 4 || tag === 0) { @@ -1236,53 +1236,50 @@ export const Policy = { return message; }, - fromJSON(object: any): Policy { + fromJSON(object: any): PolicyEvaluation { return { name: isSet(object.name) ? String(object.name) : "", - attachment: isSet(object.attachment) ? PolicyAttachment.fromJSON(object.attachment) : undefined, + materialName: isSet(object.materialName) ? String(object.materialName) : "", body: isSet(object.body) ? String(object.body) : "", violations: Array.isArray(object?.violations) - ? object.violations.map((e: any) => Policy_Violation.fromJSON(e)) + ? object.violations.map((e: any) => PolicyEvaluation_Violation.fromJSON(e)) : [], }; }, - toJSON(message: Policy): unknown { + toJSON(message: PolicyEvaluation): unknown { const obj: any = {}; message.name !== undefined && (obj.name = message.name); - message.attachment !== undefined && - (obj.attachment = message.attachment ? PolicyAttachment.toJSON(message.attachment) : undefined); + message.materialName !== undefined && (obj.materialName = message.materialName); message.body !== undefined && (obj.body = message.body); if (message.violations) { - obj.violations = message.violations.map((e) => e ? Policy_Violation.toJSON(e) : undefined); + obj.violations = message.violations.map((e) => e ? PolicyEvaluation_Violation.toJSON(e) : undefined); } else { obj.violations = []; } return obj; }, - create, I>>(base?: I): Policy { - return Policy.fromPartial(base ?? {}); + create, I>>(base?: I): PolicyEvaluation { + return PolicyEvaluation.fromPartial(base ?? {}); }, - fromPartial, I>>(object: I): Policy { - const message = createBasePolicy(); + fromPartial, I>>(object: I): PolicyEvaluation { + const message = createBasePolicyEvaluation(); message.name = object.name ?? ""; - message.attachment = (object.attachment !== undefined && object.attachment !== null) - ? PolicyAttachment.fromPartial(object.attachment) - : undefined; + message.materialName = object.materialName ?? ""; message.body = object.body ?? ""; - message.violations = object.violations?.map((e) => Policy_Violation.fromPartial(e)) || []; + message.violations = object.violations?.map((e) => PolicyEvaluation_Violation.fromPartial(e)) || []; return message; }, }; -function createBasePolicy_Violation(): Policy_Violation { +function createBasePolicyEvaluation_Violation(): PolicyEvaluation_Violation { return { subject: "", message: "" }; } -export const Policy_Violation = { - encode(message: Policy_Violation, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { +export const PolicyEvaluation_Violation = { + encode(message: PolicyEvaluation_Violation, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { if (message.subject !== "") { writer.uint32(10).string(message.subject); } @@ -1292,10 +1289,10 @@ export const Policy_Violation = { return writer; }, - decode(input: _m0.Reader | Uint8Array, length?: number): Policy_Violation { + decode(input: _m0.Reader | Uint8Array, length?: number): PolicyEvaluation_Violation { const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); let end = length === undefined ? reader.len : reader.pos + length; - const message = createBasePolicy_Violation(); + const message = createBasePolicyEvaluation_Violation(); while (reader.pos < end) { const tag = reader.uint32(); switch (tag >>> 3) { @@ -1322,26 +1319,26 @@ export const Policy_Violation = { return message; }, - fromJSON(object: any): Policy_Violation { + fromJSON(object: any): PolicyEvaluation_Violation { return { subject: isSet(object.subject) ? String(object.subject) : "", message: isSet(object.message) ? String(object.message) : "", }; }, - toJSON(message: Policy_Violation): unknown { + toJSON(message: PolicyEvaluation_Violation): unknown { const obj: any = {}; message.subject !== undefined && (obj.subject = message.subject); message.message !== undefined && (obj.message = message.message); return obj; }, - create, I>>(base?: I): Policy_Violation { - return Policy_Violation.fromPartial(base ?? {}); + create, I>>(base?: I): PolicyEvaluation_Violation { + return PolicyEvaluation_Violation.fromPartial(base ?? {}); }, - fromPartial, I>>(object: I): Policy_Violation { - const message = createBasePolicy_Violation(); + fromPartial, I>>(object: I): PolicyEvaluation_Violation { + const message = createBasePolicyEvaluation_Violation(); message.subject = object.subject ?? ""; message.message = object.message ?? ""; return message; 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 5c9726237..68722776c 100644 --- a/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts +++ b/app/controlplane/api/gen/frontend/workflowcontract/v1/crafting_schema.ts @@ -19,7 +19,8 @@ export interface CraftingSchema { * It works in addition to the annotations defined in the materials and the runner */ annotations: Annotation[]; - policies: PolicyAttachment[]; + /** Policies to apply to this schema */ + policies?: Policies; } export interface CraftingSchema_Runner { @@ -238,15 +239,22 @@ export interface Annotation { value: string; } +export interface Policies { + /** Policies to be applied to materials */ + materials: PolicyAttachment[]; + /** Policies to be applied to attestation metadata */ + attestation: PolicyAttachment[]; +} + /** A policy to be applied to this contract */ export interface PolicyAttachment { /** policy reference, it might be in URI format. */ ref?: | string | undefined; - /** reference to a policy already known by chainloop */ - name?: - | string + /** meant to be used to embed the policy in the contract */ + embedded?: + | Policy | undefined; /** * rules to select a material or materials to be validated by the policy. @@ -269,8 +277,45 @@ export interface PolicyAttachment_PolicyArgument { value: string; } +/** Represents a policy to be applied to a material or attestation */ +export interface Policy { + apiVersion: string; + kind: string; + metadata?: Metadata; + spec?: PolicySpec; +} + +export interface Metadata { + /** the name of the policy */ + name: string; +} + +export interface PolicySpec { + /** path to a policy script. It might consist of a URI reference */ + path?: + | string + | undefined; + /** embedded source code (only Rego supported currently) */ + embedded?: + | string + | undefined; + /** + * if set, it will match any material supported by Chainloop + * except those not having a direct schema (STRING, ARTIFACT, EVIDENCE), since their format cannot be guessed by the crafter. + * CONTAINER, HELM_CHART are also excluded, but we might implement custom policies for them in the future. + */ + type: CraftingSchema_Material_MaterialType; +} + function createBaseCraftingSchema(): CraftingSchema { - return { schemaVersion: "", materials: [], envAllowList: [], runner: undefined, annotations: [], policies: [] }; + return { + schemaVersion: "", + materials: [], + envAllowList: [], + runner: undefined, + annotations: [], + policies: undefined, + }; } export const CraftingSchema = { @@ -290,8 +335,8 @@ export const CraftingSchema = { for (const v of message.annotations) { Annotation.encode(v!, writer.uint32(42).fork()).ldelim(); } - for (const v of message.policies) { - PolicyAttachment.encode(v!, writer.uint32(50).fork()).ldelim(); + if (message.policies !== undefined) { + Policies.encode(message.policies, writer.uint32(50).fork()).ldelim(); } return writer; }, @@ -343,7 +388,7 @@ export const CraftingSchema = { break; } - message.policies.push(PolicyAttachment.decode(reader, reader.uint32())); + message.policies = Policies.decode(reader, reader.uint32()); continue; } if ((tag & 7) === 4 || tag === 0) { @@ -363,7 +408,7 @@ export const CraftingSchema = { envAllowList: Array.isArray(object?.envAllowList) ? object.envAllowList.map((e: any) => String(e)) : [], runner: isSet(object.runner) ? CraftingSchema_Runner.fromJSON(object.runner) : undefined, annotations: Array.isArray(object?.annotations) ? object.annotations.map((e: any) => Annotation.fromJSON(e)) : [], - policies: Array.isArray(object?.policies) ? object.policies.map((e: any) => PolicyAttachment.fromJSON(e)) : [], + policies: isSet(object.policies) ? Policies.fromJSON(object.policies) : undefined, }; }, @@ -387,11 +432,7 @@ export const CraftingSchema = { } else { obj.annotations = []; } - if (message.policies) { - obj.policies = message.policies.map((e) => e ? PolicyAttachment.toJSON(e) : undefined); - } else { - obj.policies = []; - } + message.policies !== undefined && (obj.policies = message.policies ? Policies.toJSON(message.policies) : undefined); return obj; }, @@ -408,7 +449,9 @@ export const CraftingSchema = { ? CraftingSchema_Runner.fromPartial(object.runner) : undefined; message.annotations = object.annotations?.map((e) => Annotation.fromPartial(e)) || []; - message.policies = object.policies?.map((e) => PolicyAttachment.fromPartial(e)) || []; + message.policies = (object.policies !== undefined && object.policies !== null) + ? Policies.fromPartial(object.policies) + : undefined; return message; }, }; @@ -654,8 +697,89 @@ export const Annotation = { }, }; +function createBasePolicies(): Policies { + return { materials: [], attestation: [] }; +} + +export const Policies = { + encode(message: Policies, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.materials) { + PolicyAttachment.encode(v!, writer.uint32(10).fork()).ldelim(); + } + for (const v of message.attestation) { + PolicyAttachment.encode(v!, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Policies { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicies(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.materials.push(PolicyAttachment.decode(reader, reader.uint32())); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.attestation.push(PolicyAttachment.decode(reader, reader.uint32())); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Policies { + return { + materials: Array.isArray(object?.materials) ? object.materials.map((e: any) => PolicyAttachment.fromJSON(e)) : [], + attestation: Array.isArray(object?.attestation) + ? object.attestation.map((e: any) => PolicyAttachment.fromJSON(e)) + : [], + }; + }, + + toJSON(message: Policies): unknown { + const obj: any = {}; + if (message.materials) { + obj.materials = message.materials.map((e) => e ? PolicyAttachment.toJSON(e) : undefined); + } else { + obj.materials = []; + } + if (message.attestation) { + obj.attestation = message.attestation.map((e) => e ? PolicyAttachment.toJSON(e) : undefined); + } else { + obj.attestation = []; + } + return obj; + }, + + create, I>>(base?: I): Policies { + return Policies.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): Policies { + const message = createBasePolicies(); + message.materials = object.materials?.map((e) => PolicyAttachment.fromPartial(e)) || []; + message.attestation = object.attestation?.map((e) => PolicyAttachment.fromPartial(e)) || []; + return message; + }, +}; + function createBasePolicyAttachment(): PolicyAttachment { - return { ref: undefined, name: undefined, selector: undefined, disabled: false, with: [] }; + return { ref: undefined, embedded: undefined, selector: undefined, disabled: false, with: [] }; } export const PolicyAttachment = { @@ -663,8 +787,8 @@ export const PolicyAttachment = { if (message.ref !== undefined) { writer.uint32(10).string(message.ref); } - if (message.name !== undefined) { - writer.uint32(18).string(message.name); + if (message.embedded !== undefined) { + Policy.encode(message.embedded, writer.uint32(18).fork()).ldelim(); } if (message.selector !== undefined) { PolicyAttachment_MaterialSelector.encode(message.selector, writer.uint32(26).fork()).ldelim(); @@ -697,7 +821,7 @@ export const PolicyAttachment = { break; } - message.name = reader.string(); + message.embedded = Policy.decode(reader, reader.uint32()); continue; case 3: if (tag !== 26) { @@ -732,7 +856,7 @@ export const PolicyAttachment = { fromJSON(object: any): PolicyAttachment { return { ref: isSet(object.ref) ? String(object.ref) : undefined, - name: isSet(object.name) ? String(object.name) : undefined, + embedded: isSet(object.embedded) ? Policy.fromJSON(object.embedded) : undefined, selector: isSet(object.selector) ? PolicyAttachment_MaterialSelector.fromJSON(object.selector) : undefined, disabled: isSet(object.disabled) ? Boolean(object.disabled) : false, with: Array.isArray(object?.with) ? object.with.map((e: any) => PolicyAttachment_PolicyArgument.fromJSON(e)) : [], @@ -742,7 +866,7 @@ export const PolicyAttachment = { toJSON(message: PolicyAttachment): unknown { const obj: any = {}; message.ref !== undefined && (obj.ref = message.ref); - message.name !== undefined && (obj.name = message.name); + message.embedded !== undefined && (obj.embedded = message.embedded ? Policy.toJSON(message.embedded) : undefined); message.selector !== undefined && (obj.selector = message.selector ? PolicyAttachment_MaterialSelector.toJSON(message.selector) : undefined); message.disabled !== undefined && (obj.disabled = message.disabled); @@ -761,7 +885,9 @@ export const PolicyAttachment = { fromPartial, I>>(object: I): PolicyAttachment { const message = createBasePolicyAttachment(); message.ref = object.ref ?? undefined; - message.name = object.name ?? undefined; + message.embedded = (object.embedded !== undefined && object.embedded !== null) + ? Policy.fromPartial(object.embedded) + : undefined; message.selector = (object.selector !== undefined && object.selector !== null) ? PolicyAttachment_MaterialSelector.fromPartial(object.selector) : undefined; @@ -904,6 +1030,247 @@ export const PolicyAttachment_PolicyArgument = { }, }; +function createBasePolicy(): Policy { + return { apiVersion: "", kind: "", metadata: undefined, spec: undefined }; +} + +export const Policy = { + encode(message: Policy, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.apiVersion !== "") { + writer.uint32(10).string(message.apiVersion); + } + if (message.kind !== "") { + writer.uint32(18).string(message.kind); + } + if (message.metadata !== undefined) { + Metadata.encode(message.metadata, writer.uint32(26).fork()).ldelim(); + } + if (message.spec !== undefined) { + PolicySpec.encode(message.spec, writer.uint32(34).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Policy { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicy(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.apiVersion = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.kind = reader.string(); + continue; + case 3: + if (tag !== 26) { + break; + } + + message.metadata = Metadata.decode(reader, reader.uint32()); + continue; + case 4: + if (tag !== 34) { + break; + } + + message.spec = PolicySpec.decode(reader, reader.uint32()); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Policy { + return { + apiVersion: isSet(object.apiVersion) ? String(object.apiVersion) : "", + kind: isSet(object.kind) ? String(object.kind) : "", + metadata: isSet(object.metadata) ? Metadata.fromJSON(object.metadata) : undefined, + spec: isSet(object.spec) ? PolicySpec.fromJSON(object.spec) : undefined, + }; + }, + + toJSON(message: Policy): unknown { + const obj: any = {}; + message.apiVersion !== undefined && (obj.apiVersion = message.apiVersion); + message.kind !== undefined && (obj.kind = message.kind); + message.metadata !== undefined && (obj.metadata = message.metadata ? Metadata.toJSON(message.metadata) : undefined); + message.spec !== undefined && (obj.spec = message.spec ? PolicySpec.toJSON(message.spec) : undefined); + return obj; + }, + + create, I>>(base?: I): Policy { + return Policy.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): Policy { + const message = createBasePolicy(); + message.apiVersion = object.apiVersion ?? ""; + message.kind = object.kind ?? ""; + message.metadata = (object.metadata !== undefined && object.metadata !== null) + ? Metadata.fromPartial(object.metadata) + : undefined; + message.spec = (object.spec !== undefined && object.spec !== null) + ? PolicySpec.fromPartial(object.spec) + : undefined; + return message; + }, +}; + +function createBaseMetadata(): Metadata { + return { name: "" }; +} + +export const Metadata = { + encode(message: Metadata, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.name !== "") { + writer.uint32(26).string(message.name); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): Metadata { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMetadata(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 3: + if (tag !== 26) { + break; + } + + message.name = reader.string(); + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): Metadata { + return { name: isSet(object.name) ? String(object.name) : "" }; + }, + + toJSON(message: Metadata): unknown { + const obj: any = {}; + message.name !== undefined && (obj.name = message.name); + return obj; + }, + + create, I>>(base?: I): Metadata { + return Metadata.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): Metadata { + const message = createBaseMetadata(); + message.name = object.name ?? ""; + return message; + }, +}; + +function createBasePolicySpec(): PolicySpec { + return { path: undefined, embedded: undefined, type: 0 }; +} + +export const PolicySpec = { + encode(message: PolicySpec, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.path !== undefined) { + writer.uint32(10).string(message.path); + } + if (message.embedded !== undefined) { + writer.uint32(18).string(message.embedded); + } + if (message.type !== 0) { + writer.uint32(24).int32(message.type); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): PolicySpec { + const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePolicySpec(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + if (tag !== 10) { + break; + } + + message.path = reader.string(); + continue; + case 2: + if (tag !== 18) { + break; + } + + message.embedded = reader.string(); + continue; + case 3: + if (tag !== 24) { + break; + } + + message.type = reader.int32() as any; + continue; + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skipType(tag & 7); + } + return message; + }, + + fromJSON(object: any): PolicySpec { + return { + path: isSet(object.path) ? String(object.path) : undefined, + embedded: isSet(object.embedded) ? String(object.embedded) : undefined, + type: isSet(object.type) ? craftingSchema_Material_MaterialTypeFromJSON(object.type) : 0, + }; + }, + + toJSON(message: PolicySpec): unknown { + const obj: any = {}; + message.path !== undefined && (obj.path = message.path); + message.embedded !== undefined && (obj.embedded = message.embedded); + message.type !== undefined && (obj.type = craftingSchema_Material_MaterialTypeToJSON(message.type)); + return obj; + }, + + create, I>>(base?: I): PolicySpec { + return PolicySpec.fromPartial(base ?? {}); + }, + + fromPartial, I>>(object: I): PolicySpec { + const message = createBasePolicySpec(); + message.path = object.path ?? undefined; + message.embedded = object.embedded ?? undefined; + message.type = object.type ?? 0; + return message; + }, +}; + type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; export type DeepPartial = T extends Builtin ? T diff --git a/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go b/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go index b3903b99f..13d4110dc 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema.pb.go @@ -207,8 +207,9 @@ type CraftingSchema struct { // List of annotations that can be used to add metadata to the attestation // this metadata can be used later on by the integrations engine to filter and interpolate data // It works in addition to the annotations defined in the materials and the runner - Annotations []*Annotation `protobuf:"bytes,5,rep,name=annotations,proto3" json:"annotations,omitempty"` - Policies []*PolicyAttachment `protobuf:"bytes,6,rep,name=policies,proto3" json:"policies,omitempty"` + Annotations []*Annotation `protobuf:"bytes,5,rep,name=annotations,proto3" json:"annotations,omitempty"` + // Policies to apply to this schema + Policies *Policies `protobuf:"bytes,6,opt,name=policies,proto3" json:"policies,omitempty"` } func (x *CraftingSchema) Reset() { @@ -278,7 +279,7 @@ func (x *CraftingSchema) GetAnnotations() []*Annotation { return nil } -func (x *CraftingSchema) GetPolicies() []*PolicyAttachment { +func (x *CraftingSchema) GetPolicies() *Policies { if x != nil { return x.Policies } @@ -341,6 +342,63 @@ func (x *Annotation) GetValue() string { return "" } +type Policies struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Policies to be applied to materials + Materials []*PolicyAttachment `protobuf:"bytes,1,rep,name=materials,proto3" json:"materials,omitempty"` + // Policies to be applied to attestation metadata + Attestation []*PolicyAttachment `protobuf:"bytes,2,rep,name=attestation,proto3" json:"attestation,omitempty"` +} + +func (x *Policies) Reset() { + *x = Policies{} + if protoimpl.UnsafeEnabled { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Policies) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Policies) ProtoMessage() {} + +func (x *Policies) ProtoReflect() protoreflect.Message { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[2] + 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 Policies.ProtoReflect.Descriptor instead. +func (*Policies) Descriptor() ([]byte, []int) { + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{2} +} + +func (x *Policies) GetMaterials() []*PolicyAttachment { + if x != nil { + return x.Materials + } + return nil +} + +func (x *Policies) GetAttestation() []*PolicyAttachment { + if x != nil { + return x.Attestation + } + return nil +} + // A policy to be applied to this contract type PolicyAttachment struct { state protoimpl.MessageState @@ -350,7 +408,7 @@ type PolicyAttachment struct { // Types that are assignable to Policy: // // *PolicyAttachment_Ref - // *PolicyAttachment_Name + // *PolicyAttachment_Embedded Policy isPolicyAttachment_Policy `protobuf_oneof:"policy"` // rules to select a material or materials to be validated by the policy. // If none provided, the whole statement will be injected to the policy @@ -363,7 +421,7 @@ type PolicyAttachment struct { func (x *PolicyAttachment) Reset() { *x = PolicyAttachment{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[2] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -376,7 +434,7 @@ func (x *PolicyAttachment) String() string { func (*PolicyAttachment) ProtoMessage() {} func (x *PolicyAttachment) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[2] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -389,7 +447,7 @@ func (x *PolicyAttachment) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyAttachment.ProtoReflect.Descriptor instead. func (*PolicyAttachment) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{2} + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{3} } func (m *PolicyAttachment) GetPolicy() isPolicyAttachment_Policy { @@ -406,11 +464,11 @@ func (x *PolicyAttachment) GetRef() string { return "" } -func (x *PolicyAttachment) GetName() string { - if x, ok := x.GetPolicy().(*PolicyAttachment_Name); ok { - return x.Name +func (x *PolicyAttachment) GetEmbedded() *Policy { + if x, ok := x.GetPolicy().(*PolicyAttachment_Embedded); ok { + return x.Embedded } - return "" + return nil } func (x *PolicyAttachment) GetSelector() *PolicyAttachment_MaterialSelector { @@ -443,14 +501,228 @@ type PolicyAttachment_Ref struct { Ref string `protobuf:"bytes,1,opt,name=ref,proto3,oneof"` } -type PolicyAttachment_Name struct { - // reference to a policy already known by chainloop - Name string `protobuf:"bytes,2,opt,name=name,proto3,oneof"` +type PolicyAttachment_Embedded struct { + // meant to be used to embed the policy in the contract + Embedded *Policy `protobuf:"bytes,2,opt,name=embedded,proto3,oneof"` } func (*PolicyAttachment_Ref) isPolicyAttachment_Policy() {} -func (*PolicyAttachment_Name) isPolicyAttachment_Policy() {} +func (*PolicyAttachment_Embedded) isPolicyAttachment_Policy() {} + +// Represents a policy to be applied to a material or attestation +type Policy struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ApiVersion string `protobuf:"bytes,1,opt,name=api_version,json=apiVersion,proto3" json:"api_version,omitempty"` + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + Metadata *Metadata `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"` + Spec *PolicySpec `protobuf:"bytes,4,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (x *Policy) Reset() { + *x = Policy{} + if protoimpl.UnsafeEnabled { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Policy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Policy) ProtoMessage() {} + +func (x *Policy) ProtoReflect() protoreflect.Message { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[4] + 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 Policy.ProtoReflect.Descriptor instead. +func (*Policy) Descriptor() ([]byte, []int) { + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{4} +} + +func (x *Policy) GetApiVersion() string { + if x != nil { + return x.ApiVersion + } + return "" +} + +func (x *Policy) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *Policy) GetMetadata() *Metadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *Policy) GetSpec() *PolicySpec { + if x != nil { + return x.Spec + } + return nil +} + +type Metadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the name of the policy + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *Metadata) Reset() { + *x = Metadata{} + if protoimpl.UnsafeEnabled { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Metadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Metadata) ProtoMessage() {} + +func (x *Metadata) ProtoReflect() protoreflect.Message { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[5] + 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 Metadata.ProtoReflect.Descriptor instead. +func (*Metadata) Descriptor() ([]byte, []int) { + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{5} +} + +func (x *Metadata) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type PolicySpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Source: + // + // *PolicySpec_Path + // *PolicySpec_Embedded + Source isPolicySpec_Source `protobuf_oneof:"source"` + // if set, it will match any material supported by Chainloop + // except those not having a direct schema (STRING, ARTIFACT, EVIDENCE), since their format cannot be guessed by the crafter. + // CONTAINER, HELM_CHART are also excluded, but we might implement custom policies for them in the future. + Type CraftingSchema_Material_MaterialType `protobuf:"varint,3,opt,name=type,proto3,enum=workflowcontract.v1.CraftingSchema_Material_MaterialType" json:"type,omitempty"` +} + +func (x *PolicySpec) Reset() { + *x = PolicySpec{} + if protoimpl.UnsafeEnabled { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PolicySpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PolicySpec) ProtoMessage() {} + +func (x *PolicySpec) ProtoReflect() protoreflect.Message { + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[6] + 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 PolicySpec.ProtoReflect.Descriptor instead. +func (*PolicySpec) Descriptor() ([]byte, []int) { + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{6} +} + +func (m *PolicySpec) GetSource() isPolicySpec_Source { + if m != nil { + return m.Source + } + return nil +} + +func (x *PolicySpec) GetPath() string { + if x, ok := x.GetSource().(*PolicySpec_Path); ok { + return x.Path + } + return "" +} + +func (x *PolicySpec) GetEmbedded() string { + if x, ok := x.GetSource().(*PolicySpec_Embedded); ok { + return x.Embedded + } + return "" +} + +func (x *PolicySpec) GetType() CraftingSchema_Material_MaterialType { + if x != nil { + return x.Type + } + return CraftingSchema_Material_MATERIAL_TYPE_UNSPECIFIED +} + +type isPolicySpec_Source interface { + isPolicySpec_Source() +} + +type PolicySpec_Path struct { + // path to a policy script. It might consist of a URI reference + Path string `protobuf:"bytes,1,opt,name=path,proto3,oneof"` +} + +type PolicySpec_Embedded struct { + // embedded source code (only Rego supported currently) + Embedded string `protobuf:"bytes,2,opt,name=embedded,proto3,oneof"` +} + +func (*PolicySpec_Path) isPolicySpec_Source() {} + +func (*PolicySpec_Embedded) isPolicySpec_Source() {} type CraftingSchema_Runner struct { state protoimpl.MessageState @@ -463,7 +735,7 @@ type CraftingSchema_Runner struct { func (x *CraftingSchema_Runner) Reset() { *x = CraftingSchema_Runner{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[3] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -476,7 +748,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[3] + 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 { @@ -517,7 +789,7 @@ type CraftingSchema_Material struct { func (x *CraftingSchema_Material) Reset() { *x = CraftingSchema_Material{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[4] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -530,7 +802,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[4] + 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 { @@ -593,7 +865,7 @@ type PolicyAttachment_MaterialSelector struct { func (x *PolicyAttachment_MaterialSelector) Reset() { *x = PolicyAttachment_MaterialSelector{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[5] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -606,7 +878,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[5] + 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 { @@ -619,7 +891,7 @@ func (x *PolicyAttachment_MaterialSelector) ProtoReflect() protoreflect.Message // Deprecated: Use PolicyAttachment_MaterialSelector.ProtoReflect.Descriptor instead. func (*PolicyAttachment_MaterialSelector) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{2, 0} + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{3, 0} } func (x *PolicyAttachment_MaterialSelector) GetName() string { @@ -642,7 +914,7 @@ type PolicyAttachment_PolicyArgument struct { func (x *PolicyAttachment_PolicyArgument) Reset() { *x = PolicyAttachment_PolicyArgument{} if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[6] + mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -655,7 +927,7 @@ func (x *PolicyAttachment_PolicyArgument) String() string { func (*PolicyAttachment_PolicyArgument) ProtoMessage() {} func (x *PolicyAttachment_PolicyArgument) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_crafting_schema_proto_msgTypes[6] + 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 { @@ -668,7 +940,7 @@ func (x *PolicyAttachment_PolicyArgument) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyAttachment_PolicyArgument.ProtoReflect.Descriptor instead. func (*PolicyAttachment_PolicyArgument) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{2, 1} + return file_workflowcontract_v1_crafting_schema_proto_rawDescGZIP(), []int{3, 1} } func (x *PolicyAttachment_PolicyArgument) GetName() string { @@ -693,7 +965,7 @@ var file_workflowcontract_v1_crafting_schema_proto_rawDesc = []byte{ 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdb, 0x09, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd3, 0x09, 0x0a, 0x0e, 0x43, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xba, 0x48, 0x06, 0x72, 0x04, 0x0a, @@ -713,108 +985,148 @@ var file_workflowcontract_v1_crafting_schema_proto_rawDesc = []byte{ 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x39, 0x0a, 0x08, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 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, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x1a, 0x82, - 0x02, 0x0a, 0x06, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 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, 0x52, 0x75, 0x6e, - 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x0b, - 0xba, 0x48, 0x08, 0x82, 0x01, 0x05, 0x10, 0x01, 0x22, 0x01, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x22, 0x9f, 0x01, 0x0a, 0x0a, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x55, 0x4e, 0x4e, 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, - 0x0d, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, - 0x12, 0x13, 0x0a, 0x0f, 0x47, 0x49, 0x54, 0x4c, 0x41, 0x42, 0x5f, 0x50, 0x49, 0x50, 0x45, 0x4c, - 0x49, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x50, - 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4a, 0x45, 0x4e, - 0x4b, 0x49, 0x4e, 0x53, 0x5f, 0x4a, 0x4f, 0x42, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, - 0x52, 0x43, 0x4c, 0x45, 0x43, 0x49, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x10, 0x05, 0x12, 0x13, - 0x0a, 0x0f, 0x44, 0x41, 0x47, 0x47, 0x45, 0x52, 0x5f, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, - 0x45, 0x10, 0x06, 0x1a, 0xd5, 0x04, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, - 0x12, 0x5a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 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, 0x0b, 0xba, 0x48, 0x08, 0x82, 0x01, - 0x05, 0x10, 0x01, 0x22, 0x01, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xba, 0x48, 0x0d, 0x72, - 0x0b, 0x32, 0x09, 0x5e, 0x5b, 0x5c, 0x77, 0x7c, 0x2d, 0x5d, 0x2b, 0x24, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x16, - 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x41, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x77, 0x6f, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x08, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x1a, 0x82, 0x02, 0x0a, 0x06, 0x52, 0x75, 0x6e, 0x6e, 0x65, + 0x72, 0x12, 0x56, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x35, 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, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x6e, + 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x0b, 0xba, 0x48, 0x08, 0x82, 0x01, 0x05, 0x10, 0x01, + 0x22, 0x01, 0x00, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x9f, 0x01, 0x0a, 0x0a, 0x52, 0x75, + 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x55, 0x4e, 0x4e, + 0x45, 0x52, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, + 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x47, 0x49, 0x54, 0x4c, + 0x41, 0x42, 0x5f, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x02, 0x12, 0x12, 0x0a, + 0x0e, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, + 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4a, 0x45, 0x4e, 0x4b, 0x49, 0x4e, 0x53, 0x5f, 0x4a, 0x4f, 0x42, + 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x49, 0x52, 0x43, 0x4c, 0x45, 0x43, 0x49, 0x5f, 0x42, + 0x55, 0x49, 0x4c, 0x44, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x41, 0x47, 0x47, 0x45, 0x52, + 0x5f, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e, 0x45, 0x10, 0x06, 0x1a, 0xd5, 0x04, 0x0a, 0x08, + 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x5a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 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, 0x0b, 0xba, 0x48, 0x08, 0x82, 0x01, 0x05, 0x10, 0x01, 0x22, 0x01, 0x00, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x10, 0xba, 0x48, 0x0d, 0x72, 0x0b, 0x32, 0x09, 0x5e, 0x5b, 0x5c, 0x77, 0x7c, + 0x2d, 0x5d, 0x2b, 0x24, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x41, + 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0xcf, 0x02, 0x0a, 0x0c, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x41, 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, + 0x0f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x49, 0x4d, 0x41, 0x47, 0x45, + 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x10, 0x03, + 0x12, 0x17, 0x0a, 0x13, 0x53, 0x42, 0x4f, 0x4d, 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x4f, 0x4e, 0x45, + 0x44, 0x58, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x42, 0x4f, + 0x4d, 0x5f, 0x53, 0x50, 0x44, 0x58, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0d, 0x0a, + 0x09, 0x4a, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x58, 0x4d, 0x4c, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, + 0x4f, 0x50, 0x45, 0x4e, 0x56, 0x45, 0x58, 0x10, 0x07, 0x12, 0x0e, 0x0a, 0x0a, 0x48, 0x45, 0x4c, + 0x4d, 0x5f, 0x43, 0x48, 0x41, 0x52, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x41, 0x52, + 0x49, 0x46, 0x10, 0x09, 0x12, 0x0c, 0x0a, 0x08, 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, + 0x10, 0x0b, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x54, 0x54, 0x45, 0x53, 0x54, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x10, 0x0c, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x53, 0x41, 0x46, 0x5f, 0x56, 0x45, 0x58, 0x10, + 0x08, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x53, 0x41, 0x46, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x4d, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x5f, 0x41, 0x44, 0x56, 0x49, 0x53, 0x4f, 0x52, 0x59, + 0x10, 0x0d, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x53, 0x41, 0x46, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, + 0x49, 0x54, 0x59, 0x5f, 0x41, 0x44, 0x56, 0x49, 0x53, 0x4f, 0x52, 0x59, 0x10, 0x0e, 0x12, 0x23, + 0x0a, 0x1f, 0x43, 0x53, 0x41, 0x46, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, 0x5f, + 0x49, 0x4e, 0x43, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, + 0x45, 0x10, 0x0f, 0x22, 0x46, 0x0a, 0x0a, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x0e, 0xba, 0x48, 0x0b, 0x72, 0x09, 0x32, 0x07, 0x5e, 0x5b, 0x5c, 0x77, 0x5d, 0x2b, 0x24, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x08, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x09, 0x6d, 0x61, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x01, 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, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xcf, 0x02, 0x0a, 0x0c, 0x4d, 0x61, - 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x4d, 0x41, - 0x54, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, - 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, - 0x45, 0x52, 0x5f, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x52, - 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x10, 0x03, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x42, 0x4f, 0x4d, - 0x5f, 0x43, 0x59, 0x43, 0x4c, 0x4f, 0x4e, 0x45, 0x44, 0x58, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x10, - 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x42, 0x4f, 0x4d, 0x5f, 0x53, 0x50, 0x44, 0x58, 0x5f, 0x4a, - 0x53, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x4a, 0x55, 0x4e, 0x49, 0x54, 0x5f, 0x58, - 0x4d, 0x4c, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x4f, 0x50, 0x45, 0x4e, 0x56, 0x45, 0x58, 0x10, - 0x07, 0x12, 0x0e, 0x0a, 0x0a, 0x48, 0x45, 0x4c, 0x4d, 0x5f, 0x43, 0x48, 0x41, 0x52, 0x54, 0x10, - 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x41, 0x52, 0x49, 0x46, 0x10, 0x09, 0x12, 0x0c, 0x0a, 0x08, - 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x0b, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x54, - 0x54, 0x45, 0x53, 0x54, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x0c, 0x12, 0x0c, 0x0a, 0x08, 0x43, - 0x53, 0x41, 0x46, 0x5f, 0x56, 0x45, 0x58, 0x10, 0x08, 0x12, 0x1f, 0x0a, 0x1b, 0x43, 0x53, 0x41, - 0x46, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x5f, - 0x41, 0x44, 0x56, 0x49, 0x53, 0x4f, 0x52, 0x59, 0x10, 0x0d, 0x12, 0x1a, 0x0a, 0x16, 0x43, 0x53, - 0x41, 0x46, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x41, 0x44, 0x56, 0x49, - 0x53, 0x4f, 0x52, 0x59, 0x10, 0x0e, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x53, 0x41, 0x46, 0x5f, 0x53, - 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x49, 0x4e, 0x43, 0x49, 0x44, 0x45, 0x4e, 0x54, - 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x10, 0x0f, 0x22, 0x46, 0x0a, 0x0a, 0x41, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xba, 0x48, 0x0b, 0x72, 0x09, 0x32, 0x07, - 0x5e, 0x5b, 0x5c, 0x77, 0x5d, 0x2b, 0x24, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x8a, 0x04, 0x0a, 0x10, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x74, - 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x03, 0x72, 0x65, 0x66, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, - 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x99, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 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, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x52, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x36, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, - 0x69, 0x61, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x73, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, - 0x64, 0x12, 0x48, 0x0a, 0x04, 0x77, 0x69, 0x74, 0x68, 0x18, 0x05, 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, 0x41, 0x74, 0x74, 0x61, - 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x77, 0x69, 0x74, 0x68, 0x1a, 0x26, 0x0a, 0x10, 0x4d, - 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x1a, 0x4a, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x72, 0x67, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, - 0x0f, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, - 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, + 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 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, 0x22, 0xa9, 0x03, 0x0a, 0x10, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x03, 0x72, + 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x48, 0x00, 0x52, 0x03, 0x72, 0x65, 0x66, 0x12, 0x39, 0x0a, 0x08, 0x65, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 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, 0x48, 0x00, 0x52, 0x08, 0x65, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x65, 0x64, 0x12, 0x52, 0x0a, 0x08, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 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, 0x2e, 0x4d, 0x61, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x04, 0x77, 0x69, 0x74, 0x68, 0x18, 0x05, 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, 0x41, 0x74, + 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x77, 0x69, 0x74, 0x68, 0x1a, 0x26, 0x0a, + 0x10, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x4a, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x42, 0x0f, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x05, 0xba, 0x48, 0x02, + 0x08, 0x01, 0x22, 0xf6, 0x01, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 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, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x6c, 0x6f, 0x6f, 0x70, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x76, 0x31, 0x52, 0x0a, 0x61, 0x70, + 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x0a, 0x72, 0x08, 0x0a, 0x06, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x41, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x06, 0xba, 0x48, + 0x03, 0xc8, 0x01, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3b, + 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 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, 0x42, 0x06, 0xba, + 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xa4, 0x01, 0x0a, 0x08, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 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, 0x22, 0xaf, 0x01, 0x0a, 0x0a, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x70, 0x65, + 0x63, 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, 0x5c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 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, 0x0d, + 0xba, 0x48, 0x0a, 0x82, 0x01, 0x07, 0x22, 0x05, 0x01, 0x02, 0x03, 0x0a, 0x0b, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x42, 0x0f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x05, 0xba, + 0x48, 0x02, 0x08, 0x01, 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 ( @@ -830,33 +1142,43 @@ 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, 7) +var file_workflowcontract_v1_crafting_schema_proto_msgTypes = make([]protoimpl.MessageInfo, 11) 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 (*CraftingSchema)(nil), // 2: workflowcontract.v1.CraftingSchema (*Annotation)(nil), // 3: workflowcontract.v1.Annotation - (*PolicyAttachment)(nil), // 4: workflowcontract.v1.PolicyAttachment - (*CraftingSchema_Runner)(nil), // 5: workflowcontract.v1.CraftingSchema.Runner - (*CraftingSchema_Material)(nil), // 6: workflowcontract.v1.CraftingSchema.Material - (*PolicyAttachment_MaterialSelector)(nil), // 7: workflowcontract.v1.PolicyAttachment.MaterialSelector - (*PolicyAttachment_PolicyArgument)(nil), // 8: workflowcontract.v1.PolicyAttachment.PolicyArgument + (*Policies)(nil), // 4: workflowcontract.v1.Policies + (*PolicyAttachment)(nil), // 5: workflowcontract.v1.PolicyAttachment + (*Policy)(nil), // 6: workflowcontract.v1.Policy + (*Metadata)(nil), // 7: workflowcontract.v1.Metadata + (*PolicySpec)(nil), // 8: workflowcontract.v1.PolicySpec + (*CraftingSchema_Runner)(nil), // 9: workflowcontract.v1.CraftingSchema.Runner + (*CraftingSchema_Material)(nil), // 10: workflowcontract.v1.CraftingSchema.Material + (*PolicyAttachment_MaterialSelector)(nil), // 11: workflowcontract.v1.PolicyAttachment.MaterialSelector + (*PolicyAttachment_PolicyArgument)(nil), // 12: workflowcontract.v1.PolicyAttachment.PolicyArgument } var file_workflowcontract_v1_crafting_schema_proto_depIdxs = []int32{ - 6, // 0: workflowcontract.v1.CraftingSchema.materials:type_name -> workflowcontract.v1.CraftingSchema.Material - 5, // 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.PolicyAttachment - 7, // 4: workflowcontract.v1.PolicyAttachment.selector:type_name -> workflowcontract.v1.PolicyAttachment.MaterialSelector - 8, // 5: workflowcontract.v1.PolicyAttachment.with:type_name -> workflowcontract.v1.PolicyAttachment.PolicyArgument - 0, // 6: workflowcontract.v1.CraftingSchema.Runner.type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType - 1, // 7: workflowcontract.v1.CraftingSchema.Material.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 3, // 8: workflowcontract.v1.CraftingSchema.Material.annotations:type_name -> workflowcontract.v1.Annotation - 9, // [9:9] is the sub-list for method output_type - 9, // [9:9] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 10, // 0: workflowcontract.v1.CraftingSchema.materials:type_name -> workflowcontract.v1.CraftingSchema.Material + 9, // 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 + 5, // 4: workflowcontract.v1.Policies.materials:type_name -> workflowcontract.v1.PolicyAttachment + 5, // 5: workflowcontract.v1.Policies.attestation:type_name -> workflowcontract.v1.PolicyAttachment + 6, // 6: workflowcontract.v1.PolicyAttachment.embedded:type_name -> workflowcontract.v1.Policy + 11, // 7: workflowcontract.v1.PolicyAttachment.selector:type_name -> workflowcontract.v1.PolicyAttachment.MaterialSelector + 12, // 8: workflowcontract.v1.PolicyAttachment.with:type_name -> workflowcontract.v1.PolicyAttachment.PolicyArgument + 7, // 9: workflowcontract.v1.Policy.metadata:type_name -> workflowcontract.v1.Metadata + 8, // 10: workflowcontract.v1.Policy.spec:type_name -> workflowcontract.v1.PolicySpec + 1, // 11: workflowcontract.v1.PolicySpec.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 0, // 12: workflowcontract.v1.CraftingSchema.Runner.type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType + 1, // 13: workflowcontract.v1.CraftingSchema.Material.type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 3, // 14: workflowcontract.v1.CraftingSchema.Material.annotations:type_name -> workflowcontract.v1.Annotation + 15, // [15:15] is the sub-list for method output_type + 15, // [15:15] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_workflowcontract_v1_crafting_schema_proto_init() } @@ -890,7 +1212,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicyAttachment); i { + switch v := v.(*Policies); i { case 0: return &v.state case 1: @@ -902,7 +1224,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CraftingSchema_Runner); i { + switch v := v.(*PolicyAttachment); i { case 0: return &v.state case 1: @@ -914,7 +1236,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CraftingSchema_Material); i { + switch v := v.(*Policy); i { case 0: return &v.state case 1: @@ -926,7 +1248,7 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicyAttachment_MaterialSelector); i { + switch v := v.(*Metadata); i { case 0: return &v.state case 1: @@ -938,6 +1260,54 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } file_workflowcontract_v1_crafting_schema_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicySpec); 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[7].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[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CraftingSchema_Material); 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[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PolicyAttachment_MaterialSelector); 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[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PolicyAttachment_PolicyArgument); i { case 0: return &v.state @@ -950,9 +1320,13 @@ func file_workflowcontract_v1_crafting_schema_proto_init() { } } } - file_workflowcontract_v1_crafting_schema_proto_msgTypes[2].OneofWrappers = []interface{}{ + file_workflowcontract_v1_crafting_schema_proto_msgTypes[3].OneofWrappers = []interface{}{ (*PolicyAttachment_Ref)(nil), - (*PolicyAttachment_Name)(nil), + (*PolicyAttachment_Embedded)(nil), + } + file_workflowcontract_v1_crafting_schema_proto_msgTypes[6].OneofWrappers = []interface{}{ + (*PolicySpec_Path)(nil), + (*PolicySpec_Embedded)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -960,7 +1334,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: 7, + NumMessages: 11, 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 77299c13b..8f08c11d4 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema.proto +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema.proto @@ -34,7 +34,8 @@ message CraftingSchema { // It works in addition to the annotations defined in the materials and the runner repeated Annotation annotations = 5; - repeated PolicyAttachment policies = 6; + // Policies to apply to this schema + Policies policies = 6; message Runner { RunnerType type = 1 [ @@ -106,20 +107,30 @@ message Annotation { string value = 2; } +message Policies { + // Policies to be applied to materials + repeated PolicyAttachment materials = 1; + // Policies to be applied to attestation metadata + repeated PolicyAttachment attestation = 2; +} + // A policy to be applied to this contract message PolicyAttachment { oneof policy { // policy reference, it might be in URI format. string ref = 1 [(buf.validate.field).string.min_len = 1]; - // reference to a policy already known by chainloop - string name = 2 [(buf.validate.field) = { - 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", - }, - }]; + // meant to be used to embed the policy in the contract + Policy embedded = 2; + + // TODO: reference to a policy already known by chainloop + // string name = 2 [(buf.validate.field) = { + // 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", + // }, + // }]; option (buf.validate.oneof).required = true; } @@ -144,3 +155,40 @@ message PolicyAttachment { string value = 2 [(buf.validate.field).required = true];; } } + +// Represents a policy to be applied to a material or attestation +message Policy { + string api_version = 1 [(buf.validate.field).string.const = "workflowcontract.chainloop.dev/v1"]; + string kind = 2 [(buf.validate.field).string.const = "Policy"]; + + Metadata metadata = 3 [(buf.validate.field).required = true]; + PolicySpec spec = 4 [(buf.validate.field).required = true]; +} + +message Metadata { + // the name of the policy + string name = 3 [(buf.validate.field) = { + 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", + }, + }]; +} + +message PolicySpec { + oneof source { + // path to a policy script. It might consist of a URI reference + string path = 1; + + // embedded source code (only Rego supported currently) + string embedded = 2; + + option (buf.validate.oneof).required = true; + }; + + // if set, it will match any material supported by Chainloop + // except those not having a direct schema (STRING, ARTIFACT, EVIDENCE), since their format cannot be guessed by the crafter. + // CONTAINER, HELM_CHART are also excluded, but we might implement custom policies for them in the future. + CraftingSchema.Material.MaterialType type = 3 [(buf.validate.field).enum = { not_in: [1, 2, 3, 10, 11]}]; +} diff --git a/app/controlplane/api/workflowcontract/v1/crafting_schema_test.go b/app/controlplane/api/workflowcontract/v1/crafting_schema_test.go index 2879d3a34..20ad1770d 100644 --- a/app/controlplane/api/workflowcontract/v1/crafting_schema_test.go +++ b/app/controlplane/api/workflowcontract/v1/crafting_schema_test.go @@ -112,15 +112,10 @@ func TestPolicyAttachment(t *testing.T) { policy: &v1.PolicyAttachment{Policy: &v1.PolicyAttachment_Ref{Ref: "reference"}}, wantErr: false, }, - { - desc: "policy name", - policy: &v1.PolicyAttachment{Policy: &v1.PolicyAttachment_Name{Name: "name"}}, - wantErr: false, - }, { desc: "incomplete arguments", policy: &v1.PolicyAttachment{ - Policy: &v1.PolicyAttachment_Name{Name: "name"}, + Policy: &v1.PolicyAttachment_Ref{Ref: "reference"}, With: []*v1.PolicyAttachment_PolicyArgument{ { Name: "name", @@ -133,7 +128,7 @@ func TestPolicyAttachment(t *testing.T) { { desc: "complete arguments", policy: &v1.PolicyAttachment{ - Policy: &v1.PolicyAttachment_Name{Name: "name"}, + Policy: &v1.PolicyAttachment_Ref{Ref: "reference"}, With: []*v1.PolicyAttachment_PolicyArgument{ { Name: "name", diff --git a/app/controlplane/api/workflowcontract/v1/policy.pb.go b/app/controlplane/api/workflowcontract/v1/policy.pb.go deleted file mode 100644 index 9cad6ba83..000000000 --- a/app/controlplane/api/workflowcontract/v1/policy.pb.go +++ /dev/null @@ -1,470 +0,0 @@ -// -// Copyright 2024 The Chainloop Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.31.0 -// protoc (unknown) -// source: workflowcontract/v1/policy.proto - -package v1 - -import ( - _ "buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go/buf/validate" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// buf:lint:ignore ENUM_VALUE_PREFIX ENUM_ZERO_VALUE_SUFFIX -// buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX -type PolicySpec_PolicyStage int32 - -const ( - PolicySpec_UNSPECIFIED PolicySpec_PolicyStage = 0 - PolicySpec_PUSH PolicySpec_PolicyStage = 1 -) - -// Enum value maps for PolicySpec_PolicyStage. -var ( - PolicySpec_PolicyStage_name = map[int32]string{ - 0: "UNSPECIFIED", - 1: "PUSH", - } - PolicySpec_PolicyStage_value = map[string]int32{ - "UNSPECIFIED": 0, - "PUSH": 1, - } -) - -func (x PolicySpec_PolicyStage) Enum() *PolicySpec_PolicyStage { - p := new(PolicySpec_PolicyStage) - *p = x - return p -} - -func (x PolicySpec_PolicyStage) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (PolicySpec_PolicyStage) Descriptor() protoreflect.EnumDescriptor { - return file_workflowcontract_v1_policy_proto_enumTypes[0].Descriptor() -} - -func (PolicySpec_PolicyStage) Type() protoreflect.EnumType { - return &file_workflowcontract_v1_policy_proto_enumTypes[0] -} - -func (x PolicySpec_PolicyStage) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use PolicySpec_PolicyStage.Descriptor instead. -func (PolicySpec_PolicyStage) EnumDescriptor() ([]byte, []int) { - return file_workflowcontract_v1_policy_proto_rawDescGZIP(), []int{2, 0} -} - -type Policy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ApiVersion string `protobuf:"bytes,1,opt,name=api_version,json=apiVersion,proto3" json:"api_version,omitempty"` - Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` - Metadata *Metadata `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata,omitempty"` - Spec *PolicySpec `protobuf:"bytes,4,opt,name=spec,proto3" json:"spec,omitempty"` -} - -func (x *Policy) Reset() { - *x = Policy{} - if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_policy_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Policy) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Policy) ProtoMessage() {} - -func (x *Policy) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_policy_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Policy.ProtoReflect.Descriptor instead. -func (*Policy) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_policy_proto_rawDescGZIP(), []int{0} -} - -func (x *Policy) GetApiVersion() string { - if x != nil { - return x.ApiVersion - } - return "" -} - -func (x *Policy) GetKind() string { - if x != nil { - return x.Kind - } - return "" -} - -func (x *Policy) GetMetadata() *Metadata { - if x != nil { - return x.Metadata - } - return nil -} - -func (x *Policy) GetSpec() *PolicySpec { - if x != nil { - return x.Spec - } - return nil -} - -type Metadata struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // the name of the policy - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` -} - -func (x *Metadata) Reset() { - *x = Metadata{} - if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_policy_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Metadata) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Metadata) ProtoMessage() {} - -func (x *Metadata) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_policy_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Metadata.ProtoReflect.Descriptor instead. -func (*Metadata) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_policy_proto_rawDescGZIP(), []int{1} -} - -func (x *Metadata) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -type PolicySpec struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Source: - // - // *PolicySpec_Path - // *PolicySpec_Embedded - Source isPolicySpec_Source `protobuf_oneof:"source"` - // stage at which this policy will be run. - // Only "push" is supported currently and this field will be ignored - Stage PolicySpec_PolicyStage `protobuf:"varint,3,opt,name=stage,proto3,enum=workflowcontract.v1.PolicySpec_PolicyStage" json:"stage,omitempty"` - // if set, it will match a material kind supported by Chainloop. - Kind CraftingSchema_Material_MaterialType `protobuf:"varint,4,opt,name=kind,proto3,enum=workflowcontract.v1.CraftingSchema_Material_MaterialType" json:"kind,omitempty"` -} - -func (x *PolicySpec) Reset() { - *x = PolicySpec{} - if protoimpl.UnsafeEnabled { - mi := &file_workflowcontract_v1_policy_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PolicySpec) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PolicySpec) ProtoMessage() {} - -func (x *PolicySpec) ProtoReflect() protoreflect.Message { - mi := &file_workflowcontract_v1_policy_proto_msgTypes[2] - 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 PolicySpec.ProtoReflect.Descriptor instead. -func (*PolicySpec) Descriptor() ([]byte, []int) { - return file_workflowcontract_v1_policy_proto_rawDescGZIP(), []int{2} -} - -func (m *PolicySpec) GetSource() isPolicySpec_Source { - if m != nil { - return m.Source - } - return nil -} - -func (x *PolicySpec) GetPath() string { - if x, ok := x.GetSource().(*PolicySpec_Path); ok { - return x.Path - } - return "" -} - -func (x *PolicySpec) GetEmbedded() string { - if x, ok := x.GetSource().(*PolicySpec_Embedded); ok { - return x.Embedded - } - return "" -} - -func (x *PolicySpec) GetStage() PolicySpec_PolicyStage { - if x != nil { - return x.Stage - } - return PolicySpec_UNSPECIFIED -} - -func (x *PolicySpec) GetKind() CraftingSchema_Material_MaterialType { - if x != nil { - return x.Kind - } - return CraftingSchema_Material_MATERIAL_TYPE_UNSPECIFIED -} - -type isPolicySpec_Source interface { - isPolicySpec_Source() -} - -type PolicySpec_Path struct { - // path to a policy script. It might consist of a URI reference - Path string `protobuf:"bytes,1,opt,name=path,proto3,oneof"` -} - -type PolicySpec_Embedded struct { - // embedded source code (only Rego supported currently) - Embedded string `protobuf:"bytes,2,opt,name=embedded,proto3,oneof"` -} - -func (*PolicySpec_Path) isPolicySpec_Source() {} - -func (*PolicySpec_Embedded) isPolicySpec_Source() {} - -var File_workflowcontract_v1_policy_proto protoreflect.FileDescriptor - -var file_workflowcontract_v1_policy_proto_rawDesc = []byte{ - 0x0a, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x62, 0x75, 0x66, 0x2f, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x61, 0x66, 0x74, 0x69, - 0x6e, 0x67, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xf6, 0x01, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 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, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x6c, 0x6f, - 0x6f, 0x70, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x76, 0x31, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x0a, 0x72, 0x08, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x41, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2e, 0x76, 0x31, - 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, - 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x3b, 0x0a, 0x04, 0x73, - 0x70, 0x65, 0x63, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 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, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, - 0x01, 0x01, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0xa4, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x97, 0x01, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, - 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, 0x22, - 0x8d, 0x02, 0x0a, 0x0a, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x70, 0x65, 0x63, 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, 0x41, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x2b, 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, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x4d, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x04, 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, 0x52, 0x04, - 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x28, 0x0a, 0x0b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x74, - 0x61, 0x67, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x55, 0x53, 0x48, 0x10, 0x01, 0x42, 0x0f, - 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 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 ( - file_workflowcontract_v1_policy_proto_rawDescOnce sync.Once - file_workflowcontract_v1_policy_proto_rawDescData = file_workflowcontract_v1_policy_proto_rawDesc -) - -func file_workflowcontract_v1_policy_proto_rawDescGZIP() []byte { - file_workflowcontract_v1_policy_proto_rawDescOnce.Do(func() { - file_workflowcontract_v1_policy_proto_rawDescData = protoimpl.X.CompressGZIP(file_workflowcontract_v1_policy_proto_rawDescData) - }) - return file_workflowcontract_v1_policy_proto_rawDescData -} - -var file_workflowcontract_v1_policy_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_workflowcontract_v1_policy_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_workflowcontract_v1_policy_proto_goTypes = []interface{}{ - (PolicySpec_PolicyStage)(0), // 0: workflowcontract.v1.PolicySpec.PolicyStage - (*Policy)(nil), // 1: workflowcontract.v1.Policy - (*Metadata)(nil), // 2: workflowcontract.v1.Metadata - (*PolicySpec)(nil), // 3: workflowcontract.v1.PolicySpec - (CraftingSchema_Material_MaterialType)(0), // 4: workflowcontract.v1.CraftingSchema.Material.MaterialType -} -var file_workflowcontract_v1_policy_proto_depIdxs = []int32{ - 2, // 0: workflowcontract.v1.Policy.metadata:type_name -> workflowcontract.v1.Metadata - 3, // 1: workflowcontract.v1.Policy.spec:type_name -> workflowcontract.v1.PolicySpec - 0, // 2: workflowcontract.v1.PolicySpec.stage:type_name -> workflowcontract.v1.PolicySpec.PolicyStage - 4, // 3: workflowcontract.v1.PolicySpec.kind:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name -} - -func init() { file_workflowcontract_v1_policy_proto_init() } -func file_workflowcontract_v1_policy_proto_init() { - if File_workflowcontract_v1_policy_proto != nil { - return - } - file_workflowcontract_v1_crafting_schema_proto_init() - if !protoimpl.UnsafeEnabled { - file_workflowcontract_v1_policy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Policy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_workflowcontract_v1_policy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metadata); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_workflowcontract_v1_policy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PolicySpec); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_workflowcontract_v1_policy_proto_msgTypes[2].OneofWrappers = []interface{}{ - (*PolicySpec_Path)(nil), - (*PolicySpec_Embedded)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_workflowcontract_v1_policy_proto_rawDesc, - NumEnums: 1, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_workflowcontract_v1_policy_proto_goTypes, - DependencyIndexes: file_workflowcontract_v1_policy_proto_depIdxs, - EnumInfos: file_workflowcontract_v1_policy_proto_enumTypes, - MessageInfos: file_workflowcontract_v1_policy_proto_msgTypes, - }.Build() - File_workflowcontract_v1_policy_proto = out.File - file_workflowcontract_v1_policy_proto_rawDesc = nil - file_workflowcontract_v1_policy_proto_goTypes = nil - file_workflowcontract_v1_policy_proto_depIdxs = nil -} diff --git a/app/controlplane/api/workflowcontract/v1/policy.proto b/app/controlplane/api/workflowcontract/v1/policy.proto deleted file mode 100644 index 1c8ab6799..000000000 --- a/app/controlplane/api/workflowcontract/v1/policy.proto +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2024 The Chainloop Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package workflowcontract.v1; - -import "buf/validate/validate.proto"; -import "workflowcontract/v1/crafting_schema.proto"; - -option go_package = "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"; - -message Policy { - string api_version = 1 [(buf.validate.field).string.const = "workflowcontract.chainloop.dev/v1"]; - string kind = 2 [(buf.validate.field).string.const = "Policy"]; - - Metadata metadata = 3 [(buf.validate.field).required = true]; - PolicySpec spec = 4 [(buf.validate.field).required = true]; -} - -message Metadata { - // the name of the policy - string name = 3 [(buf.validate.field) = { - 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", - }, - }]; -} - -message PolicySpec { - oneof source { - // path to a policy script. It might consist of a URI reference - string path = 1; - - // embedded source code (only Rego supported currently) - string embedded = 2; - - option (buf.validate.oneof).required = true; - }; - - // stage at which this policy will be run. - // Only "push" is supported currently and this field will be ignored - PolicyStage stage = 3; - - // if set, it will match a material kind supported by Chainloop. - CraftingSchema.Material.MaterialType kind = 4; - - // buf:lint:ignore ENUM_VALUE_PREFIX ENUM_ZERO_VALUE_SUFFIX - // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX - enum PolicyStage { - UNSPECIFIED = 0; - PUSH = 1; - } -} diff --git a/app/controlplane/api/workflowcontract/v1/policy_test.go b/app/controlplane/api/workflowcontract/v1/policy_test.go index 537f00897..7d7b0cbfc 100644 --- a/app/controlplane/api/workflowcontract/v1/policy_test.go +++ b/app/controlplane/api/workflowcontract/v1/policy_test.go @@ -85,7 +85,7 @@ func TestValidatePolicy(t *testing.T) { { desc: "filter material type", policy: &v1.Policy{ApiVersion: "workflowcontract.chainloop.dev/v1", Kind: "Policy", - Metadata: &v1.Metadata{Name: "my-policy"}, Spec: &v1.PolicySpec{Source: &v1.PolicySpec_Path{Path: "policy.rego"}, Kind: v1.CraftingSchema_Material_ATTESTATION}}, + Metadata: &v1.Metadata{Name: "my-policy"}, Spec: &v1.PolicySpec{Source: &v1.PolicySpec_Path{Path: "policy.rego"}, Type: v1.CraftingSchema_Material_ATTESTATION}}, wantErr: false, }, } diff --git a/internal/attestation/crafter/api/attestation/v1/crafting_state.pb.go b/internal/attestation/crafter/api/attestation/v1/crafting_state.pb.go index 0b1f3a1f5..e9f6473d8 100644 --- a/internal/attestation/crafter/api/attestation/v1/crafting_state.pb.go +++ b/internal/attestation/crafter/api/attestation/v1/crafting_state.pb.go @@ -55,8 +55,8 @@ type Attestation struct { RunnerType v1.CraftingSchema_Runner_RunnerType `protobuf:"varint,8,opt,name=runner_type,json=runnerType,proto3,enum=workflowcontract.v1.CraftingSchema_Runner_RunnerType" json:"runner_type,omitempty"` // Head Commit of the environment where the attestation was executed (optional) Head *Commit `protobuf:"bytes,9,opt,name=head,proto3" json:"head,omitempty"` - // Policies that this attestation was validated against - Policies []*Policy `protobuf:"bytes,10,rep,name=policies,proto3" json:"policies,omitempty"` + // Policies that materials in this attestation were validated against + PolicyEvaluations []*PolicyEvaluation `protobuf:"bytes,10,rep,name=policy_evaluations,json=policyEvaluations,proto3" json:"policy_evaluations,omitempty"` } func (x *Attestation) Reset() { @@ -154,31 +154,30 @@ func (x *Attestation) GetHead() *Commit { return nil } -func (x *Attestation) GetPolicies() []*Policy { +func (x *Attestation) GetPolicyEvaluations() []*PolicyEvaluation { if x != nil { - return x.Policies + return x.PolicyEvaluations } return nil } -// A policy executed against an attestation -type Policy struct { +// A policy executed against an attestation or material +type PolicyEvaluation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // The policy name from the policy spec - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // The attachment as in the contract, with arguments and any other metadata - Attachment *v1.PolicyAttachment `protobuf:"bytes,2,opt,name=attachment,proto3" json:"attachment,omitempty"` - // The policy script body (rego) + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + MaterialName string `protobuf:"bytes,2,opt,name=material_name,json=materialName,proto3" json:"material_name,omitempty"` + // The body script of the policy Body string `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"` // The policy violations, if any - Violations []*Policy_Violation `protobuf:"bytes,4,rep,name=violations,proto3" json:"violations,omitempty"` + Violations []*PolicyEvaluation_Violation `protobuf:"bytes,4,rep,name=violations,proto3" json:"violations,omitempty"` } -func (x *Policy) Reset() { - *x = Policy{} +func (x *PolicyEvaluation) Reset() { + *x = PolicyEvaluation{} if protoimpl.UnsafeEnabled { mi := &file_attestation_v1_crafting_state_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -186,13 +185,13 @@ func (x *Policy) Reset() { } } -func (x *Policy) String() string { +func (x *PolicyEvaluation) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Policy) ProtoMessage() {} +func (*PolicyEvaluation) ProtoMessage() {} -func (x *Policy) ProtoReflect() protoreflect.Message { +func (x *PolicyEvaluation) ProtoReflect() protoreflect.Message { mi := &file_attestation_v1_crafting_state_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -204,33 +203,33 @@ func (x *Policy) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Policy.ProtoReflect.Descriptor instead. -func (*Policy) Descriptor() ([]byte, []int) { +// Deprecated: Use PolicyEvaluation.ProtoReflect.Descriptor instead. +func (*PolicyEvaluation) Descriptor() ([]byte, []int) { return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{1} } -func (x *Policy) GetName() string { +func (x *PolicyEvaluation) GetName() string { if x != nil { return x.Name } return "" } -func (x *Policy) GetAttachment() *v1.PolicyAttachment { +func (x *PolicyEvaluation) GetMaterialName() string { if x != nil { - return x.Attachment + return x.MaterialName } - return nil + return "" } -func (x *Policy) GetBody() string { +func (x *PolicyEvaluation) GetBody() string { if x != nil { return x.Body } return "" } -func (x *Policy) GetViolations() []*Policy_Violation { +func (x *PolicyEvaluation) GetViolations() []*PolicyEvaluation_Violation { if x != nil { return x.Violations } @@ -843,7 +842,7 @@ func (x *Attestation_Material_Artifact) GetContent() []byte { return nil } -type Policy_Violation struct { +type PolicyEvaluation_Violation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -852,8 +851,8 @@ type Policy_Violation struct { Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` } -func (x *Policy_Violation) Reset() { - *x = Policy_Violation{} +func (x *PolicyEvaluation_Violation) Reset() { + *x = PolicyEvaluation_Violation{} if protoimpl.UnsafeEnabled { mi := &file_attestation_v1_crafting_state_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -861,13 +860,13 @@ func (x *Policy_Violation) Reset() { } } -func (x *Policy_Violation) String() string { +func (x *PolicyEvaluation_Violation) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Policy_Violation) ProtoMessage() {} +func (*PolicyEvaluation_Violation) ProtoMessage() {} -func (x *Policy_Violation) ProtoReflect() protoreflect.Message { +func (x *PolicyEvaluation_Violation) ProtoReflect() protoreflect.Message { mi := &file_attestation_v1_crafting_state_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -879,19 +878,19 @@ func (x *Policy_Violation) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Policy_Violation.ProtoReflect.Descriptor instead. -func (*Policy_Violation) Descriptor() ([]byte, []int) { +// Deprecated: Use PolicyEvaluation_Violation.ProtoReflect.Descriptor instead. +func (*PolicyEvaluation_Violation) Descriptor() ([]byte, []int) { return file_attestation_v1_crafting_state_proto_rawDescGZIP(), []int{1, 0} } -func (x *Policy_Violation) GetSubject() string { +func (x *PolicyEvaluation_Violation) GetSubject() string { if x != nil { return x.Subject } return "" } -func (x *Policy_Violation) GetMessage() string { +func (x *PolicyEvaluation_Violation) GetMessage() string { if x != nil { return x.Message } @@ -965,7 +964,7 @@ var file_attestation_v1_crafting_state_proto_rawDesc = []byte{ 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x29, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x72, 0x61, 0x66, 0x74, 0x69, 0x6e, - 0x67, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, + 0x67, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa1, 0x0f, 0x0a, 0x0b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, @@ -1004,170 +1003,170 @@ var file_attestation_v1_crafting_state_proto_rawDesc = []byte{ 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x32, 0x0a, 0x08, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x4f, 0x0a, 0x12, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x62, 0x0a, + 0x0e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 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, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x24, 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, 0x2e, 0x4d, 0x61, + 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 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, 0x82, 0x08, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x12, 0x45, + 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x1a, 0x62, 0x0a, 0x0e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 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, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x24, 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, - 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 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, 0x82, 0x08, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, - 0x6c, 0x12, 0x45, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2b, 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, 0x2e, 0x4d, - 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x48, 0x00, - 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x5e, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x33, 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, 0x2e, 0x4d, - 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, - 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x48, 0x00, 0x52, 0x08, 0x61, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x61, - 0x74, 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, 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, 0x41, 0x74, 0x12, 0x5e, 0x0a, 0x0d, - 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x63, 0x6f, + 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x06, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x5e, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, + 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, + 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x48, 0x00, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x61, 0x74, 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, 0x07, 0x61, 0x64, 0x64, 0x65, 0x64, 0x41, 0x74, 0x12, 0x5e, 0x0a, 0x0d, 0x6d, 0x61, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 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, 0x52, 0x0c, 0x6d, 0x61, 0x74, + 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x75, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x61, 0x73, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0d, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x54, 0x6f, 0x43, 0x61, + 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x61, 0x73, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x61, 0x73, + 0x12, 0x65, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x0c, 0xba, 0x48, + 0x09, 0x9a, 0x01, 0x06, 0x2a, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x40, 0x0a, 0x06, 0x4b, 0x65, 0x79, 0x56, 0x61, + 0x6c, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, + 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, + 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x98, 0x01, 0x0a, 0x0e, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x17, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x64, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x74, 0x61, 0x67, 0x1a, 0x9a, 0x01, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, + 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, + 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, + 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x42, 0x03, 0x0a, 0x01, 0x6d, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, + 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, 0x8a, 0x03, 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, 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, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x04, 0x62, 0x6f, + 0x64, 0x79, 0x12, 0x4a, 0x0a, 0x0a, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x04, 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, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0a, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 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, 0x22, + 0xc9, 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, 0x2a, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, + 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 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, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, - 0x6c, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, - 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x26, 0x0a, 0x0f, - 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x63, 0x61, 0x73, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x54, - 0x6f, 0x43, 0x61, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, - 0x61, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, - 0x43, 0x61, 0x73, 0x12, 0x65, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 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, 0x2e, 0x4d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x41, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, - 0x0c, 0xba, 0x48, 0x09, 0x9a, 0x01, 0x06, 0x2a, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x61, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x40, 0x0a, 0x06, 0x4b, 0x65, - 0x79, 0x56, 0x61, 0x6c, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, - 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x98, 0x01, 0x0a, - 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, - 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, - 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x73, 0x75, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x53, 0x75, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x1a, 0x9a, 0x01, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x12, 0x17, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x64, 0x69, - 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, - 0x02, 0x10, 0x01, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x69, - 0x73, 0x5f, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x69, 0x73, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x42, 0x03, 0x0a, 0x01, 0x6d, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x6e, 0x76, - 0x56, 0x61, 0x72, 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, 0xa0, 0x03, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 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, 0x4d, 0x0a, 0x0a, 0x61, 0x74, - 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 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, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0a, 0x61, - 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x04, 0x62, 0x6f, 0x64, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, - 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x40, 0x0a, 0x0a, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x76, 0x69, 0x6f, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 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, 0x22, 0xc9, 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, 0x2a, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 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, 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, 0x8e, 0x02, 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, 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, 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, 0x42, 0x54, 0x5a, 0x52, 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, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 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, + 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, 0x8e, 0x02, + 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, 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, 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, 0x42, 0x54, + 0x5a, 0x52, 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, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 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 ( @@ -1185,7 +1184,7 @@ func file_attestation_v1_crafting_state_proto_rawDescGZIP() []byte { var file_attestation_v1_crafting_state_proto_msgTypes = make([]protoimpl.MessageInfo, 15) var file_attestation_v1_crafting_state_proto_goTypes = []interface{}{ (*Attestation)(nil), // 0: attestation.v1.Attestation - (*Policy)(nil), // 1: attestation.v1.Policy + (*PolicyEvaluation)(nil), // 1: attestation.v1.PolicyEvaluation (*Commit)(nil), // 2: attestation.v1.Commit (*CraftingState)(nil), // 3: attestation.v1.CraftingState (*WorkflowMetadata)(nil), // 4: attestation.v1.WorkflowMetadata @@ -1197,13 +1196,12 @@ var file_attestation_v1_crafting_state_proto_goTypes = []interface{}{ (*Attestation_Material_KeyVal)(nil), // 10: attestation.v1.Attestation.Material.KeyVal (*Attestation_Material_ContainerImage)(nil), // 11: attestation.v1.Attestation.Material.ContainerImage (*Attestation_Material_Artifact)(nil), // 12: attestation.v1.Attestation.Material.Artifact - (*Policy_Violation)(nil), // 13: attestation.v1.Policy.Violation + (*PolicyEvaluation_Violation)(nil), // 13: attestation.v1.PolicyEvaluation.Violation (*Commit_Remote)(nil), // 14: attestation.v1.Commit.Remote (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp (v1.CraftingSchema_Runner_RunnerType)(0), // 16: workflowcontract.v1.CraftingSchema.Runner.RunnerType - (*v1.PolicyAttachment)(nil), // 17: workflowcontract.v1.PolicyAttachment - (*v1.CraftingSchema)(nil), // 18: workflowcontract.v1.CraftingSchema - (v1.CraftingSchema_Material_MaterialType)(0), // 19: workflowcontract.v1.CraftingSchema.Material.MaterialType + (*v1.CraftingSchema)(nil), // 17: workflowcontract.v1.CraftingSchema + (v1.CraftingSchema_Material_MaterialType)(0), // 18: workflowcontract.v1.CraftingSchema.Material.MaterialType } var file_attestation_v1_crafting_state_proto_depIdxs = []int32{ 15, // 0: attestation.v1.Attestation.initialized_at:type_name -> google.protobuf.Timestamp @@ -1214,25 +1212,24 @@ var file_attestation_v1_crafting_state_proto_depIdxs = []int32{ 8, // 5: attestation.v1.Attestation.env_vars:type_name -> attestation.v1.Attestation.EnvVarsEntry 16, // 6: attestation.v1.Attestation.runner_type:type_name -> workflowcontract.v1.CraftingSchema.Runner.RunnerType 2, // 7: attestation.v1.Attestation.head:type_name -> attestation.v1.Commit - 1, // 8: attestation.v1.Attestation.policies:type_name -> attestation.v1.Policy - 17, // 9: attestation.v1.Policy.attachment:type_name -> workflowcontract.v1.PolicyAttachment - 13, // 10: attestation.v1.Policy.violations:type_name -> attestation.v1.Policy.Violation - 15, // 11: attestation.v1.Commit.date:type_name -> google.protobuf.Timestamp - 14, // 12: attestation.v1.Commit.remotes:type_name -> attestation.v1.Commit.Remote - 18, // 13: attestation.v1.CraftingState.input_schema:type_name -> workflowcontract.v1.CraftingSchema - 0, // 14: attestation.v1.CraftingState.attestation:type_name -> attestation.v1.Attestation - 7, // 15: attestation.v1.Attestation.MaterialsEntry.value:type_name -> attestation.v1.Attestation.Material - 10, // 16: attestation.v1.Attestation.Material.string:type_name -> attestation.v1.Attestation.Material.KeyVal - 11, // 17: attestation.v1.Attestation.Material.container_image:type_name -> attestation.v1.Attestation.Material.ContainerImage - 12, // 18: attestation.v1.Attestation.Material.artifact:type_name -> attestation.v1.Attestation.Material.Artifact - 15, // 19: attestation.v1.Attestation.Material.added_at:type_name -> google.protobuf.Timestamp - 19, // 20: attestation.v1.Attestation.Material.material_type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType - 9, // 21: attestation.v1.Attestation.Material.annotations:type_name -> attestation.v1.Attestation.Material.AnnotationsEntry - 22, // [22:22] is the sub-list for method output_type - 22, // [22:22] is the sub-list for method input_type - 22, // [22:22] is the sub-list for extension type_name - 22, // [22:22] is the sub-list for extension extendee - 0, // [0:22] is the sub-list for field type_name + 1, // 8: attestation.v1.Attestation.policy_evaluations:type_name -> attestation.v1.PolicyEvaluation + 13, // 9: attestation.v1.PolicyEvaluation.violations:type_name -> attestation.v1.PolicyEvaluation.Violation + 15, // 10: attestation.v1.Commit.date:type_name -> google.protobuf.Timestamp + 14, // 11: attestation.v1.Commit.remotes:type_name -> attestation.v1.Commit.Remote + 17, // 12: attestation.v1.CraftingState.input_schema:type_name -> workflowcontract.v1.CraftingSchema + 0, // 13: attestation.v1.CraftingState.attestation:type_name -> attestation.v1.Attestation + 7, // 14: attestation.v1.Attestation.MaterialsEntry.value:type_name -> attestation.v1.Attestation.Material + 10, // 15: attestation.v1.Attestation.Material.string:type_name -> attestation.v1.Attestation.Material.KeyVal + 11, // 16: attestation.v1.Attestation.Material.container_image:type_name -> attestation.v1.Attestation.Material.ContainerImage + 12, // 17: attestation.v1.Attestation.Material.artifact:type_name -> attestation.v1.Attestation.Material.Artifact + 15, // 18: attestation.v1.Attestation.Material.added_at:type_name -> google.protobuf.Timestamp + 18, // 19: attestation.v1.Attestation.Material.material_type:type_name -> workflowcontract.v1.CraftingSchema.Material.MaterialType + 9, // 20: attestation.v1.Attestation.Material.annotations:type_name -> attestation.v1.Attestation.Material.AnnotationsEntry + 21, // [21:21] is the sub-list for method output_type + 21, // [21:21] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name } func init() { file_attestation_v1_crafting_state_proto_init() } @@ -1254,7 +1251,7 @@ func file_attestation_v1_crafting_state_proto_init() { } } file_attestation_v1_crafting_state_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Policy); i { + switch v := v.(*PolicyEvaluation); i { case 0: return &v.state case 1: @@ -1350,7 +1347,7 @@ func file_attestation_v1_crafting_state_proto_init() { } } file_attestation_v1_crafting_state_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Policy_Violation); i { + switch v := v.(*PolicyEvaluation_Violation); i { case 0: return &v.state case 1: diff --git a/internal/attestation/crafter/api/attestation/v1/crafting_state.proto b/internal/attestation/crafter/api/attestation/v1/crafting_state.proto index a181e4260..f8b02b3ce 100644 --- a/internal/attestation/crafter/api/attestation/v1/crafting_state.proto +++ b/internal/attestation/crafter/api/attestation/v1/crafting_state.proto @@ -89,12 +89,12 @@ message Attestation { // Head Commit of the environment where the attestation was executed (optional) Commit head = 9; - // Policies that this attestation was validated against - repeated Policy policies = 10; + // Policies that materials in this attestation were validated against + repeated PolicyEvaluation policy_evaluations = 10; } -// A policy executed against an attestation -message Policy { +// A policy executed against an attestation or material +message PolicyEvaluation { // The policy name from the policy spec string name = 1 [(buf.validate.field) = { cel: { @@ -103,10 +103,12 @@ message Policy { id: "name.dns-1123", }, }]; - // The attachment as in the contract, with arguments and any other metadata - workflowcontract.v1.PolicyAttachment attachment = 2 [(buf.validate.field).required = true]; - // The policy script body (rego) + + string material_name = 2; + + // The body script of the policy string body = 3 [(buf.validate.field).required = true]; + // The policy violations, if any repeated Violation violations = 4; diff --git a/internal/attestation/crafter/crafter.go b/internal/attestation/crafter/crafter.go index e1a7ac1b5..be2c20b47 100644 --- a/internal/attestation/crafter/crafter.go +++ b/internal/attestation/crafter/crafter.go @@ -27,20 +27,19 @@ import ( "strings" "time" - "cuelang.org/go/cue/cuecontext" "github.com/bufbuild/protovalidate-go" schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" api "github.com/chainloop-dev/chainloop/internal/attestation/crafter/api/attestation/v1" "github.com/chainloop-dev/chainloop/internal/attestation/crafter/materials" "github.com/chainloop-dev/chainloop/internal/casclient" "github.com/chainloop-dev/chainloop/internal/ociauth" + "github.com/chainloop-dev/chainloop/pkg/policies" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/google/go-containerregistry/pkg/authn" "github.com/rs/zerolog" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/timestamppb" - "sigs.k8s.io/yaml" ) // StateManager is an interface for managing the state of the crafting process @@ -153,33 +152,6 @@ func (c *Crafter) AlreadyInitialized(ctx context.Context, stateID string) (bool, return c.stateManager.Initialized(ctx, stateID) } -// LoadJSONBytes Extracts raw data in JSON format from different sources, i.e cue or yaml files -func LoadJSONBytes(rawData []byte, extension string) ([]byte, error) { - var jsonRawData []byte - var err error - - switch extension { - case ".yaml", ".yml": - jsonRawData, err = yaml.YAMLToJSON(rawData) - if err != nil { - return nil, err - } - case ".cue": - ctx := cuecontext.New() - v := ctx.CompileBytes(rawData) - jsonRawData, err = v.MarshalJSON() - if err != nil { - return nil, err - } - case ".json": - jsonRawData = rawData - default: - return nil, errors.New("unsupported file format") - } - - return jsonRawData, nil -} - func LoadSchema(pathOrURI string) (*schemaapi.CraftingSchema, error) { // Extract json formatted data content, err := loadFileOrURL(pathOrURI) @@ -187,7 +159,7 @@ func LoadSchema(pathOrURI string) (*schemaapi.CraftingSchema, error) { return nil, err } - jsonSchemaRaw, err := LoadJSONBytes(content, filepath.Ext(pathOrURI)) + jsonSchemaRaw, err := materials.LoadJSONBytes(content, filepath.Ext(pathOrURI)) if err != nil { return nil, err } @@ -212,9 +184,31 @@ func LoadSchema(pathOrURI string) (*schemaapi.CraftingSchema, error) { return nil, err } + // Load, validate policies, and embed them in the schema + if err := validatePolicyAttachments(schema.GetPolicies().GetMaterials()); err != nil { + return nil, fmt.Errorf("validating policies: %w", err) + } + if err := validatePolicyAttachments(schema.GetPolicies().GetAttestation()); err != nil { + return nil, fmt.Errorf("validating policies: %w", err) + } + return schema, nil } +func validatePolicyAttachments(pols []*schemaapi.PolicyAttachment) error { + for _, p := range pols { + spec, err := policies.LoadPolicySpec(p) + if err != nil { + return fmt.Errorf("validating policy: %w", err) + } + if _, err := policies.LoadPolicyScriptFromSpec(spec); err != nil { + return fmt.Errorf("loading policy script: %w", err) + } + } + + return nil +} + // Initialize the temporary file with the content of the schema func (c *Crafter) initCraftingStateFile( ctx context.Context, @@ -577,13 +571,20 @@ func (c *Crafter) addMaterial(ctx context.Context, m *schemaapi.CraftingSchema_M return fmt.Errorf("validation error: %w", err) } + // Validate policies + pv := policies.NewPolicyVerifier(c.CraftingState.InputSchema, c.logger) + policyResults, err := pv.VerifyMaterial(ctx, mt, value) + if err != nil { + return fmt.Errorf("error applying policies to material: %w", err) + } + // store policy results + c.CraftingState.Attestation.PolicyEvaluations = append(c.CraftingState.Attestation.PolicyEvaluations, policyResults...) + // 5 - Attach it to state - if mt != nil { - if c.CraftingState.Attestation.Materials == nil { - c.CraftingState.Attestation.Materials = map[string]*api.Attestation_Material{m.Name: mt} - } - c.CraftingState.Attestation.Materials[m.Name] = mt + if c.CraftingState.Attestation.Materials == nil { + c.CraftingState.Attestation.Materials = map[string]*api.Attestation_Material{m.Name: mt} } + c.CraftingState.Attestation.Materials[m.Name] = mt // 6 - Persist state if err := c.stateManager.Write(ctx, attestationID, c.CraftingState); err != nil { diff --git a/internal/attestation/crafter/crafter_test.go b/internal/attestation/crafter/crafter_test.go index 48b37bb35..0cd336f02 100644 --- a/internal/attestation/crafter/crafter_test.go +++ b/internal/attestation/crafter/crafter_test.go @@ -182,22 +182,33 @@ func newInitializedCrafter(t *testing.T, contractPath string, wfMeta *v1.Workflo } func (s *crafterSuite) TestLoadSchema() { + want := &schemaapi.CraftingSchema{ + SchemaVersion: "v1", + Runner: &schemaapi.CraftingSchema_Runner{ + Type: schemaapi.CraftingSchema_Runner_GITHUB_ACTION, + }, + } + testCases := []struct { name string contractPath string + want *schemaapi.CraftingSchema wantErr bool }{ { name: "yaml", contractPath: "testdata/contracts/empty_github.yaml", + want: want, }, { name: "json", contractPath: "testdata/contracts/empty_github.json", + want: want, }, { name: "cue", contractPath: "testdata/contracts/empty_github.cue", + want: want, }, { name: "unsupported", @@ -209,6 +220,48 @@ func (s *crafterSuite) TestLoadSchema() { contractPath: "testdata/contracts/invalid.yaml", wantErr: true, }, + { + name: "policies", + contractPath: "testdata/contracts/with_policy_embedded.yaml", + want: &schemaapi.CraftingSchema{ + SchemaVersion: "v1", + Policies: &schemaapi.Policies{ + Attestation: []*schemaapi.PolicyAttachment{ + { + Policy: &schemaapi.PolicyAttachment_Ref{ + Ref: "testdata/policies/policy_embedded.yaml", + }, + }, + }, + }, + }, + }, + { + name: "missing policy", + contractPath: "testdata/contracts/with_missing_policy.yaml", + wantErr: true, + }, + { + name: "missing script", + contractPath: "testdata/contracts/with_policy_missing_rego.yaml", + wantErr: true, + }, + { + name: "rego policy", + contractPath: "testdata/contracts/with_rego.yaml", + want: &schemaapi.CraftingSchema{ + SchemaVersion: "v1", + Policies: &schemaapi.Policies{ + Attestation: []*schemaapi.PolicyAttachment{ + { + Policy: &schemaapi.PolicyAttachment_Ref{ + Ref: "testdata/policies/policy_rego.yaml", + }, + }, + }, + }, + }, + }, } for _, tc := range testCases { @@ -219,16 +272,11 @@ func (s *crafterSuite) TestLoadSchema() { return } - want := &schemaapi.CraftingSchema{ - SchemaVersion: "v1", - Runner: &schemaapi.CraftingSchema_Runner{ - Type: schemaapi.CraftingSchema_Runner_GITHUB_ACTION, - }, - } - - // Check state - if ok := proto.Equal(want, got); !ok { - s.Fail(fmt.Sprintf("These two protobuf messages are not equal:\nexpected: %v\nactual: %v", want, got)) + if tc.want != nil { + // Check state + if ok := proto.Equal(tc.want, got); !ok { + s.Fail(fmt.Sprintf("These two protobuf messages are not equal:\nexpected: %v\nactual: %v", want, got)) + } } }) } diff --git a/internal/attestation/crafter/materials/materials.go b/internal/attestation/crafter/materials/materials.go index 426d0bef2..d6743e218 100644 --- a/internal/attestation/crafter/materials/materials.go +++ b/internal/attestation/crafter/materials/materials.go @@ -24,6 +24,7 @@ import ( "time" "code.cloudfoundry.org/bytefmt" + "cuelang.org/go/cue/cuecontext" "github.com/bufbuild/protovalidate-go" schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" api "github.com/chainloop-dev/chainloop/internal/attestation/crafter/api/attestation/v1" @@ -32,6 +33,7 @@ import ( cr_v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/rs/zerolog" "google.golang.org/protobuf/types/known/timestamppb" + "sigs.k8s.io/yaml" ) var ( @@ -207,3 +209,30 @@ func Craft(ctx context.Context, materialSchema *schemaapi.CraftingSchema_Materia return m, nil } + +// LoadJSONBytes Extracts raw data in JSON format from different sources, i.e cue or yaml files +func LoadJSONBytes(rawData []byte, extension string) ([]byte, error) { + var jsonRawData []byte + var err error + + switch extension { + case ".yaml", ".yml": + jsonRawData, err = yaml.YAMLToJSON(rawData) + if err != nil { + return nil, err + } + case ".cue": + ctx := cuecontext.New() + v := ctx.CompileBytes(rawData) + jsonRawData, err = v.MarshalJSON() + if err != nil { + return nil, err + } + case ".json": + jsonRawData = rawData + default: + return nil, errors.New("unsupported file format") + } + + return jsonRawData, nil +} diff --git a/internal/attestation/crafter/testdata/contracts/with_missing_policy.yaml b/internal/attestation/crafter/testdata/contracts/with_missing_policy.yaml new file mode 100644 index 000000000..febaded54 --- /dev/null +++ b/internal/attestation/crafter/testdata/contracts/with_missing_policy.yaml @@ -0,0 +1,4 @@ +schemaVersion: "v1" +policies: + attestation: + - ref: idontexist.yaml diff --git a/internal/attestation/crafter/testdata/contracts/with_policy_embedded.yaml b/internal/attestation/crafter/testdata/contracts/with_policy_embedded.yaml new file mode 100644 index 000000000..39dcb1325 --- /dev/null +++ b/internal/attestation/crafter/testdata/contracts/with_policy_embedded.yaml @@ -0,0 +1,4 @@ +schemaVersion: "v1" +policies: + attestation: + - ref: testdata/policies/policy_embedded.yaml diff --git a/internal/attestation/crafter/testdata/contracts/with_policy_missing_rego.yaml b/internal/attestation/crafter/testdata/contracts/with_policy_missing_rego.yaml new file mode 100644 index 000000000..4260c1de3 --- /dev/null +++ b/internal/attestation/crafter/testdata/contracts/with_policy_missing_rego.yaml @@ -0,0 +1,4 @@ +schemaVersion: "v1" +policies: + attestation: + - ref: testdata/policies/policy_missing_rego.yaml diff --git a/internal/attestation/crafter/testdata/contracts/with_rego.yaml b/internal/attestation/crafter/testdata/contracts/with_rego.yaml new file mode 100644 index 000000000..d56ca9902 --- /dev/null +++ b/internal/attestation/crafter/testdata/contracts/with_rego.yaml @@ -0,0 +1,4 @@ +schemaVersion: "v1" +policies: + attestation: + - ref: testdata/policies/policy_rego.yaml diff --git a/internal/attestation/crafter/testdata/policies/policy.rego b/internal/attestation/crafter/testdata/policies/policy.rego new file mode 100644 index 000000000..a6d0b5038 --- /dev/null +++ b/internal/attestation/crafter/testdata/policies/policy.rego @@ -0,0 +1,9 @@ +package main +deny[msg] { + not is_workflow + msg := "incorrect workflow" +} + +is_workflow { + input.workflow.name == "policytest" +} diff --git a/internal/attestation/crafter/testdata/policies/policy_embedded.yaml b/internal/attestation/crafter/testdata/policies/policy_embedded.yaml new file mode 100644 index 000000000..6e02a4062 --- /dev/null +++ b/internal/attestation/crafter/testdata/policies/policy_embedded.yaml @@ -0,0 +1,15 @@ +apiVersion: workflowcontract.chainloop.dev/v1 +kind: Policy +metadata: + name: workflow +spec: + embedded: | + package main + deny[msg] { + not is_workflow + msg := "incorrect workflow" + } + + is_workflow { + input.workflow.name == "policytest" + } diff --git a/internal/attestation/crafter/testdata/policies/policy_missing_rego.yaml b/internal/attestation/crafter/testdata/policies/policy_missing_rego.yaml new file mode 100644 index 000000000..898fa6315 --- /dev/null +++ b/internal/attestation/crafter/testdata/policies/policy_missing_rego.yaml @@ -0,0 +1,6 @@ +apiVersion: workflowcontract.chainloop.dev/v1 +kind: Policy +metadata: + name: workflow +spec: + path: idontexist.rego diff --git a/internal/attestation/crafter/testdata/policies/policy_rego.yaml b/internal/attestation/crafter/testdata/policies/policy_rego.yaml new file mode 100644 index 000000000..4c52a0c5b --- /dev/null +++ b/internal/attestation/crafter/testdata/policies/policy_rego.yaml @@ -0,0 +1,6 @@ +apiVersion: workflowcontract.chainloop.dev/v1 +kind: Policy +metadata: + name: workflow +spec: + path: testdata/policies/policy.rego diff --git a/internal/attestation/renderer/chainloop/chainloop.go b/internal/attestation/renderer/chainloop/chainloop.go index c8521e8bb..4688fb90e 100644 --- a/internal/attestation/renderer/chainloop/chainloop.go +++ b/internal/attestation/renderer/chainloop/chainloop.go @@ -20,7 +20,6 @@ import ( "fmt" "time" - v12 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" v1 "github.com/chainloop-dev/chainloop/internal/attestation/crafter/api/attestation/v1" "github.com/secure-systems-lab/go-securesystemslib/dsse" "google.golang.org/protobuf/encoding/protojson" @@ -73,18 +72,6 @@ type ProvenancePredicateCommon struct { RunnerURL string `json:"runnerURL,omitempty"` // Custom annotations Annotations map[string]string `json:"annotations,omitempty"` - // Applied policies - Policies []PolicyPredicate `json:"policies,omitempty"` -} - -// PolicyPredicate represents a policy that has been run against an attestation -type PolicyPredicate struct { - Name string `json:"name"` - Stage string `json:"stage,omitempty"` - // Base64 body of the policy script - Body string `json:"body"` - // optional parameters set as policy inputs - Arguments []v12.PolicyAttachment_PolicyArgument `json:"arguments,omitempty"` } type Metadata struct { @@ -177,18 +164,18 @@ func ExtractPredicate(envelope *dsse.Envelope) (NormalizablePredicate, error) { // 2 - Extract the Chainloop predicate from the in-toto statement switch statement.PredicateType { case PredicateTypeV02: - var predicate *ProvenancePredicateV02 + var predicate ProvenancePredicateV02 if err = extractPredicate(statement, &predicate); err != nil { return nil, fmt.Errorf("extracting predicate: %w", err) } - return predicate, nil + return &predicate, nil default: return nil, fmt.Errorf("unsupported predicate type: %s", statement.PredicateType) } } -func extractPredicate(statement *intoto.Statement, v any) error { +func extractPredicate(statement *intoto.Statement, v *ProvenancePredicateV02) error { jsonPredicate, err := protojson.Marshal(statement.Predicate) if err != nil { return fmt.Errorf("un-marshaling predicate: %w", err) diff --git a/internal/attestation/renderer/chainloop/v02.go b/internal/attestation/renderer/chainloop/v02.go index 73dc94eb2..a0a66defc 100644 --- a/internal/attestation/renderer/chainloop/v02.go +++ b/internal/attestation/renderer/chainloop/v02.go @@ -23,13 +23,12 @@ import ( "strings" "time" + schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" v1 "github.com/chainloop-dev/chainloop/internal/attestation/crafter/api/attestation/v1" crv1 "github.com/google/go-containerregistry/pkg/v1" + intoto "github.com/in-toto/attestation/go/v1" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/structpb" - - schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" - intoto "github.com/in-toto/attestation/go/v1" ) // Replace custom material type with https://github.com/in-toto/attestation/blob/main/spec/v1.0/resource_descriptor.md @@ -38,6 +37,8 @@ const PredicateTypeV02 = "chainloop.dev/attestation/v0.2" type ProvenancePredicateV02 struct { *ProvenancePredicateCommon Materials []*intoto.ResourceDescriptor `json:"materials,omitempty"` + // Map materials and policies + PolicyEvaluations map[string][]*v1.PolicyEvaluation `json:"policy_evaluations,omitempty"` } type RendererV02 struct { @@ -147,9 +148,12 @@ func (r *RendererV02) predicate() (*structpb.Struct, error) { return nil, fmt.Errorf("error normalizing materials: %w", err) } + policies := policyEvaluationsFromMaterials(r.att) + p := ProvenancePredicateV02{ ProvenancePredicateCommon: predicateCommon(r.builder, r.att), Materials: normalizedMaterials, + PolicyEvaluations: policies, } // transform to structpb.Struct in a two steps process @@ -168,6 +172,16 @@ func (r *RendererV02) predicate() (*structpb.Struct, error) { return predicate, nil } +// collect all policy evaluations grouped by material +func policyEvaluationsFromMaterials(att *v1.Attestation) map[string][]*v1.PolicyEvaluation { + result := map[string][]*v1.PolicyEvaluation{} + for _, p := range att.GetPolicyEvaluations() { + result[p.MaterialName] = append(result[p.MaterialName], p) + } + + return result +} + func outputMaterials(att *v1.Attestation, onlyOutput bool) ([]*intoto.ResourceDescriptor, error) { // Sort material keys to stabilize output keys := make([]string, 0, len(att.GetMaterials())) diff --git a/internal/attestation/renderer/renderer.go b/internal/attestation/renderer/renderer.go index d9f1f253e..1a5413f36 100644 --- a/internal/attestation/renderer/renderer.go +++ b/internal/attestation/renderer/renderer.go @@ -17,6 +17,7 @@ package renderer import ( "bytes" + "context" "encoding/base64" "encoding/json" "encoding/pem" @@ -24,9 +25,11 @@ import ( "fmt" "os" + schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" v1 "github.com/chainloop-dev/chainloop/internal/attestation/crafter/api/attestation/v1" "github.com/chainloop-dev/chainloop/internal/attestation/renderer/chainloop" chainloopsigner "github.com/chainloop-dev/chainloop/internal/attestation/signer/chainloop" + "github.com/chainloop-dev/chainloop/pkg/policies" intoto "github.com/in-toto/attestation/go/v1" "github.com/rs/zerolog" "github.com/secure-systems-lab/go-securesystemslib/dsse" @@ -36,11 +39,13 @@ import ( sigstoresigner "github.com/sigstore/sigstore/pkg/signature" sigdsee "github.com/sigstore/sigstore/pkg/signature/dsse" "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/types/known/structpb" ) type AttestationRenderer struct { logger zerolog.Logger att *v1.Attestation + schema *schemaapi.CraftingSchema renderer r signer sigstoresigner.Signer dsseSigner sigstoresigner.Signer @@ -53,6 +58,8 @@ type r interface { type Opt func(*AttestationRenderer) +const AttPolicyEvaluation = "CHAINLOOP.ATTESTATION" + func WithLogger(logger zerolog.Logger) Opt { return func(ar *AttestationRenderer) { ar.logger = logger @@ -73,6 +80,7 @@ func NewAttestationRenderer(state *v1.CraftingState, builderVersion, builderDige r := &AttestationRenderer{ logger: zerolog.Nop(), att: state.GetAttestation(), + schema: state.GetInputSchema(), dsseSigner: sigdsee.WrapSigner(signer, "application/vnd.in-toto+json"), signer: signer, renderer: chainloop.NewChainloopRendererV02(state.GetAttestation(), builderVersion, builderDigest), @@ -87,7 +95,7 @@ func NewAttestationRenderer(state *v1.CraftingState, builderVersion, builderDige // Attestation (dsee envelope) -> { message: { Statement(in-toto): [subject, predicate] }, signature: "sig" }. // NOTE: It currently only supports cosign key based signing. -func (ab *AttestationRenderer) Render() (*dsse.Envelope, error) { +func (ab *AttestationRenderer) Render(ctx context.Context) (*dsse.Envelope, error) { ab.logger.Debug().Msg("generating in-toto statement") statement, err := ab.renderer.Statement() @@ -99,6 +107,18 @@ func (ab *AttestationRenderer) Render() (*dsse.Envelope, error) { return nil, fmt.Errorf("validating intoto statement: %w", err) } + // validate attestation-level policies + pv := policies.NewPolicyVerifier(ab.schema, &ab.logger) + policyResults, err := pv.VerifyStatement(ctx, statement) + if err != nil { + return nil, fmt.Errorf("applying policies to statement: %w", err) + } + + // insert attestation level policy results into statement + if err = addPolicyResults(statement, policyResults); err != nil { + return nil, fmt.Errorf("adding policy results to statement: %w", err) + } + rawStatement, err := protojson.Marshal(statement) if err != nil { return nil, err @@ -134,6 +154,48 @@ func (ab *AttestationRenderer) Render() (*dsse.Envelope, error) { return &dsseEnvelope, nil } +// addPolicyResults adds policy evaluation results to the statement. It does it by deserializing the predicate from a structpb.Struct, +// filling PolicyEvaluations, and serializing it again to a structpb.Struct object, using JSON as an intermediate representation. +// Note that this is needed because intoto predicates are generic structpb.Struct +func addPolicyResults(statement *intoto.Statement, policyResults []*v1.PolicyEvaluation) error { + predicate := statement.Predicate + // marshall to json + jsonPredicate, err := protojson.Marshal(predicate) + if err != nil { + return fmt.Errorf("marshalling predicate: %w", err) + } + + // unmarshall to our typed predicate object + var p chainloop.ProvenancePredicateV02 + err = json.Unmarshal(jsonPredicate, &p) + if err != nil { + return fmt.Errorf("unmarshalling predicate: %w", err) + } + + // insert policy evaluations + if p.PolicyEvaluations == nil { + p.PolicyEvaluations = make(map[string][]*v1.PolicyEvaluation) + } + p.PolicyEvaluations[AttPolicyEvaluation] = policyResults + + // marshall back to JSON + jsonPredicate, err = json.Marshal(p) + if err != nil { + return fmt.Errorf("marshalling predicate: %w", err) + } + + // finally unmarshal from JSON to structpb.Struct. + var finalPredicate structpb.Struct + err = protojson.Unmarshal(jsonPredicate, &finalPredicate) + if err != nil { + return fmt.Errorf("unmarshalling predicate: %w", err) + } + + statement.Predicate = &finalPredicate + + return nil +} + func (ab *AttestationRenderer) envelopeToBundle(dsseEnvelope dsse.Envelope) (*protobundle.Bundle, error) { // DSSE Envelope is already base64 encoded, we need to decode to prevent it from being encoded twice payload, err := base64.StdEncoding.DecodeString(dsseEnvelope.Payload) diff --git a/internal/attestation/renderer/renderer_test.go b/internal/attestation/renderer/renderer_test.go index 549d6ba1c..040da425d 100644 --- a/internal/attestation/renderer/renderer_test.go +++ b/internal/attestation/renderer/renderer_test.go @@ -68,7 +68,7 @@ func (s *rendererSuite) TestRender() { renderer, err := NewAttestationRenderer(s.cs, "", "", s.sv) s.Require().NoError(err) - envelope, err := renderer.Render() + envelope, err := renderer.Render(context.TODO()) s.NoError(err) _, err = s.dsseVerifier.Verify(context.TODO(), envelope) @@ -81,7 +81,7 @@ func (s *rendererSuite) TestRender() { renderer, err := NewAttestationRenderer(s.cs, "", "", doubleWrapper) s.Require().NoError(err) - envelope, err := renderer.Render() + envelope, err := renderer.Render(context.TODO()) s.NoError(err) _, err = s.dsseVerifier.Verify(context.TODO(), envelope) diff --git a/pkg/policies/policies.go b/pkg/policies/policies.go index 50aa829a3..acea8ba2c 100644 --- a/pkg/policies/policies.go +++ b/pkg/policies/policies.go @@ -16,61 +16,112 @@ package policies import ( - "bufio" - "bytes" "context" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "os" "path/filepath" "github.com/bufbuild/protovalidate-go" + intoto "github.com/in-toto/attestation/go/v1" + "github.com/rs/zerolog" + "github.com/secure-systems-lab/go-securesystemslib/dsse" "github.com/sigstore/cosign/v2/pkg/blob" "google.golang.org/protobuf/encoding/protojson" v1 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" - "github.com/chainloop-dev/chainloop/internal/attestation/crafter" v12 "github.com/chainloop-dev/chainloop/internal/attestation/crafter/api/attestation/v1" - "github.com/chainloop-dev/chainloop/internal/casclient" + "github.com/chainloop-dev/chainloop/internal/attestation/crafter/materials" "github.com/chainloop-dev/chainloop/pkg/policies/engine" "github.com/chainloop-dev/chainloop/pkg/policies/engine/rego" ) type PolicyVerifier struct { - state *v12.CraftingState - cas casclient.Downloader + schema *v1.CraftingSchema + logger *zerolog.Logger } -func NewPolicyVerifier(state *v12.CraftingState, client casclient.Downloader) *PolicyVerifier { - // only Rego engine is currently supported - return &PolicyVerifier{state: state, cas: client} +func NewPolicyVerifier(schema *v1.CraftingSchema, logger *zerolog.Logger) *PolicyVerifier { + return &PolicyVerifier{schema: schema, logger: logger} } -// Verify verifies that the statement is compliant with the policies present in the schema -func (pv *PolicyVerifier) Verify(ctx context.Context) ([]*engine.PolicyViolation, error) { - violations := make([]*engine.PolicyViolation, 0) - policies := pv.state.GetInputSchema().GetPolicies() - for _, policyAtt := range policies { - if policyAtt.Disabled { - // policy is disabled - // TODO: WARN. - continue +// VerifyMaterial applies all required policies to a material +func (pv *PolicyVerifier) VerifyMaterial(ctx context.Context, material *v12.Attestation_Material, artifactPath string) ([]*v12.PolicyEvaluation, error) { + result := make([]*v12.PolicyEvaluation, 0) + + policies, err := pv.requiredPoliciesForMaterial(material) + if err != nil { + return nil, fmt.Errorf("error getting required policies for material: %w", err) + } + + for _, policy := range policies { + // 1. load the policy spec + spec, err := LoadPolicySpec(policy) + if err != nil { + return nil, fmt.Errorf("failed to load policy spec: %w", err) + } + + // load the policy script (rego) + script, err := LoadPolicyScriptFromSpec(spec) + if err != nil { + return nil, fmt.Errorf("failed to load policy content: %w", err) + } + + // Load material content + subject, err := getMaterialContent(material, artifactPath) + if err != nil { + return nil, fmt.Errorf("failed to load material content: %w", err) } + pv.logger.Info().Msgf("evaluating policy '%s' against material '%s'", spec.Metadata.Name, material.GetArtifact().GetId()) + + // verify the policy + ng := getPolicyEngine(spec) + violations, err := ng.Verify(ctx, script, subject) + if err != nil { + return nil, fmt.Errorf("failed to verify policy: %w", err) + } + + result = append(result, &v12.PolicyEvaluation{ + Name: spec.GetMetadata().GetName(), + MaterialName: material.GetArtifact().GetId(), + Body: base64.StdEncoding.EncodeToString(script.Source), + Violations: engineViolationsToAPIViolations(violations), + }) + } + + return result, 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) + policies := pv.schema.GetPolicies().GetAttestation() + for _, policyAtt := range policies { // 1. load the policy spec - spec, err := pv.loadSpec(policyAtt) + spec, err := LoadPolicySpec(policyAtt) if err != nil { return nil, fmt.Errorf("failed to load policy spec: %w", err) } + // it's expected statements can only be validated by policy of type ATTESTATION + if spec.GetSpec().GetType() != v1.CraftingSchema_Material_ATTESTATION { + continue + } + // 2. load the policy script (rego) - script, err := pv.loadPolicyScriptFromSpec(spec) + script, err := LoadPolicyScriptFromSpec(spec) if err != nil { return nil, fmt.Errorf("failed to load policy content: %w", err) } - // 3. load the affected material (or the whole attestation) - material, err := pv.loadSubject(ctx, policyAtt, spec, pv.state) + pv.logger.Info().Msgf("evaluating policy '%s' on attestation", spec.Metadata.Name) + + material, err := protojson.Marshal(statement) if err != nil { - return nil, fmt.Errorf("failed to load policy subject: %w", err) + return nil, fmt.Errorf("failed to load material content: %w", err) } // 4. verify the policy @@ -79,114 +130,101 @@ func (pv *PolicyVerifier) Verify(ctx context.Context) ([]*engine.PolicyViolation if err != nil { return nil, fmt.Errorf("failed to verify policy: %w", err) } - violations = append(violations, res...) // 5. Store result in the attestation itself (for the renderer to include them in the predicate) - pv.state.Attestation.Policies = append(pv.state.Attestation.Policies, &v12.Policy{ + result = append(result, &v12.PolicyEvaluation{ Name: spec.Metadata.Name, - Attachment: policyAtt, - Body: string(script.Source), + Body: base64.StdEncoding.EncodeToString(script.Source), Violations: policyViolationsToAttestationViolations(res), }) } - return violations, nil + return result, nil } -func (pv *PolicyVerifier) loadSpec(attachment *v1.PolicyAttachment) (*v1.Policy, error) { - // look for the referenced policy spec (note: loading by `name` is not supported yet) - reference := attachment.GetRef() - // this method understands env, http and https schemes, and defaults to file system. - rawData, err := blob.LoadFileOrURL(reference) - if err != nil { - return nil, fmt.Errorf("loading policy spec: %w", err) - } - jsonContent, err := crafter.LoadJSONBytes(rawData, filepath.Ext(reference)) - if err != nil { - return nil, fmt.Errorf("loading policy spec: %w", err) - } - var policy v1.Policy - if err := protojson.Unmarshal(jsonContent, &policy); err != nil { - return nil, fmt.Errorf("unmarshalling policy spec: %w", err) - } - // Validate just in case - validator, err := protovalidate.New() - if err != nil { - return nil, fmt.Errorf("validating policy spec: %w", err) - } - err = validator.Validate(&policy) - if err != nil { - return nil, fmt.Errorf("validating policy spec: %w", err) +func engineViolationsToAPIViolations(input []*engine.PolicyViolation) []*v12.PolicyEvaluation_Violation { + res := make([]*v12.PolicyEvaluation_Violation, 0) + for _, v := range input { + res = append(res, &v12.PolicyEvaluation_Violation{ + Subject: v.Subject, + Message: v.Violation, + }) } - return &policy, nil + return res } -// loads a policy referenced from the spec -func (pv *PolicyVerifier) loadPolicyScriptFromSpec(spec *v1.Policy) (*engine.Policy, error) { - var content []byte +func getMaterialContent(material *v12.Attestation_Material, artifactPath string) ([]byte, error) { + var rawMaterial []byte var err error - switch source := spec.GetSpec().GetSource().(type) { - case *v1.PolicySpec_Embedded: - content = []byte(source.Embedded) - case *v1.PolicySpec_Path: - content, err = blob.LoadFileOrURL(source.Path) + // nolint: gocritic + if material.InlineCas { + rawMaterial = material.GetArtifact().GetContent() + } else if artifactPath == "" { + return nil, errors.New("artifact path required") + } else { + // read content from local filesystem + rawMaterial, err = os.ReadFile(artifactPath) if err != nil { - return nil, fmt.Errorf("loading policy content: %w", err) + return nil, fmt.Errorf("failed to read material content: %w", err) } - default: - return nil, fmt.Errorf("policy spec is empty") } + // special case for ATTESTATION materials, the statement needs to be extracted from the dsse wrapper. + if material.MaterialType == v1.CraftingSchema_Material_ATTESTATION { + var envelope dsse.Envelope + if err := json.Unmarshal(rawMaterial, &envelope); err != nil { + return nil, fmt.Errorf("failed to unmarshal attestation material: %w", err) + } - return &engine.Policy{ - Name: spec.GetMetadata().GetName(), - Source: content, - }, nil + rawMaterial, err = envelope.DecodeB64Payload() + if err != nil { + return nil, fmt.Errorf("failed to decode attestation material: %w", err) + } + } + + return rawMaterial, nil } -// load the subject of the policy. -func (pv *PolicyVerifier) loadSubject(ctx context.Context, attachment *v1.PolicyAttachment, spec *v1.Policy, state *v12.CraftingState) ([]byte, error) { - // Load the affected material or attestation, and checks if the expected name and type match - name := attachment.GetSelector().GetName() - // if name selector is not set, the subject will become the full crafting state - if name == "" { - return protojson.Marshal(state.GetAttestation()) - } +// returns the list of polices to be applied to a material, following these rules: +// 1. if policy spec has a type, return it only if material has the same type +// 2. if attachment has a name filter, return the policy only if the material has the same name +// 3. if policy spec doesn't have a type, a name filter is mandatory (otherwise there is no way to know if material has to be applied) +func (pv *PolicyVerifier) requiredPoliciesForMaterial(material *v12.Attestation_Material) ([]*v1.PolicyAttachment, error) { + result := make([]*v1.PolicyAttachment, 0) + policies := pv.schema.GetPolicies().GetMaterials() - // if name is set, we want a specific material - for k, m := range state.GetAttestation().GetMaterials() { - if k == name { - if spec.GetSpec().GetKind() != v1.CraftingSchema_Material_MATERIAL_TYPE_UNSPECIFIED && spec.GetSpec().GetKind() != m.GetMaterialType() { - // If policy wasn't meant to be evaluated against this type of material, raise an error - return nil, fmt.Errorf("invalid material type: %s, policy expected: %s", m.GetMaterialType(), spec.GetSpec().GetKind()) - } - return pv.getMaterialPayload(ctx, m) + for _, policyAtt := range policies { + // load the policy spec + spec, err := LoadPolicySpec(policyAtt) + if err != nil { + return nil, fmt.Errorf("failed to load policy spec: %w", err) } - } - return nil, fmt.Errorf("no material found with name %s", name) -} + specType := spec.GetSpec().GetType() + materialType := material.GetMaterialType() + filteredName := policyAtt.GetSelector().GetName() -// Gets the material payload from the CAS -func (pv *PolicyVerifier) getMaterialPayload(ctx context.Context, m *v12.Attestation_Material) ([]byte, error) { - if m.InlineCas { - return m.GetArtifact().GetContent(), nil - } + // if spec has a type, and it's different to the material type, skip + if specType != v1.CraftingSchema_Material_MATERIAL_TYPE_UNSPECIFIED && specType != materialType { + // types don't match, continue + continue + } - // Use the CAS to look for the material - var b bytes.Buffer - w := bufio.NewWriter(&b) - err := pv.cas.Download(ctx, w, m.GetArtifact().GetDigest()) - if err != nil { - return nil, fmt.Errorf("failed to download artifact: %w", err) - } - err = w.Flush() - if err != nil { - return nil, fmt.Errorf("failed to download artifact: %w", err) + if filteredName != "" && filteredName != material.GetArtifact().GetId() { + // a filer exists and doesn't match + continue + } + + // no type nor name to match, we can't guess anything + if specType == v1.CraftingSchema_Material_MATERIAL_TYPE_UNSPECIFIED && filteredName == "" { + continue + } + + result = append(result, policyAtt) } - return b.Bytes(), nil + return result, nil } // getPolicyEngine returns a PolicyEngine implementation to evaluate a given policy. @@ -195,12 +233,86 @@ func getPolicyEngine(_ *v1.Policy) engine.PolicyEngine { return new(rego.Rego) } -func policyViolationsToAttestationViolations(violations []*engine.PolicyViolation) (pvs []*v12.Policy_Violation) { +func policyViolationsToAttestationViolations(violations []*engine.PolicyViolation) (pvs []*v12.PolicyEvaluation_Violation) { for _, violation := range violations { - pvs = append(pvs, &v12.Policy_Violation{ + pvs = append(pvs, &v12.PolicyEvaluation_Violation{ Subject: violation.Subject, Message: violation.Violation, }) } return } + +// LoadPolicySpec loads and validates a policy spec from a contract +func LoadPolicySpec(attachment *v1.PolicyAttachment) (*v1.Policy, error) { + reference := attachment.GetRef() + embedded := attachment.GetEmbedded() + + if embedded == nil && reference == "" { + return nil, errors.New("policy must be referenced or embedded in the attachment") + } + + var spec v1.Policy + if embedded != nil { + spec = *attachment.GetEmbedded() + } else { + // look for the referenced policy spec (note: loading by `name` is not supported yet) + // this method understands env, http and https schemes, and defaults to file system. + rawData, err := blob.LoadFileOrURL(reference) + if err != nil { + return nil, fmt.Errorf("loading policy spec: %w", err) + } + + jsonContent, err := materials.LoadJSONBytes(rawData, filepath.Ext(reference)) + if err != nil { + return nil, fmt.Errorf("loading policy spec: %w", err) + } + + if err := protojson.Unmarshal(jsonContent, &spec); err != nil { + return nil, fmt.Errorf("unmarshalling policy spec: %w", err) + } + } + + // Validate just in case + if err := validatePolicy(&spec); err != nil { + return nil, fmt.Errorf("invalid policy: %w", err) + } + + return &spec, nil +} + +func validatePolicy(policy *v1.Policy) error { + validator, err := protovalidate.New() + if err != nil { + return fmt.Errorf("validating policy spec: %w", err) + } + err = validator.Validate(policy) + if err != nil { + return fmt.Errorf("validating policy spec: %w", err) + } + + return nil +} + +// LoadPolicyScriptFromSpec loads a policy referenced from the spec +func LoadPolicyScriptFromSpec(spec *v1.Policy) (*engine.Policy, error) { + var content []byte + var err error + + switch source := spec.GetSpec().GetSource().(type) { + case *v1.PolicySpec_Embedded: + content = []byte(source.Embedded) + case *v1.PolicySpec_Path: + content, err = blob.LoadFileOrURL(source.Path) + if err != nil { + return nil, fmt.Errorf("loading policy content: %w", err) + } + default: + return nil, fmt.Errorf("policy spec is empty") + } + + return &engine.Policy{ + Name: spec.GetMetadata().GetName(), + Source: content, + }, nil +} diff --git a/pkg/policies/policies_test.go b/pkg/policies/policies_test.go index 4f9aad354..dc75d4464 100644 --- a/pkg/policies/policies_test.go +++ b/pkg/policies/policies_test.go @@ -17,424 +17,403 @@ package policies import ( "context" - "io" "io/fs" "os" "testing" - "github.com/stretchr/testify/mock" + intoto "github.com/in-toto/attestation/go/v1" + "github.com/rs/zerolog" "github.com/stretchr/testify/suite" - "golang.org/x/exp/slices" + "google.golang.org/protobuf/encoding/protojson" v12 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" v1 "github.com/chainloop-dev/chainloop/internal/attestation/crafter/api/attestation/v1" - "github.com/chainloop-dev/chainloop/internal/casclient/mocks" ) func (s *testSuite) TestVerifyAttestations() { cases := []struct { name string - state *v1.CraftingState + schema *v12.CraftingSchema + statement string + npolicies int violations int wantErr error }{ { name: "happy path, test attestation properties", - state: &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ + schema: &v12.CraftingSchema{ + Policies: &v12.Policies{ + Attestation: []*v12.PolicyAttachment{ {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow.yaml"}}, }, }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - RunnerType: v12.CraftingSchema_Runner_GITHUB_ACTION, - }, }, + statement: "testdata/statement.json", + npolicies: 1, }, { name: "wrong runner", + npolicies: 1, violations: 1, - state: &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ + statement: "testdata/statement_gitlab.json", + schema: &v12.CraftingSchema{ + Policies: &v12.Policies{ + Attestation: []*v12.PolicyAttachment{ {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow.yaml"}}, }, }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - RunnerType: v12.CraftingSchema_Runner_DAGGER_PIPELINE, - }, }, }, { name: "missing runner", + npolicies: 1, violations: 1, - state: &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ + schema: &v12.CraftingSchema{ + Policies: &v12.Policies{ + Attestation: []*v12.PolicyAttachment{ {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow.yaml"}}, }, }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - }, }, + statement: "testdata/statement_missing_runner.json", }, { name: "wrong policy", wantErr: &fs.PathError{}, - state: &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ + schema: &v12.CraftingSchema{ + Policies: &v12.Policies{ + Attestation: []*v12.PolicyAttachment{ {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/wrong_policy.yaml"}}, }, }, }, + statement: "testdata/statement.json", }, { name: "missing rego policy", wantErr: &fs.PathError{}, - state: &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ + schema: &v12.CraftingSchema{ + Policies: &v12.Policies{ + Attestation: []*v12.PolicyAttachment{ {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/missing_rego.yaml"}}, }, }, }, + statement: "testdata/statement.json", }, { name: "embedded rego policy", - state: &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ + schema: &v12.CraftingSchema{ + Policies: &v12.Policies{ + Attestation: []*v12.PolicyAttachment{ {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow_embedded.yaml"}}, }, }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - }, }, + statement: "testdata/statement.json", + npolicies: 1, }, { name: "embedded rego policy violations", - state: &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ + schema: &v12.CraftingSchema{ + Policies: &v12.Policies{ + Attestation: []*v12.PolicyAttachment{ {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow_embedded.yaml"}}, }, }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "wrongname", + }, + npolicies: 1, + violations: 1, + statement: "testdata/statement_missing_runner.json", + }, + { + name: "multiple policies", + schema: &v12.CraftingSchema{ + Policies: &v12.Policies{ + Attestation: []*v12.PolicyAttachment{ + {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow_embedded.yaml"}}, + {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/materials.yaml"}}, }, }, }, + npolicies: 2, violations: 1, + statement: "testdata/statement.json", }, } for _, tc := range cases { s.Run(tc.name, func() { - verifier := NewPolicyVerifier(tc.state, nil) - res, err := verifier.Verify(context.TODO()) + verifier := NewPolicyVerifier(tc.schema, &s.logger) + stContent, err := os.ReadFile(tc.statement) + s.Require().NoError(err) + var statement intoto.Statement + err = protojson.Unmarshal(stContent, &statement) + s.Require().NoError(err) + + res, err := verifier.VerifyStatement(context.TODO(), &statement) if tc.wantErr != nil { // #nosec G601 s.ErrorAs(err, &tc.wantErr) return } s.Require().NoError(err) - if tc.violations > 0 { - s.Len(res, tc.violations) + s.Len(res, tc.npolicies) + if tc.npolicies > 0 { + violations := 0 + for _, pol := range res { + violations += len(pol.Violations) + } + s.Equal(tc.violations, violations) } }) } } -func (s *testSuite) TestAttestationResult() { - s.Run("successful attestation", func() { - state := &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ - {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow.yaml"}}, - }, - }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - RunnerType: v12.CraftingSchema_Runner_GITHUB_ACTION, - }, - } - - verifier := NewPolicyVerifier(state, nil) - res, err := verifier.Verify(context.TODO()) - s.Require().NoError(err) - s.Len(res, 0) - - att := state.GetAttestation() - s.Len(att.Policies, 1) - - p := att.Policies[0] - s.Len(p.Violations, 0) - s.Equal("testdata/workflow.yaml", p.Attachment.GetRef()) - s.Equal("workflow", p.Name) - s.Contains(p.Body, "package main") - }) - - s.Run("failed attestation", func() { - state := &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ - {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow.yaml"}}, - }, - }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - RunnerType: v12.CraftingSchema_Runner_DAGGER_PIPELINE, - }, - } - - verifier := NewPolicyVerifier(state, nil) - res, err := verifier.Verify(context.TODO()) - s.Require().NoError(err) - s.Len(res, 1) - - att := state.GetAttestation() - s.Len(att.Policies, 1) - - p := att.Policies[0] - s.Len(p.Violations, 1) - s.Contains(p.Body, "package main") - v := p.Violations[0] - s.Equal(p.Name, v.Subject) - s.Equal("incorrect runner", v.Message) - }) - - s.Run("multiple successful policies", func() { - state := &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ - {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow.yaml"}}, - {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/materials.yaml"}}, - }, - }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - RunnerType: v12.CraftingSchema_Runner_GITHUB_ACTION, - Materials: map[string]*v1.Attestation_Material{ - "vex": { - MaterialType: v12.CraftingSchema_Material_OPENVEX, +func (s *testSuite) TestMaterialSelectionCriteria() { + attNoFilterPolicyTyped := &v12.PolicyAttachment{ + Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/sbom_syft.yaml"}, + } + attFilteredPolicyTyped := &v12.PolicyAttachment{ + Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/sbom_syft.yaml"}, + Selector: &v12.PolicyAttachment_MaterialSelector{Name: "sbom"}, + } + attFilteredPolicyNotTyped := &v12.PolicyAttachment{ + Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/sbom_syft_not_typed.yaml"}, + Selector: &v12.PolicyAttachment_MaterialSelector{Name: "custom-material"}, + } + testcases := []struct { + name string + policies []*v12.PolicyAttachment + material *v1.Attestation_Material + wantErr bool + result int + }{ + { + name: "attachment with no filter, policy with type, matched material", + policies: []*v12.PolicyAttachment{attNoFilterPolicyTyped}, + material: &v1.Attestation_Material{MaterialType: v12.CraftingSchema_Material_SBOM_SPDX_JSON}, + result: 1, + }, + { + name: "attachment with no filter, policy with type, non matched material", + policies: []*v12.PolicyAttachment{attNoFilterPolicyTyped}, + material: &v1.Attestation_Material{MaterialType: v12.CraftingSchema_Material_SBOM_CYCLONEDX_JSON}, + result: 0, + }, + { + name: "attachment with filter, policy with type, matched material", + policies: []*v12.PolicyAttachment{attFilteredPolicyTyped}, + material: &v1.Attestation_Material{ + M: &v1.Attestation_Material_Artifact_{ + Artifact: &v1.Attestation_Material_Artifact{ + Id: "sbom", }, }, - }, - } - - verifier := NewPolicyVerifier(state, nil) - res, err := verifier.Verify(context.TODO()) - s.Require().NoError(err) - s.Len(res, 0) - att := state.GetAttestation() - s.Len(att.Policies, 2) - s.Len(att.Policies[0].Violations, 0) - s.Len(att.Policies[1].Violations, 0) - }) - - s.Run("partial success", func() { - state := &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Policies: []*v12.PolicyAttachment{ - {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/workflow.yaml"}}, - {Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/materials.yaml"}}, + MaterialType: v12.CraftingSchema_Material_SBOM_SPDX_JSON}, + result: 1, + }, + { + name: "attachment with filter, policy with type, unmatched material", + policies: []*v12.PolicyAttachment{attFilteredPolicyTyped}, + material: &v1.Attestation_Material{ + M: &v1.Attestation_Material_Artifact_{ + Artifact: &v1.Attestation_Material_Artifact{ + Id: "not-the-sbom-you-expect", + }, }, - }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", + MaterialType: v12.CraftingSchema_Material_SBOM_SPDX_JSON}, + result: 0, + }, + { + name: "attachment with no filter, policy without type, matched material", + policies: []*v12.PolicyAttachment{attFilteredPolicyNotTyped}, + material: &v1.Attestation_Material{ + M: &v1.Attestation_Material_Artifact_{ + Artifact: &v1.Attestation_Material_Artifact{ + Id: "custom-material", + }, }, - RunnerType: v12.CraftingSchema_Runner_DAGGER_PIPELINE, - Materials: map[string]*v1.Attestation_Material{ - "vex": { - MaterialType: v12.CraftingSchema_Material_OPENVEX, + MaterialType: v12.CraftingSchema_Material_ATTESTATION}, + result: 1, + }, + { + name: "attachment with no filter, policy without type, unmatched material", + policies: []*v12.PolicyAttachment{attFilteredPolicyNotTyped}, + material: &v1.Attestation_Material{ + M: &v1.Attestation_Material_Artifact_{ + Artifact: &v1.Attestation_Material_Artifact{ + Id: "not-the-material-you-expect", }, }, - }, - } - - verifier := NewPolicyVerifier(state, nil) - res, err := verifier.Verify(context.TODO()) - s.Require().NoError(err) - s.Greater(len(res), 0) - att := state.GetAttestation() - s.Len(att.Policies, 2) - - // Check that only 1 policy failed - index := slices.IndexFunc(att.Policies, func(p *v1.Policy) bool { - return p.Name == "workflow" - }) - p := att.Policies[index] - s.Len(p.Violations, 1) + MaterialType: v12.CraftingSchema_Material_ATTESTATION}, + result: 0, + }, + } - index = slices.IndexFunc(att.Policies, func(p *v1.Policy) bool { - return p.Name == "materials" + for _, tc := range testcases { + s.Run(tc.name, func() { + schema := &v12.CraftingSchema{ + Policies: &v12.Policies{ + Materials: tc.policies, + }, + } + pv := NewPolicyVerifier(schema, &s.logger) + atts, err := pv.requiredPoliciesForMaterial(tc.material) + s.Require().NoError(err) + s.Require().Len(atts, tc.result) }) - p = att.Policies[index] - s.Len(p.Violations, 0) - }) + } } -func (s *testSuite) TestInlineMaterial() { +func (s *testSuite) TestValidInlineMaterial() { content, err := os.ReadFile("testdata/sbom-spdx.json") s.Require().NoError(err) - state := &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Materials: []*v12.CraftingSchema_Material{ - { - Name: "sbom", - Type: v12.CraftingSchema_Material_SBOM_SPDX_JSON, - }, - }, - Policies: []*v12.PolicyAttachment{ - { - Selector: &v12.PolicyAttachment_MaterialSelector{Name: "sbom"}, - Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/sbom_syft.yaml"}, - }, + schema := &v12.CraftingSchema{ + Materials: []*v12.CraftingSchema_Material{ + { + Name: "sbom", + Type: v12.CraftingSchema_Material_SBOM_SPDX_JSON, }, }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - Materials: map[string]*v1.Attestation_Material{ - "sbom": { - MaterialType: v12.CraftingSchema_Material_SBOM_SPDX_JSON, - M: &v1.Attestation_Material_Artifact_{Artifact: &v1.Attestation_Material_Artifact{ - Content: content, - }, - }, - InlineCas: true, + Policies: &v12.Policies{ + Materials: []*v12.PolicyAttachment{ + { + Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/sbom_syft.yaml"}, }, }, + Attestation: nil, }, } - verifier := NewPolicyVerifier(state, nil) - res, err := verifier.Verify(context.TODO()) - s.Require().NoError(err) - s.Len(res, 0) + material := &v1.Attestation_Material{ + M: &v1.Attestation_Material_Artifact_{Artifact: &v1.Attestation_Material_Artifact{ + Content: content, + }}, + MaterialType: v12.CraftingSchema_Material_SBOM_SPDX_JSON, + InlineCas: true, + } - att := state.GetAttestation() - s.Len(att.Policies, 1) - s.Len(att.Policies[0].Violations, 0) -} + verifier := NewPolicyVerifier(schema, &s.logger) -func (s *testSuite) TestDownloadedMaterial() { - content, err := os.ReadFile("testdata/sbom-spdx.json") + res, err := verifier.VerifyMaterial(context.TODO(), material, "") s.Require().NoError(err) + s.Len(res, 1) + s.Equal("made-with-syft", res[0].Name) + s.Len(res[0].Violations, 0) +} - d := mocks.NewDownloader(s.T()) - d.On("Download", context.TODO(), mock.AnythingOfType("*bufio.Writer"), "foobar").Run(func(args mock.Arguments) { - w := args.Get(1).(io.Writer) - _, err := w.Write(content) - s.Require().NoError(err) - }).Return(nil) - - state := &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Materials: []*v12.CraftingSchema_Material{ - { - Name: "sbom", - Type: v12.CraftingSchema_Material_SBOM_SPDX_JSON, - }, - }, - Policies: []*v12.PolicyAttachment{ - { - Selector: &v12.PolicyAttachment_MaterialSelector{Name: "sbom"}, - Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/sbom_syft.yaml"}, - }, +func (s *testSuite) TestInvalidInlineMaterial() { + schema := &v12.CraftingSchema{ + Materials: []*v12.CraftingSchema_Material{ + { + Name: "sbom", + Type: v12.CraftingSchema_Material_SBOM_SPDX_JSON, }, }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - Materials: map[string]*v1.Attestation_Material{ - "sbom": { - MaterialType: v12.CraftingSchema_Material_SBOM_SPDX_JSON, - M: &v1.Attestation_Material_Artifact_{Artifact: &v1.Attestation_Material_Artifact{ - Digest: "foobar", - }, - }, - UploadedToCas: true, + Policies: &v12.Policies{ + Materials: []*v12.PolicyAttachment{ + { + Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/sbom_syft.yaml"}, }, }, + Attestation: nil, }, } - verifier := NewPolicyVerifier(state, d) - res, err := verifier.Verify(context.TODO()) + material := &v1.Attestation_Material{ + M: &v1.Attestation_Material_Artifact_{Artifact: &v1.Attestation_Material_Artifact{ + Content: []byte(`{"this": { "is": "not", "a": "sbom"}}`), + }}, + MaterialType: v12.CraftingSchema_Material_SBOM_SPDX_JSON, + InlineCas: true, + } + + verifier := NewPolicyVerifier(schema, &s.logger) + + res, err := verifier.VerifyMaterial(context.TODO(), material, "") s.Require().NoError(err) - s.Len(res, 0) + s.Len(res, 1) + s.Equal("made-with-syft", res[0].Name) + s.Len(res[0].Violations, 1) + s.Equal("made-with-syft", res[0].Violations[0].Subject) + s.Equal("Not made with syft", res[0].Violations[0].Message) } -func (s *testSuite) TestInvalidDownloadedMaterial() { - d := mocks.NewDownloader(s.T()) - d.On("Download", context.TODO(), mock.AnythingOfType("*bufio.Writer"), "another").Run(func(args mock.Arguments) { - w := args.Get(1).(io.Writer) - _, err := w.Write([]byte(`{"this": { "is": "not", "a": "sbom"}}`)) - s.Require().NoError(err) - }).Return(nil) - - state := &v1.CraftingState{ - InputSchema: &v12.CraftingSchema{ - Materials: []*v12.CraftingSchema_Material{ - { - Name: "sbom", - Type: v12.CraftingSchema_Material_SBOM_SPDX_JSON, +func (s *testSuite) TestLoadPolicySpec() { + var cases = []struct { + name string + attachment *v12.PolicyAttachment + wantErr bool + expectedName string + }{ + { + name: "missing policy", + attachment: &v12.PolicyAttachment{}, + wantErr: true, + }, + { + name: "by ref", + attachment: &v12.PolicyAttachment{ + Policy: &v12.PolicyAttachment_Ref{ + Ref: "testdata/sbom_syft.yaml", }, }, - Policies: []*v12.PolicyAttachment{ - { - Selector: &v12.PolicyAttachment_MaterialSelector{Name: "sbom"}, - Policy: &v12.PolicyAttachment_Ref{Ref: "testdata/sbom_syft.yaml"}, + expectedName: "made-with-syft", + }, + { + name: "embedded invalid", + attachment: &v12.PolicyAttachment{ + Policy: &v12.PolicyAttachment_Embedded{ + Embedded: &v12.Policy{ + ApiVersion: "", + Kind: "", + Metadata: &v12.Metadata{Name: "my-policy"}, + Spec: nil, + }, }, }, + wantErr: true, }, - Attestation: &v1.Attestation{ - Workflow: &v1.WorkflowMetadata{ - Name: "policytest", - }, - Materials: map[string]*v1.Attestation_Material{ - "sbom": { - MaterialType: v12.CraftingSchema_Material_SBOM_SPDX_JSON, - M: &v1.Attestation_Material_Artifact_{Artifact: &v1.Attestation_Material_Artifact{ - Digest: "another", - }, + { + name: "embedded valid", + attachment: &v12.PolicyAttachment{ + Policy: &v12.PolicyAttachment_Embedded{ + Embedded: &v12.Policy{ + ApiVersion: "workflowcontract.chainloop.dev/v1", + Kind: "Policy", + Metadata: &v12.Metadata{Name: "my-policy"}, + Spec: &v12.PolicySpec{ + Source: &v12.PolicySpec_Path{Path: "file.rego"}, + Type: v12.CraftingSchema_Material_OPENVEX, + }, }, - UploadedToCas: true, }, }, + expectedName: "my-policy", }, } - verifier := NewPolicyVerifier(state, d) - res, err := verifier.Verify(context.TODO()) - s.Require().NoError(err) - s.Len(res, 1) + + for _, tc := range cases { + s.Run(tc.name, func() { + p, err := LoadPolicySpec(tc.attachment) + if tc.wantErr { + s.Error(err) + return + } + s.Require().NoError(err) + s.Equal(tc.expectedName, p.Metadata.Name) + }) + } } type testSuite struct { suite.Suite + + logger zerolog.Logger +} + +func (s *testSuite) SetupTest() { + s.logger = zerolog.Nop() } func TestPolicyVerifier(t *testing.T) { diff --git a/pkg/policies/testdata/materials.rego b/pkg/policies/testdata/materials.rego index a31b6d1c3..63bd77ba9 100644 --- a/pkg/policies/testdata/materials.rego +++ b/pkg/policies/testdata/materials.rego @@ -13,8 +13,8 @@ deny[msg] { # Collect all material types kinds contains kind { - some material in input.materials - kind := material.materialType + some material in input.predicate.materials + kind := material.annotations["chainloop.material.type"] } has_vex { diff --git a/pkg/policies/testdata/materials.yaml b/pkg/policies/testdata/materials.yaml index 15a851a8d..c7cbba94b 100644 --- a/pkg/policies/testdata/materials.yaml +++ b/pkg/policies/testdata/materials.yaml @@ -3,4 +3,5 @@ kind: Policy metadata: name: materials spec: + type: ATTESTATION path: testdata/materials.rego diff --git a/pkg/policies/testdata/missing_rego.yaml b/pkg/policies/testdata/missing_rego.yaml index 0f326aa1e..df8b6ba5c 100644 --- a/pkg/policies/testdata/missing_rego.yaml +++ b/pkg/policies/testdata/missing_rego.yaml @@ -3,4 +3,5 @@ kind: Policy metadata: name: missing-rego spec: + type: ATTESTATION path: this_is_a_missing.rego diff --git a/pkg/policies/testdata/sbom_syft.yaml b/pkg/policies/testdata/sbom_syft.yaml index 4fa4d9a1a..ef90f448b 100644 --- a/pkg/policies/testdata/sbom_syft.yaml +++ b/pkg/policies/testdata/sbom_syft.yaml @@ -3,4 +3,5 @@ kind: Policy metadata: name: made-with-syft spec: + type: SBOM_SPDX_JSON path: testdata/sbom_syft.rego diff --git a/pkg/policies/testdata/sbom_syft_not_typed.yaml b/pkg/policies/testdata/sbom_syft_not_typed.yaml new file mode 100644 index 000000000..4fa4d9a1a --- /dev/null +++ b/pkg/policies/testdata/sbom_syft_not_typed.yaml @@ -0,0 +1,6 @@ +apiVersion: workflowcontract.chainloop.dev/v1 +kind: Policy +metadata: + name: made-with-syft +spec: + path: testdata/sbom_syft.rego diff --git a/pkg/policies/testdata/statement.json b/pkg/policies/testdata/statement.json new file mode 100644 index 000000000..6103b25e0 --- /dev/null +++ b/pkg/policies/testdata/statement.json @@ -0,0 +1,247 @@ +{ + "_type": "https://in-toto.io/Statement/v1", + "subject": [ + { + "name": "chainloop.workflow.chainloop-vault-release", + "digest": { + "sha256": "9ae495a85891eb1130fefc17bc89940c9aa96acb8355c26a3e0d73a5097d41d4" + } + }, + { + "name": "git.head", + "digest": { + "sha1": "53f95f066b620172301e2a3879e7d593da05727e" + }, + "annotations": { + "author.email": "devel@chainloop.dev", + "author.name": "Developer", + "date": "2024-07-12T10:16:04Z", + "message": "chore(vulns): fix CVEs in base image (#1088)\n\nSigned-off-by: Jose I. Paris ", + "remotes": [ + { + "name": "origin", + "url": "https://github.com/chainloop-dev/chainloop" + } + ] + } + } + ], + "predicateType": "chainloop.dev/attestation/v0.2", + "predicate": { + "buildType": "chainloop.dev/workflowrun/v0.1", + "builder": { + "id": "chainloop.dev/cli/0.90.1@sha256:431a0765636854095f0c78d01b61eb5558abe7c8de1608aa93eef1530deee0b6" + }, + "env": { + "GITHUB_ACTOR": "jiparis", + "GITHUB_REF": "refs/tags/v0.93.7", + "GITHUB_REPOSITORY": "chainloop-dev/chainloop", + "GITHUB_REPOSITORY_OWNER": "chainloop-dev", + "GITHUB_RUN_ID": "9906853011", + "GITHUB_SHA": "53f95f066b620172301e2a3879e7d593da05727e", + "RUNNER_NAME": "GitHub Actions 193", + "RUNNER_OS": "Linux" + }, + "materials": [ + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782291120414953", + "chainloop.material.type": "SBOM_CYCLONEDX_JSON" + }, + "digest": { + "sha256": "bc449b71c4a47f2f69b514f27e1d61250ff0af0cc554a68d331b40042d90a3da" + }, + "name": "cas.cyclonedx.json" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782293352471920", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "972ca204670aee23ed070619333fb04410ed996bf3c063ff88d35de0702fd478" + }, + "name": "chainloop-cli-0.93.7-darwin-amd64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782295934163620", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "27e4efa094adef0dc5375da7bce70437dde9d35d1e20598240debfc318f374da" + }, + "name": "chainloop-cli-0.93.7-darwin-amd64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782297645680131", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "389ea065be2dd50d07b27619b8594d4738b2c86481db969f62dd549e579af1e2" + }, + "name": "chainloop-cli-0.93.7-darwin-arm64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782300158976415", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "47d5c22ee0f56bf3e7eed5c283fe66e5f61a7a9e913b9af1550dd07e71ac09e1" + }, + "name": "chainloop-cli-0.93.7-darwin-arm64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782301800977382", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "a57b0b11a51b8ebbc9d421bd68e6e82fd021f4e87742780ef30f0aaca0bdd1c2" + }, + "name": "chainloop-cli-0.93.7-linux-amd64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782304541799505", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "754dea96fc2addc0fdb70f725686fd4b5e01a1aa69a1ed0726e4d08866400d42" + }, + "name": "chainloop-cli-0.93.7-linux-amd64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782306140039811", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "c63ee103397001d2e9727d30d02a4ce4e55b7e32da55f042a414c7424b42b21d" + }, + "name": "chainloop-cli-0.93.7-linux-arm64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782308650938558", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "b5c7c73c9d4cd325b8da64135c28685715e8e19f6b48357eaf1a02e693734f37" + }, + "name": "chainloop-cli-0.93.7-linux-arm64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782309843066922", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "897f1dfc64736dd66ea8881ab07689d59e1bc147c45da0baa1de416834a46a3d" + }, + "name": "checksums.txt" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782311062937592", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "2f804aa3b95a81802c24e384e5e87e86f02ec23d043c9c4d3aa9243ee866b60b" + }, + "name": "checksums.txt.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782311526704542", + "chainloop.material.type": "SBOM_CYCLONEDX_JSON" + }, + "digest": { + "sha256": "8b53305ead21a9ede6e0e3aee2fcc04f04796716e1a2b566ce03f3f8cbc2b130" + }, + "name": "controlplane.cyclonedx.json" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782313410977824", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "91c0b92358109bfc31ea4c58902d9b7f4f582ff9c4782fb276a685e914d3cc82" + }, + "name": "cosign.pub" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782315689903312", + "chainloop.material.type": "HELM_CHART" + }, + "digest": { + "sha256": "7cbbda1e5ab71fef561c0f123f5f584c8e0de523d4da80379599ce7a05c04c1f" + }, + "name": "chainloop-0.93.7.tar.gz" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782317669410353", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "4a8eb6f9ae76460b682e7e9eb5504df9f7f2b2250d9c5cb63204442e265e2c5a" + }, + "name": "ghcr.io/chainloop-dev/chainloop/control-plane" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782318334142313", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "4d329b2aee79b35ec5e6c462be5d8000565d5ccd13602427cd889fc91c187fc8" + }, + "name": "ghcr.io/chainloop-dev/chainloop/artifact-cas" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782319034635257", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "571a5543151d651cbc62679c3f50c2e6cadfd2ff20279374c6d6106b3f70560f" + }, + "name": "ghcr.io/chainloop-dev/chainloop/cli" + } + ], + "metadata": { + "finishedAt": "2024-07-12T11:05:19.808858785Z", + "initializedAt": "2024-07-12T11:04:48.604833219Z", + "name": "chainloop-vault-release", + "organization": "read-only-demo", + "project": "chainloop", + "team": "", + "workflowID": "2acc7ee5-21d1-4500-9ca4-2d25748a1ce0", + "workflowRunID": "37dd3d94-06e3-483f-83c2-18b1137e73ee" + }, + "runnerType": "GITHUB_ACTION", + "runnerURL": "https://github.com/chainloop-dev/chainloop/actions/runs/9906853011" + } +} \ No newline at end of file diff --git a/pkg/policies/testdata/statement_gitlab.json b/pkg/policies/testdata/statement_gitlab.json new file mode 100644 index 000000000..affd5a8f9 --- /dev/null +++ b/pkg/policies/testdata/statement_gitlab.json @@ -0,0 +1,247 @@ +{ + "_type": "https://in-toto.io/Statement/v1", + "subject": [ + { + "name": "chainloop.workflow.chainloop-vault-release", + "digest": { + "sha256": "9ae495a85891eb1130fefc17bc89940c9aa96acb8355c26a3e0d73a5097d41d4" + } + }, + { + "name": "git.head", + "digest": { + "sha1": "53f95f066b620172301e2a3879e7d593da05727e" + }, + "annotations": { + "author.email": "devel@chainloop.dev", + "author.name": "Developer", + "date": "2024-07-12T10:16:04Z", + "message": "chore(vulns): fix CVEs in base image (#1088)\n\nSigned-off-by: Jose I. Paris ", + "remotes": [ + { + "name": "origin", + "url": "https://github.com/chainloop-dev/chainloop" + } + ] + } + } + ], + "predicateType": "chainloop.dev/attestation/v0.2", + "predicate": { + "buildType": "chainloop.dev/workflowrun/v0.1", + "builder": { + "id": "chainloop.dev/cli/0.90.1@sha256:431a0765636854095f0c78d01b61eb5558abe7c8de1608aa93eef1530deee0b6" + }, + "env": { + "GITHUB_ACTOR": "jiparis", + "GITHUB_REF": "refs/tags/v0.93.7", + "GITHUB_REPOSITORY": "chainloop-dev/chainloop", + "GITHUB_REPOSITORY_OWNER": "chainloop-dev", + "GITHUB_RUN_ID": "9906853011", + "GITHUB_SHA": "53f95f066b620172301e2a3879e7d593da05727e", + "RUNNER_NAME": "GitHub Actions 193", + "RUNNER_OS": "Linux" + }, + "materials": [ + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782291120414953", + "chainloop.material.type": "SBOM_CYCLONEDX_JSON" + }, + "digest": { + "sha256": "bc449b71c4a47f2f69b514f27e1d61250ff0af0cc554a68d331b40042d90a3da" + }, + "name": "cas.cyclonedx.json" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782293352471920", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "972ca204670aee23ed070619333fb04410ed996bf3c063ff88d35de0702fd478" + }, + "name": "chainloop-cli-0.93.7-darwin-amd64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782295934163620", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "27e4efa094adef0dc5375da7bce70437dde9d35d1e20598240debfc318f374da" + }, + "name": "chainloop-cli-0.93.7-darwin-amd64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782297645680131", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "389ea065be2dd50d07b27619b8594d4738b2c86481db969f62dd549e579af1e2" + }, + "name": "chainloop-cli-0.93.7-darwin-arm64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782300158976415", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "47d5c22ee0f56bf3e7eed5c283fe66e5f61a7a9e913b9af1550dd07e71ac09e1" + }, + "name": "chainloop-cli-0.93.7-darwin-arm64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782301800977382", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "a57b0b11a51b8ebbc9d421bd68e6e82fd021f4e87742780ef30f0aaca0bdd1c2" + }, + "name": "chainloop-cli-0.93.7-linux-amd64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782304541799505", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "754dea96fc2addc0fdb70f725686fd4b5e01a1aa69a1ed0726e4d08866400d42" + }, + "name": "chainloop-cli-0.93.7-linux-amd64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782306140039811", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "c63ee103397001d2e9727d30d02a4ce4e55b7e32da55f042a414c7424b42b21d" + }, + "name": "chainloop-cli-0.93.7-linux-arm64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782308650938558", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "b5c7c73c9d4cd325b8da64135c28685715e8e19f6b48357eaf1a02e693734f37" + }, + "name": "chainloop-cli-0.93.7-linux-arm64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782309843066922", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "897f1dfc64736dd66ea8881ab07689d59e1bc147c45da0baa1de416834a46a3d" + }, + "name": "checksums.txt" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782311062937592", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "2f804aa3b95a81802c24e384e5e87e86f02ec23d043c9c4d3aa9243ee866b60b" + }, + "name": "checksums.txt.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782311526704542", + "chainloop.material.type": "SBOM_CYCLONEDX_JSON" + }, + "digest": { + "sha256": "8b53305ead21a9ede6e0e3aee2fcc04f04796716e1a2b566ce03f3f8cbc2b130" + }, + "name": "controlplane.cyclonedx.json" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782313410977824", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "91c0b92358109bfc31ea4c58902d9b7f4f582ff9c4782fb276a685e914d3cc82" + }, + "name": "cosign.pub" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782315689903312", + "chainloop.material.type": "HELM_CHART" + }, + "digest": { + "sha256": "7cbbda1e5ab71fef561c0f123f5f584c8e0de523d4da80379599ce7a05c04c1f" + }, + "name": "chainloop-0.93.7.tar.gz" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782317669410353", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "4a8eb6f9ae76460b682e7e9eb5504df9f7f2b2250d9c5cb63204442e265e2c5a" + }, + "name": "ghcr.io/chainloop-dev/chainloop/control-plane" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782318334142313", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "4d329b2aee79b35ec5e6c462be5d8000565d5ccd13602427cd889fc91c187fc8" + }, + "name": "ghcr.io/chainloop-dev/chainloop/artifact-cas" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782319034635257", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "571a5543151d651cbc62679c3f50c2e6cadfd2ff20279374c6d6106b3f70560f" + }, + "name": "ghcr.io/chainloop-dev/chainloop/cli" + } + ], + "metadata": { + "finishedAt": "2024-07-12T11:05:19.808858785Z", + "initializedAt": "2024-07-12T11:04:48.604833219Z", + "name": "chainloop-vault-release", + "organization": "read-only-demo", + "project": "chainloop", + "team": "", + "workflowID": "2acc7ee5-21d1-4500-9ca4-2d25748a1ce0", + "workflowRunID": "37dd3d94-06e3-483f-83c2-18b1137e73ee" + }, + "runnerType": "GITLAB", + "runnerURL": "https://github.com/chainloop-dev/chainloop/actions/runs/9906853011" + } +} \ No newline at end of file diff --git a/pkg/policies/testdata/statement_missing_runner.json b/pkg/policies/testdata/statement_missing_runner.json new file mode 100644 index 000000000..99dec26c4 --- /dev/null +++ b/pkg/policies/testdata/statement_missing_runner.json @@ -0,0 +1,245 @@ +{ + "_type": "https://in-toto.io/Statement/v1", + "subject": [ + { + "name": "chainloop.workflow.chainloop-vault-release", + "digest": { + "sha256": "9ae495a85891eb1130fefc17bc89940c9aa96acb8355c26a3e0d73a5097d41d4" + } + }, + { + "name": "git.head", + "digest": { + "sha1": "53f95f066b620172301e2a3879e7d593da05727e" + }, + "annotations": { + "author.email": "devel@chainloop.dev", + "author.name": "Developer", + "date": "2024-07-12T10:16:04Z", + "message": "chore(vulns): fix CVEs in base image (#1088)\n\nSigned-off-by: Jose I. Paris ", + "remotes": [ + { + "name": "origin", + "url": "https://github.com/chainloop-dev/chainloop" + } + ] + } + } + ], + "predicateType": "chainloop.dev/attestation/v0.2", + "predicate": { + "buildType": "chainloop.dev/workflowrun/v0.1", + "builder": { + "id": "chainloop.dev/cli/0.90.1@sha256:431a0765636854095f0c78d01b61eb5558abe7c8de1608aa93eef1530deee0b6" + }, + "env": { + "GITHUB_ACTOR": "jiparis", + "GITHUB_REF": "refs/tags/v0.93.7", + "GITHUB_REPOSITORY": "chainloop-dev/chainloop", + "GITHUB_REPOSITORY_OWNER": "chainloop-dev", + "GITHUB_RUN_ID": "9906853011", + "GITHUB_SHA": "53f95f066b620172301e2a3879e7d593da05727e", + "RUNNER_NAME": "GitHub Actions 193", + "RUNNER_OS": "Linux" + }, + "materials": [ + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782291120414953", + "chainloop.material.type": "SBOM_CYCLONEDX_JSON" + }, + "digest": { + "sha256": "bc449b71c4a47f2f69b514f27e1d61250ff0af0cc554a68d331b40042d90a3da" + }, + "name": "cas.cyclonedx.json" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782293352471920", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "972ca204670aee23ed070619333fb04410ed996bf3c063ff88d35de0702fd478" + }, + "name": "chainloop-cli-0.93.7-darwin-amd64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782295934163620", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "27e4efa094adef0dc5375da7bce70437dde9d35d1e20598240debfc318f374da" + }, + "name": "chainloop-cli-0.93.7-darwin-amd64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782297645680131", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "389ea065be2dd50d07b27619b8594d4738b2c86481db969f62dd549e579af1e2" + }, + "name": "chainloop-cli-0.93.7-darwin-arm64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782300158976415", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "47d5c22ee0f56bf3e7eed5c283fe66e5f61a7a9e913b9af1550dd07e71ac09e1" + }, + "name": "chainloop-cli-0.93.7-darwin-arm64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782301800977382", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "a57b0b11a51b8ebbc9d421bd68e6e82fd021f4e87742780ef30f0aaca0bdd1c2" + }, + "name": "chainloop-cli-0.93.7-linux-amd64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782304541799505", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "754dea96fc2addc0fdb70f725686fd4b5e01a1aa69a1ed0726e4d08866400d42" + }, + "name": "chainloop-cli-0.93.7-linux-amd64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782306140039811", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "c63ee103397001d2e9727d30d02a4ce4e55b7e32da55f042a414c7424b42b21d" + }, + "name": "chainloop-cli-0.93.7-linux-arm64.tar.gz" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782308650938558", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "b5c7c73c9d4cd325b8da64135c28685715e8e19f6b48357eaf1a02e693734f37" + }, + "name": "chainloop-cli-0.93.7-linux-arm64.tar.gz.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782309843066922", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "897f1dfc64736dd66ea8881ab07689d59e1bc147c45da0baa1de416834a46a3d" + }, + "name": "checksums.txt" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782311062937592", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "2f804aa3b95a81802c24e384e5e87e86f02ec23d043c9c4d3aa9243ee866b60b" + }, + "name": "checksums.txt.sig" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782311526704542", + "chainloop.material.type": "SBOM_CYCLONEDX_JSON" + }, + "digest": { + "sha256": "8b53305ead21a9ede6e0e3aee2fcc04f04796716e1a2b566ce03f3f8cbc2b130" + }, + "name": "controlplane.cyclonedx.json" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782313410977824", + "chainloop.material.type": "ARTIFACT" + }, + "digest": { + "sha256": "91c0b92358109bfc31ea4c58902d9b7f4f582ff9c4782fb276a685e914d3cc82" + }, + "name": "cosign.pub" + }, + { + "annotations": { + "chainloop.material.cas": true, + "chainloop.material.name": "material-1720782315689903312", + "chainloop.material.type": "HELM_CHART" + }, + "digest": { + "sha256": "7cbbda1e5ab71fef561c0f123f5f584c8e0de523d4da80379599ce7a05c04c1f" + }, + "name": "chainloop-0.93.7.tar.gz" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782317669410353", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "4a8eb6f9ae76460b682e7e9eb5504df9f7f2b2250d9c5cb63204442e265e2c5a" + }, + "name": "ghcr.io/chainloop-dev/chainloop/control-plane" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782318334142313", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "4d329b2aee79b35ec5e6c462be5d8000565d5ccd13602427cd889fc91c187fc8" + }, + "name": "ghcr.io/chainloop-dev/chainloop/artifact-cas" + }, + { + "annotations": { + "chainloop.material.image.tag": "v0.93.7", + "chainloop.material.name": "material-1720782319034635257", + "chainloop.material.type": "CONTAINER_IMAGE" + }, + "digest": { + "sha256": "571a5543151d651cbc62679c3f50c2e6cadfd2ff20279374c6d6106b3f70560f" + }, + "name": "ghcr.io/chainloop-dev/chainloop/cli" + } + ], + "metadata": { + "finishedAt": "2024-07-12T11:05:19.808858785Z", + "initializedAt": "2024-07-12T11:04:48.604833219Z", + "name": "chainloop-vault-release", + "organization": "read-only-demo", + "project": "chainloop", + "team": "", + "workflowID": "2acc7ee5-21d1-4500-9ca4-2d25748a1ce0", + "workflowRunID": "37dd3d94-06e3-483f-83c2-18b1137e73ee" + } + } +} \ No newline at end of file diff --git a/pkg/policies/testdata/workflow.rego b/pkg/policies/testdata/workflow.rego index 403fa3c4d..74eac1353 100644 --- a/pkg/policies/testdata/workflow.rego +++ b/pkg/policies/testdata/workflow.rego @@ -14,9 +14,10 @@ deny[msg] { is_workflow { - input.workflow.name == "policytest" + input.predicate.metadata.name == "chainloop-vault-release" } is_github { - input.runnerType == "GITHUB_ACTION" + input.predicate.runnerType == "GITHUB_ACTION" + input.predicate.env.GITHUB_SHA } \ No newline at end of file diff --git a/pkg/policies/testdata/workflow.yaml b/pkg/policies/testdata/workflow.yaml index 60aa90267..c4f6c0179 100644 --- a/pkg/policies/testdata/workflow.yaml +++ b/pkg/policies/testdata/workflow.yaml @@ -3,4 +3,5 @@ kind: Policy metadata: name: workflow spec: + type: ATTESTATION path: testdata/workflow.rego diff --git a/pkg/policies/testdata/workflow_embedded.yaml b/pkg/policies/testdata/workflow_embedded.yaml index 6e02a4062..ceb1585e4 100644 --- a/pkg/policies/testdata/workflow_embedded.yaml +++ b/pkg/policies/testdata/workflow_embedded.yaml @@ -3,6 +3,7 @@ kind: Policy metadata: name: workflow spec: + type: ATTESTATION embedded: | package main deny[msg] { @@ -10,6 +11,17 @@ spec: msg := "incorrect workflow" } + deny[msg] { + not is_github + msg := "incorrect runner" + } + is_workflow { - input.workflow.name == "policytest" + input.predicate.metadata.name == "chainloop-vault-release" + } + + is_github { + input.predicate.runnerType == "GITHUB_ACTION" + input.predicate.env.GITHUB_SHA } +