-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add allowed package sources policy #1212
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -148,6 +148,61 @@ deny contains result if { | |
result := lib.result_helper_with_term(rego.metadata.chain(), [id, reference.url, reference.type, msg], id) | ||
} | ||
|
||
# METADATA | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We also need corresponding changes in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cachi2 currently does not produce an SPDX SBOM, so there's not yet anything to latch onto (as in to the externalReference of type distribution in CycloneDX). Holding out on this until the the comment about rule data format is settled. |
||
# title: Allowed package sources | ||
# description: >- | ||
# For each of the components fetched by Cachi2 which define externalReferences of type | ||
# distribution, verify they are allowed based on the allowed_package_sources rule data | ||
# key. By default, allowed_package_sources is empty which means no components with such | ||
# references are allowed. | ||
# custom: | ||
# short_name: allowed_package_sources | ||
# failure_msg: Package %s fetched by cachi2 was sourced from %q which is not allowed | ||
# solution: Update the image to not use a package from a disallowed source. | ||
# collections: | ||
# - redhat | ||
# - policy_data | ||
# effective_on: 2024-12-15T00:00:00Z | ||
deny contains result if { | ||
some s in sbom.cyclonedx_sboms | ||
some component in s.components | ||
|
||
# only look at components that define an externalReferences of type `distribution` | ||
some reference in component.externalReferences | ||
reference.type == "distribution" | ||
|
||
# only look at components fetched by cachi2 | ||
some properties in component.properties | ||
properties.name == "cachi2:found_by" | ||
properties.value == "cachi2" | ||
|
||
purl := component.purl | ||
parsed_purl := ec.purl.parse(purl) | ||
|
||
# patterns are either those defined by the rule for a give purl type, or empty by default | ||
allowed_data := lib.rule_data(sbom.rule_data_allowed_package_sources_key) | ||
patterns := _get_purl_allowed_patterns(parsed_purl.type, allowed_data) | ||
distribution_url := object.get(reference, "url", "") | ||
|
||
# only progress past this point if no matches were found | ||
not _url_matches_any_pattern(distribution_url, patterns) | ||
|
||
result := lib.result_helper_with_term(rego.metadata.chain(), [purl, distribution_url], purl) | ||
} | ||
|
||
# get allowed pattens for given purl type, or empty list if not defined | ||
_get_purl_allowed_patterns(purl_type, allowed_rule_data) := patterns if { | ||
some allowed in allowed_rule_data | ||
purl_type == allowed.type | ||
patterns := allowed.patterns | ||
} else := [] | ||
|
||
# see if any pattern matches given url | ||
_url_matches_any_pattern(url, patterns) if { | ||
some pattern in patterns | ||
regex.match(pattern, url) | ||
} | ||
|
||
# _with_effective_on annotates the result with the item's effective_on attribute. If the item does | ||
# not have the attribute, result is returned unmodified. | ||
_with_effective_on(result, item) := new_result if { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -188,6 +188,101 @@ test_external_references_disallowed_no_purl if { | |
}]} | ||
} | ||
|
||
test_allowed_package_sources if { | ||
expected := {{ | ||
"code": "sbom_cyclonedx.allowed_package_sources", | ||
"term": "pkg:generic/[email protected]?download_url=https://openssl.org/source/openssl-1.1.0g.tar.gz", | ||
# regal ignore:line-length | ||
"msg": `Package pkg:generic/[email protected]?download_url=https://openssl.org/source/openssl-1.1.0g.tar.gz fetched by cachi2 was sourced from "https://openssl.org/source/openssl-1.1.0g.tar.gz" which is not allowed`, | ||
}} | ||
|
||
att := json.patch(_sbom_attestation, [ | ||
{ | ||
"op": "add", | ||
"path": "/statement/predicate/components/-", | ||
"value": { | ||
"type": "file", | ||
"name": "openssl", | ||
"purl": "pkg:generic/[email protected]?download_url=https://openssl.org/source/openssl-1.1.0g.tar.gz", | ||
"properties": [{ | ||
"name": "cachi2:found_by", | ||
"value": "cachi2", | ||
}], | ||
"externalReferences": [{"type": "distribution", "url": "https://openssl.org/source/openssl-1.1.0g.tar.gz"}], | ||
}, | ||
}, | ||
{ | ||
"op": "add", | ||
"path": "/statement/predicate/components/-", | ||
"value": { | ||
"type": "library", | ||
"name": "batik-anim", | ||
"purl": "pkg:maven/org.apache.xmlgraphics/[email protected]?type=pom", | ||
"properties": [{ | ||
"name": "cachi2:found_by", | ||
"value": "cachi2", | ||
}], | ||
# regal ignore:line-length | ||
"externalReferences": [{"type": "distribution", "url": "https://repo.maven.apache.org/maven2/org/apache/xmlgraphics/batik-anim/1.9.1/batik-anim-1.9.1.pom"}], | ||
}, | ||
}, | ||
{ | ||
"op": "add", | ||
"path": "/statement/predicate/components/-", | ||
"value": { | ||
"type": "file", | ||
"name": "unrelated", | ||
"purl": "pkg:generic/unrelated", | ||
"externalReferences": [{"type": "distribution", "url": "https://irrelevant.org"}], | ||
}, | ||
}, | ||
]) | ||
|
||
lib.assert_equal_results(expected, sbom_cyclonedx.deny) with input.attestations as [att] | ||
with data.rule_data as {sbom.rule_data_allowed_package_sources_key: [ | ||
{ | ||
"type": "maven", | ||
"patterns": [".*apache.org.*", ".*example.com.*"], | ||
}, | ||
{ | ||
"type": "generic", | ||
"patterns": [".*apache.org.*", ".*example.com.*"], | ||
}, | ||
]} | ||
} | ||
|
||
test_allowed_package_sources_no_rule_defined if { | ||
expected := {{ | ||
"code": "sbom_cyclonedx.allowed_package_sources", | ||
"term": "pkg:maven/org.apache.xmlgraphics/[email protected]?type=pom", | ||
# regal ignore:line-length | ||
"msg": `Package pkg:maven/org.apache.xmlgraphics/[email protected]?type=pom fetched by cachi2 was sourced from "https://repo.maven.apache.org/maven2/org/apache/xmlgraphics/batik-anim/1.9.1/batik-anim-1.9.1.pom" which is not allowed`, | ||
}} | ||
|
||
att := json.patch(_sbom_attestation, [{ | ||
"op": "add", | ||
"path": "/statement/predicate/components/-", | ||
"value": { | ||
"type": "library", | ||
"name": "batik-anim", | ||
"purl": "pkg:maven/org.apache.xmlgraphics/[email protected]?type=pom", | ||
"properties": [{ | ||
"name": "cachi2:found_by", | ||
"value": "cachi2", | ||
}], | ||
# regal ignore:line-length | ||
"externalReferences": [{"type": "distribution", "url": "https://repo.maven.apache.org/maven2/org/apache/xmlgraphics/batik-anim/1.9.1/batik-anim-1.9.1.pom"}], | ||
}, | ||
}]) | ||
|
||
# rule data is defined only for purl of type generic | ||
lib.assert_equal_results(expected, sbom_cyclonedx.deny) with input.attestations as [att] | ||
with data.rule_data as {sbom.rule_data_allowed_package_sources_key: [{ | ||
"type": "generic", | ||
"patterns": [".*example.com.*"], | ||
}]} | ||
} | ||
|
||
test_attributes_not_allowed_no_properties if { | ||
att := json.patch(_sbom_attestation, [{ | ||
"op": "remove", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the
rule_data_errors
rules above. Let's add a new one that verifies the consistency of this new rule data key. This helps us determine if the rule data provided has any problems.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Holding out on this until the the comment about rule data format is settled.