From 56cb209451724d732d84d328d97488b6d3fb3363 Mon Sep 17 00:00:00 2001 From: Jon Orris Date: Wed, 22 Jan 2025 16:23:54 -0500 Subject: [PATCH 1/7] Add a check for the RPM build pipleline Ensure that all tasks building the RPM come from an approved pipeline. --- policy/release/rpm_pipeline/rpm_pipeline.rego | 45 +++++++++++++++++ .../rpm_pipeline/rpm_pipeline_test.rego | 49 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 policy/release/rpm_pipeline/rpm_pipeline.rego create mode 100644 policy/release/rpm_pipeline/rpm_pipeline_test.rego diff --git a/policy/release/rpm_pipeline/rpm_pipeline.rego b/policy/release/rpm_pipeline/rpm_pipeline.rego new file mode 100644 index 00000000..ca883277 --- /dev/null +++ b/policy/release/rpm_pipeline/rpm_pipeline.rego @@ -0,0 +1,45 @@ +# +# METADATA +# title: RPM Pipeline +# description: >- +# This package provides rules for verifying the RPMs are built in an approved pipeline +# +package rpm_pipeline + +import rego.v1 + +import data.lib +import data.lib.tekton + +_pipeline_key := "build.appstudio.redhat.com/pipeline" + +_rule_data_key := "allowed_rpm_build_pipelines" + +# METADATA +# title: Task version invalid_pipeline +# description: >- +# The Tekton Task used specifies an invalid pipeline. The Task is annotated with +# `build.appstudio.redhat.com/pipeline` annotation, which must be in the set of +# `allowed_rpm_build_pipelines` in the rule data. +# custom: +# short_name: invalid_pipeline +# failure_msg: >- +# Task %q uses invalid pipleline %s, which is not in the list of valid pipelines: %s +# collections: +# - redhat +# depends_on: +# - tasks.pipeline_has_tasks +# +deny contains result if { + some att in lib.pipelinerun_attestations + some task in tekton.tasks(att) + + annotations := tekton.task_annotations(task) + pipeline := annotations[_pipeline_key] + allowed_pipelines := lib.rule_data(_rule_data_key) + + some p in allowed_pipelines + p != pipeline + + result := lib.result_helper(rego.metadata.chain(), [tekton.pipeline_task_name(task), pipeline, concat(",", allowed_pipelines)]) +} diff --git a/policy/release/rpm_pipeline/rpm_pipeline_test.rego b/policy/release/rpm_pipeline/rpm_pipeline_test.rego new file mode 100644 index 00000000..9f702f79 --- /dev/null +++ b/policy/release/rpm_pipeline/rpm_pipeline_test.rego @@ -0,0 +1,49 @@ +package rpm_pipeline_test + +import rego.v1 + +import data.lib +import data.rpm_pipeline + +test_invalid_pipeline if { + attestations := [{"statement": {"predicate": { + "buildType": lib.tekton_pipeline_run, + "buildConfig": {"tasks": [_valid_pipeline_task, _invalid_pipeline_task]}, + }}}] + + expected := {{ + "code": "rpm_pipeline.invalid_pipeline", + "msg": "Task \"build\" uses invalid pipleline not_allowed, which is not in the list of valid pipelines: foobar", + }} + lib.assert_equal_results(expected, rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as ["foobar"] with input.attestations as attestations +} + +test_valid_pipelines_met if { + attestations := [{"statement": {"predicate": { + "buildType": lib.tekton_pipeline_run, + "buildConfig": {"tasks": [_valid_pipeline_task, _valid_pipeline_task_2]}, + }}}] + + lib.assert_empty(rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as [["foobar", "baz"]] with input.attestations as attestations +} + +_invalid_pipeline_task := { + "name": "build", + "status": "Succeeded", + "ref": {"name": "init", "kind": "Task", "bundle": "quay.io/konflux-ci/tekton-catalog/task-init"}, + "invocation": {"environment": {"annotations": {"build.appstudio.redhat.com/pipeline": "not_allowed"}}}, +} + +_valid_pipeline_task := { + "name": "init", + "status": "Succeeded", + "ref": {"name": "init", "kind": "Task", "bundle": "quay.io/konflux-ci/tekton-catalog/task-init"}, + "invocation": {"environment": {"annotations": {"build.appstudio.redhat.com/pipeline": "foobar"}}}, +} + +_valid_pipeline_task_2 := { + "name": "get-rpm-sources", + "status": "Succeeded", + "ref": {"name": "init", "kind": "Task", "bundle": "quay.io/konflux-ci/tekton-catalog/task-init"}, + "invocation": {"environment": {"annotations": {"build.appstudio.redhat.com/pipeline": "biff"}}}, +} From 80177de45ac03590ed29f053cca4b34affe29fe9 Mon Sep 17 00:00:00 2001 From: Jon Orris Date: Wed, 22 Jan 2025 16:25:48 -0500 Subject: [PATCH 2/7] Add a separate collection for rpms --- policy/release/collection/redhat_rpms/redhat_rpms.rego | 8 ++++++++ policy/release/rpm_pipeline/rpm_pipeline.rego | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 policy/release/collection/redhat_rpms/redhat_rpms.rego diff --git a/policy/release/collection/redhat_rpms/redhat_rpms.rego b/policy/release/collection/redhat_rpms/redhat_rpms.rego new file mode 100644 index 00000000..f810562e --- /dev/null +++ b/policy/release/collection/redhat_rpms/redhat_rpms.rego @@ -0,0 +1,8 @@ +# +# METADATA +# title: redhat_rpms +# description: >- +# Include the set of policy rules required for building Red Hat RPMs. +package collection.redhat_rpms + +import rego.v1 diff --git a/policy/release/rpm_pipeline/rpm_pipeline.rego b/policy/release/rpm_pipeline/rpm_pipeline.rego index ca883277..05020d1a 100644 --- a/policy/release/rpm_pipeline/rpm_pipeline.rego +++ b/policy/release/rpm_pipeline/rpm_pipeline.rego @@ -26,7 +26,7 @@ _rule_data_key := "allowed_rpm_build_pipelines" # failure_msg: >- # Task %q uses invalid pipleline %s, which is not in the list of valid pipelines: %s # collections: -# - redhat +# - redhat_rpms # depends_on: # - tasks.pipeline_has_tasks # From a77aea38d1e08f636e3b23e07f8987aa5a8b6043 Mon Sep 17 00:00:00 2001 From: Jon Orris Date: Thu, 23 Jan 2025 07:49:12 -0500 Subject: [PATCH 3/7] Fix line length --- policy/release/rpm_pipeline/rpm_pipeline.rego | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/policy/release/rpm_pipeline/rpm_pipeline.rego b/policy/release/rpm_pipeline/rpm_pipeline.rego index 05020d1a..4871e4e7 100644 --- a/policy/release/rpm_pipeline/rpm_pipeline.rego +++ b/policy/release/rpm_pipeline/rpm_pipeline.rego @@ -41,5 +41,8 @@ deny contains result if { some p in allowed_pipelines p != pipeline - result := lib.result_helper(rego.metadata.chain(), [tekton.pipeline_task_name(task), pipeline, concat(",", allowed_pipelines)]) + result := lib.result_helper( + rego.metadata.chain(), + [tekton.pipeline_task_name(task), pipeline, concat(",", allowed_pipelines)], + ) } From e41bfac84f70a9d77504b3c780e0a2a8d020f2d4 Mon Sep 17 00:00:00 2001 From: Jon Orris Date: Thu, 23 Jan 2025 16:25:57 -0500 Subject: [PATCH 4/7] Fix some syntax and bad test data --- policy/release/rpm_pipeline/rpm_pipeline.rego | 3 +-- policy/release/rpm_pipeline/rpm_pipeline_test.rego | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/policy/release/rpm_pipeline/rpm_pipeline.rego b/policy/release/rpm_pipeline/rpm_pipeline.rego index 4871e4e7..d2e71921 100644 --- a/policy/release/rpm_pipeline/rpm_pipeline.rego +++ b/policy/release/rpm_pipeline/rpm_pipeline.rego @@ -38,8 +38,7 @@ deny contains result if { pipeline := annotations[_pipeline_key] allowed_pipelines := lib.rule_data(_rule_data_key) - some p in allowed_pipelines - p != pipeline + not pipeline in allowed_pipelines result := lib.result_helper( rego.metadata.chain(), diff --git a/policy/release/rpm_pipeline/rpm_pipeline_test.rego b/policy/release/rpm_pipeline/rpm_pipeline_test.rego index 9f702f79..be852280 100644 --- a/policy/release/rpm_pipeline/rpm_pipeline_test.rego +++ b/policy/release/rpm_pipeline/rpm_pipeline_test.rego @@ -24,7 +24,7 @@ test_valid_pipelines_met if { "buildConfig": {"tasks": [_valid_pipeline_task, _valid_pipeline_task_2]}, }}}] - lib.assert_empty(rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as [["foobar", "baz"]] with input.attestations as attestations + lib.assert_empty(rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as ["foobar", "baz"] with input.attestations as attestations } _invalid_pipeline_task := { @@ -45,5 +45,5 @@ _valid_pipeline_task_2 := { "name": "get-rpm-sources", "status": "Succeeded", "ref": {"name": "init", "kind": "Task", "bundle": "quay.io/konflux-ci/tekton-catalog/task-init"}, - "invocation": {"environment": {"annotations": {"build.appstudio.redhat.com/pipeline": "biff"}}}, + "invocation": {"environment": {"annotations": {"build.appstudio.redhat.com/pipeline": "baz"}}}, } From 77c4a1ee3e7dfd333f90428408976085ee7ae342 Mon Sep 17 00:00:00 2001 From: Jon Orris Date: Mon, 27 Jan 2025 12:21:29 -0500 Subject: [PATCH 5/7] Line length fix --- policy/release/rpm_pipeline/rpm_pipeline_test.rego | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/policy/release/rpm_pipeline/rpm_pipeline_test.rego b/policy/release/rpm_pipeline/rpm_pipeline_test.rego index be852280..97a2ca24 100644 --- a/policy/release/rpm_pipeline/rpm_pipeline_test.rego +++ b/policy/release/rpm_pipeline/rpm_pipeline_test.rego @@ -15,7 +15,8 @@ test_invalid_pipeline if { "code": "rpm_pipeline.invalid_pipeline", "msg": "Task \"build\" uses invalid pipleline not_allowed, which is not in the list of valid pipelines: foobar", }} - lib.assert_equal_results(expected, rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as ["foobar"] with input.attestations as attestations + lib.assert_equal_results(expected, rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as ["foobar"] + with input.attestations as attestations } test_valid_pipelines_met if { @@ -24,7 +25,8 @@ test_valid_pipelines_met if { "buildConfig": {"tasks": [_valid_pipeline_task, _valid_pipeline_task_2]}, }}}] - lib.assert_empty(rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as ["foobar", "baz"] with input.attestations as attestations + lib.assert_empty(rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as ["foobar", "baz"] + with input.attestations as attestations } _invalid_pipeline_task := { From 91208aac22e013c2dd94d338709a40da6334f914 Mon Sep 17 00:00:00 2001 From: Jon Orris Date: Mon, 27 Jan 2025 12:57:12 -0500 Subject: [PATCH 6/7] Fix format --- policy/release/rpm_pipeline/rpm_pipeline_test.rego | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/policy/release/rpm_pipeline/rpm_pipeline_test.rego b/policy/release/rpm_pipeline/rpm_pipeline_test.rego index 97a2ca24..41ea9c8a 100644 --- a/policy/release/rpm_pipeline/rpm_pipeline_test.rego +++ b/policy/release/rpm_pipeline/rpm_pipeline_test.rego @@ -16,7 +16,7 @@ test_invalid_pipeline if { "msg": "Task \"build\" uses invalid pipleline not_allowed, which is not in the list of valid pipelines: foobar", }} lib.assert_equal_results(expected, rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as ["foobar"] - with input.attestations as attestations + with input.attestations as attestations } test_valid_pipelines_met if { @@ -26,7 +26,7 @@ test_valid_pipelines_met if { }}}] lib.assert_empty(rpm_pipeline.deny) with data.rule_data.allowed_rpm_build_pipelines as ["foobar", "baz"] - with input.attestations as attestations + with input.attestations as attestations } _invalid_pipeline_task := { From 782c37b390dca1424394c9f0babc89f283bd2423 Mon Sep 17 00:00:00 2001 From: Jon Orris Date: Mon, 27 Jan 2025 13:16:21 -0500 Subject: [PATCH 7/7] Generate docs --- .../modules/ROOT/pages/release_policy.adoc | 24 +++++++++++++++++++ .../ROOT/partials/release_policy_nav.adoc | 3 +++ 2 files changed, 27 insertions(+) diff --git a/antora/docs/modules/ROOT/pages/release_policy.adoc b/antora/docs/modules/ROOT/pages/release_policy.adoc index 0627ec00..1e7ca3df 100644 --- a/antora/docs/modules/ROOT/pages/release_policy.adoc +++ b/antora/docs/modules/ROOT/pages/release_policy.adoc @@ -206,6 +206,13 @@ Rules included: * xref:release_policy.adoc#rpm_ostree_task__builder_image_param[rpm-ostree Task: Builder image parameter] * xref:release_policy.adoc#rpm_ostree_task__rule_data[rpm-ostree Task: Rule data] +| [#redhat_rpms]`redhat_rpms` +a| Include the set of policy rules required for building Red Hat RPMs. + +Rules included: + +* xref:release_policy.adoc#rpm_pipeline__invalid_pipeline[RPM Pipeline: Task version invalid_pipeline] + | [#rhtap-multi-ci]`rhtap-multi-ci` a| A set of policy rules to validate artifacts built using RHTAP Multi-CI pipelines. @@ -990,6 +997,23 @@ Verify an attestation created by the RHTAP Multi-CI build pipeline is present. * Code: `rhtap_multi_ci.attestation_found` * https://github.com/enterprise-contract/ec-policies/blob/{page-origin-refhash}/policy/release/rhtap_multi_ci/rhtap_multi_ci.rego#L16[Source, window="_blank"] +[#rpm_pipeline_package] +== link:#rpm_pipeline_package[RPM Pipeline] + +This package provides rules for verifying the RPMs are built in an approved pipeline + +* Package name: `rpm_pipeline` + +[#rpm_pipeline__invalid_pipeline] +=== link:#rpm_pipeline__invalid_pipeline[Task version invalid_pipeline] + +The Tekton Task used specifies an invalid pipeline. The Task is annotated with `build.appstudio.redhat.com/pipeline` annotation, which must be in the set of `allowed_rpm_build_pipelines` in the rule data. + +* Rule type: [rule-type-indicator failure]#FAILURE# +* FAILURE message: `Task %q uses invalid pipleline %s, which is not in the list of valid pipelines: %s` +* Code: `rpm_pipeline.invalid_pipeline` +* https://github.com/enterprise-contract/ec-policies/blob/{page-origin-refhash}/policy/release/rpm_pipeline/rpm_pipeline.rego#L18[Source, window="_blank"] + [#rpm_repos_package] == link:#rpm_repos_package[RPM Repos] diff --git a/antora/docs/modules/ROOT/partials/release_policy_nav.adoc b/antora/docs/modules/ROOT/partials/release_policy_nav.adoc index bebbc4b1..3dcf1daa 100644 --- a/antora/docs/modules/ROOT/partials/release_policy_nav.adoc +++ b/antora/docs/modules/ROOT/partials/release_policy_nav.adoc @@ -4,6 +4,7 @@ *** xref:release_policy.adoc#minimal[minimal] *** xref:release_policy.adoc#policy_data[policy_data] *** xref:release_policy.adoc#redhat[redhat] +*** xref:release_policy.adoc#redhat_rpms[redhat_rpms] *** xref:release_policy.adoc#rhtap-multi-ci[rhtap-multi-ci] *** xref:release_policy.adoc#slsa3[slsa3] ** Release Rules @@ -74,6 +75,8 @@ *** xref:release_policy.adoc#rhtap_multi_ci_package[RHTAP Multi-CI] **** xref:release_policy.adoc#rhtap_multi_ci__attestation_format[SLSA Provenance Attestation Format] **** xref:release_policy.adoc#rhtap_multi_ci__attestation_found[SLSA Provenance Attestation Found] +*** xref:release_policy.adoc#rpm_pipeline_package[RPM Pipeline] +**** xref:release_policy.adoc#rpm_pipeline__invalid_pipeline[Task version invalid_pipeline] *** xref:release_policy.adoc#rpm_repos_package[RPM Repos] **** xref:release_policy.adoc#rpm_repos__ids_known[All rpms have known repo ids] **** xref:release_policy.adoc#rpm_repos__rule_data_provided[Known repo id list provided]