Skip to content

Commit

Permalink
Merge pull request #993 from simonbaird/quay-expires-after
Browse files Browse the repository at this point in the history
Prevent release with quay expires-after set
  • Loading branch information
simonbaird committed May 15, 2024
2 parents b977a95 + 9750df9 commit 7058844
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
21 changes: 21 additions & 0 deletions antora/docs/modules/ROOT/pages/release_policy.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ Rules included:
* xref:release_policy.adoc#olm__unpinned_references[OLM: Unpinned images in OLM bundle]
* xref:release_policy.adoc#provenance_materials__git_clone_source_matches_provenance[Provenance Materials: Git clone source matches materials provenance]
* xref:release_policy.adoc#provenance_materials__git_clone_task_found[Provenance Materials: Git clone task found]
* xref:release_policy.adoc#quay_expiration__expires_label[Quay expiration: Expires label]
* xref:release_policy.adoc#redhat_manifests__redhat_manifests_missing[Red Hat manifests: Missing Red Hat manifests]
* xref:release_policy.adoc#sbom_cyclonedx__allowed[SBOM CycloneDX: Allowed]
* xref:release_policy.adoc#sbom_cyclonedx__disallowed_packages_provided[SBOM CycloneDX: Disallowed packages list is provided]
Expand Down Expand Up @@ -824,6 +825,26 @@ Confirm that the attestation contains a git-clone task with `commit` and `url` t
* Code: `provenance_materials.git_clone_task_found`
* https://github.com/enterprise-contract/ec-policies/blob/{page-origin-refhash}/policy/release/provenance_materials.rego#L15[Source, window="_blank"]

[#quay_expiration_package]
== link:#quay_expiration_package[Quay expiration]

Policies to prevent releasing an image to quay that has a quay expiration date. In Konflux images with an expiration date are produced by "on-pr" build pipelines, i.e. pre-merge CI builds, so this is intended to prevent accidentally releasing a CI build.

* Package name: `quay_expiration`
* Package full path: `policy.release.quay_expiration`

[#quay_expiration__expires_label]
=== link:#quay_expiration__expires_label[Expires label]

Check the image metadata for the presence of a "quay.expires-after" label. If it's present then produce a violation. This check is enforced only for a "release" pipeline, as determined by the value of the `pipeline_intention` rule data.

*Solution*: Make sure the image is built without setting the "quay.expires-after" label. This label is usually set if the container image was built by an "on-pr" pipeline during pre-merge CI.

* Rule type: [rule-type-indicator failure]#FAILURE#
* FAILURE message: `The image has a 'quay.expires-after' label set to '%s'`
* Code: `quay_expiration.expires_label`
* https://github.com/enterprise-contract/ec-policies/blob/{page-origin-refhash}/policy/release/quay_expiration.rego#L16[Source, window="_blank"]

[#redhat_manifests_package]
== link:#redhat_manifests_package[Red Hat manifests]

Expand Down
2 changes: 2 additions & 0 deletions antora/docs/modules/ROOT/partials/release_policy_nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
*** xref:release_policy.adoc#provenance_materials_package[Provenance Materials]
**** xref:release_policy.adoc#provenance_materials__git_clone_source_matches_provenance[Git clone source matches materials provenance]
**** xref:release_policy.adoc#provenance_materials__git_clone_task_found[Git clone task found]
*** xref:release_policy.adoc#quay_expiration_package[Quay expiration]
**** xref:release_policy.adoc#quay_expiration__expires_label[Expires label]
*** xref:release_policy.adoc#redhat_manifests_package[Red Hat manifests]
**** xref:release_policy.adoc#redhat_manifests__redhat_manifests_missing[Missing Red Hat manifests]
*** xref:release_policy.adoc#sbom_cyclonedx_package[SBOM CycloneDX]
Expand Down
56 changes: 56 additions & 0 deletions policy/release/quay_expiration.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#
# METADATA
# title: Quay expiration
# description: >-
# Policies to prevent releasing an image to quay that has a quay
# expiration date. In Konflux images with an expiration date are
# produced by "on-pr" build pipelines, i.e. pre-merge CI builds,
# so this is intended to prevent accidentally releasing a CI build.
#
package policy.release.quay_expiration

import rego.v1

import data.lib

# METADATA
# title: Expires label
# description: >-
# Check the image metadata for the presence of a "quay.expires-after"
# label. If it's present then produce a violation. This check is enforced
# only for a "release" pipeline, as determined by the value of the
# `pipeline_intention` rule data.
# custom:
# short_name: expires_label
# failure_msg: The image has a 'quay.expires-after' label set to '%s'
# solution: >-
# Make sure the image is built without setting the "quay.expires-after" label. This
# label is usually set if the container image was built by an "on-pr" pipeline
# during pre-merge CI.
# collections:
# - redhat
#
deny contains result if {
_expires_label_check_applies

# This is where we can access the image labels
some label_name, label_value in input.image.config.Labels

# The quay.expires-after label is present
label_name == "quay.expires-after"

# This is an edge case that may never happen, but let's assume that if
# the value is an empty string then it is not an expiration and therefore
# can be permitted
count(label_value) > 0

# Send up the violation the details
result := lib.result_helper(rego.metadata.chain(), [label_value])
}

# The check only applies if we're intending to release the image
default _expires_label_check_applies := false

_expires_label_check_applies if {
lib.rule_data("pipeline_intention") == "release"
}
54 changes: 54 additions & 0 deletions policy/release/quay_expiration_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package policy.release.quay_expiration_test

import rego.v1

import data.lib
import data.policy.release.quay_expiration

test_ci_pipeline if {
# Should not produce violations when we're in a non-release pipeline
lib.assert_equal(false, quay_expiration._expires_label_check_applies) with data.rule_data as _rule_data_for_ci

lib.assert_empty(quay_expiration.deny) with input.image as _image_expires_none
with data.rule_data as _rule_data_for_ci

lib.assert_empty(quay_expiration.deny) with input.image as _image_expires_blank
with data.rule_data as _rule_data_for_ci

lib.assert_empty(quay_expiration.deny) with input.image as _image_expires_5d
with data.rule_data as _rule_data_for_ci
}

test_release_pipeline if {
# Should produce violations when we're in a release pipeline
lib.assert_equal(true, quay_expiration._expires_label_check_applies) with data.rule_data as _rule_data_for_release

lib.assert_empty(quay_expiration.deny) with input.image as _image_expires_none
with data.rule_data as _rule_data_for_release

lib.assert_empty(quay_expiration.deny) with input.image as _image_expires_blank
with data.rule_data as _rule_data_for_release

expected := {{
"code": "quay_expiration.expires_label",
"msg": "The image has a 'quay.expires-after' label set to '5d'",
}}
lib.assert_equal_results(expected, quay_expiration.deny) with input.image as _image_expires_5d
with data.rule_data as _rule_data_for_release
}

_image_expires_5d := {"config": {"Labels": {
"foo": "bar",
"quay.expires-after": "5d",
}}}

_image_expires_blank := {"config": {"Labels": {
"foo": "bar",
"quay.expires-after": "",
}}}

_image_expires_none := {"config": {"Labels": {"foo": "bar"}}}

_rule_data_for_ci := {}

_rule_data_for_release := {"pipeline_intention": "release"}

0 comments on commit 7058844

Please sign in to comment.