Enterprise Policy Mgmt.
Enterprise Policy Manager: Rego Recipes
Recipe 1: Simple Tag Check
Use case: Match any package with a certain tag. For example: ready-for-production. For this rule, the value ofmatch will be true when any tag.name contains the value provided in required_tag.
package cloudsmith
required_tag := "ready-for-production"
default match := false
match if {
has_required_tag
}
has_required_tag if {
some i
input.v0["package"].tags[i].name == required_tag
}
Recipe 2: Time-Based CVSS Policy
Use case: Evaluate vulnerabilities older than 30 days, check CVSS threshold ≥ 7, filter a specific repo, ignoring certain CVEs.
What It Does:
- Scopes to the
testing-policyrepository. - Ignores certain CVEs, requires CVSS ≥ 7.
- Only triggers if vulnerability is older than 30 days.
package cloudsmith
max_cvss_score := 7
older_than_days := -30
target_repository := "testing-policy"
ignored_cves := {"CVE-2023-45853", "CVE-2024-12345"}
default match := false
match if {
in_target_repository
count(reason) != 0
}
in_target_repository if {
input.v0.repository.name == target_repository
}
reason contains msg if {
some scan in input.v0.security_scan
some vulnerability in scan.Vulnerabilities
not ignored_cve(vulnerability)
vulnerability.FixedVersion
vulnerability.Status == "fixed"
some val in vulnerability.CVSS
val.V3Score >= max_cvss_score
t := time.add_date(time.now_ns(), 0, 0, older_than_days)
published_date := time.parse_rfc3339_ns(vulnerability.PublishedDate)
published_date <= t
msg := sprintf(
"CVSS Score: %v | Package: %v | Vulnerability: %v | Reason: %v",
[val.V3Score, input.v0["package"].name, vulnerability.VulnerabilityID, vulnerability.Description],
)
}
ignored_cve(vulnerability) if {
vulnerability.VulnerabilityID in ignored_cves
}Recipe 3: CVSS Score + Fix Version + CVE Exclusion + Repo
Use case: Another approach for ignoring certain CVEs, focusing on one repository, with high/critical CVSS threshold.
What It Does:
- Matches packages in repository testing-policy if at least one vulnerability is “fixed,” CVSS > 7, and not in
ignored_cves.
package cloudsmith
max_cvss_score := 7
target_repository := "testing-policy"
ignored_cves := {"CVE-2023-45853"}
default match := false
match if {
input.v0.repository.name == target_repository
some scan in input.v0.security_scan
some vulnerability in scan.Vulnerabilities
vulnerability.FixedVersion
vulnerability.Status == "fixed"
not ignored_cve(vulnerability)
exceeded_max_cvss(vulnerability)
}
exceeded_max_cvss(vulnerability) if {
some val in vulnerability.CVSS
val.V3Score > max_cvss_score
}
ignored_cve(vulnerability) if {
vulnerability.VulnerabilityID in ignored_cves
}
Recipe 4: CVSS Score + Tag + Time-Based
Use case: Combine tag requirements with older vulnerabilities that surpass a threshold.
What It Does:
- Requires package to have a tag containing "internal-only"
- Only triggers if a vulnerability is older than 21 days, fixed, and has a CVSS ≥ 7.
package cloudsmith
customer_face_tag := "internal-only"
max_cvss_score := 7
default match := false
match if {
has_given_tag
count(reason) != 0
}
has_given_tag if {
some tag in input.v0["package"].tags
contains(tag.name, customer_face_tag)
}
reason contains msg if {
t := time.add_date(time.now_ns(), 0, 0, -21)
some scan in input.v0.security_scan
some vulnerability in scan.Vulnerabilities
published_date := time.parse_rfc3339_ns(vulnerability.PublishedDate)
published_date <= t
vulnerability.FixedVersion
vulnerability.Status == "fixed"
some val in vulnerability.CVSS
val.V3Score >= max_cvss_score
msg := sprintf(
"CVSS Score: '%v' for Package: '%v' has VulnerabilityID: '%v' with Reason: '%v'",
[val.V3Score, input.v0["package"].name, vulnerability.VulnerabilityID, vulnerability.Description],
)
}
Recipe 5: Compare software package license to a list of copyleft licenses
Use case: Check whether a software package's license is a copyleft license.
What It Does:
- Defines a set of known copyleft SPDX identifiers.
- Triggers if the package's license SPDX identifier matches any of those copyleft licenses.
package cloudsmith
default match := false
# GNU General Public License (GPL) variants
gpl_licenses := {
"GPL-1.0-only",
"GPL-1.0-or-later",
"GPL-2.0",
"GPL-2.0-only",
"GPL-2.0-or-later",
"GPL-3.0",
"GPL-3.0-only",
"GPL-3.0-or-later",
}
# GNU Lesser General Public License (LGPL) variants
lgpl_licenses := {
"LGPL-2.0",
"LGPL-2.0-only",
"LGPL-2.0-or-later",
"LGPL-2.1",
"LGPL-2.1-only",
"LGPL-2.1-or-later",
"LGPL-3.0",
"LGPL-3.0-only",
"LGPL-3.0-or-later",
}
# GNU Affero General Public License (AGPL) variants
agpl_licenses := {
"AGPL-1.0",
"AGPL-1.0-only",
"AGPL-1.0-or-later",
"AGPL-3.0",
"AGPL-3.0-only",
"AGPL-3.0-or-later",
}
# Mozilla Public License (MPL) variants
mpl_licenses := {
"MPL-1.0",
"MPL-1.1",
"MPL-2.0",
}
# Common Development and Distribution License (CDDL) variants
cddl_licenses := {
"CDDL-1.0",
"CDDL-1.1",
}
# Eclipse Public License (EPL) variants
epl_licenses := {
"EPL-1.0",
"EPL-2.0",
}
# Open Software License (OSL) variants
osl_licenses := {
"OSL-1.0",
"OSL-2.0",
"OSL-3.0",
}
# GNU Free Documentation License (GFDL) variants
gfdl_licenses := {
"GFDL-1.1-only",
"GFDL-1.1-or-later",
"GFDL-1.2-only",
"GFDL-1.2-or-later",
"GFDL-1.3-only",
"GFDL-1.3-or-later",
}
# Creative Commons Share Alike (CC-BY-SA) variants
cc_by_sa_licenses := {
"CC-BY-SA-1.0",
"CC-BY-SA-2.0",
"CC-BY-SA-2.5",
"CC-BY-SA-3.0",
"CC-BY-SA-4.0",
}
# Other copyleft licenses
other_copyleft_licenses := {
"QPL-1.0",
"Sleepycat",
"SSPL-1.0",
"copyleft-next-0.3.0",
}
# Combined copyleft license set
copyleft := gpl_licenses | lgpl_licenses | agpl_licenses | mpl_licenses | cddl_licenses | epl_licenses | osl_licenses | gfdl_licenses | cc_by_sa_licenses | other_copyleft_licenses
# Main policy rule
match if {
input.v0.package.license.oss_license.spdx_identifier in copyleft
}Recipe 6: Detect malicious packages
Use case: Check if a package was part of a supply chain attack.
package cloudsmith
default match := false
match if count(malicious_packages) > 0
malicious_packages := [vulnerability.id |
some vulnerability in input.v0.osv
startswith(vulnerability.id, "MAL-")
]Recipe 7: Detect non-compliant licenses used in a Docker image
Use case: Check whether any components or transitive dependencies of a Docker image have a copyleft license.
What It Does:
- Defines a set of known copyleft SPDX identifiers.
- Triggers if any component of the Docker image has a copyleft license.
package cloudsmith
import rego.v1
default match := false
# Match components with copyleft SPDX licenses
# Comprehensive list of copyleft licenses from https://spdx.org/licenses/
# GNU General Public License (GPL) variants
gpl_licenses := {
"GPL-1.0-only",
"GPL-1.0-or-later",
"GPL-2.0",
"GPL-2.0-only",
"GPL-2.0-or-later",
"GPL-3.0",
"GPL-3.0-only",
"GPL-3.0-or-later",
}
# GNU Lesser General Public License (LGPL) variants
lgpl_licenses := {
"LGPL-2.0",
"LGPL-2.0-only",
"LGPL-2.0-or-later",
"LGPL-2.1",
"LGPL-2.1-only",
"LGPL-2.1-or-later",
"LGPL-3.0",
"LGPL-3.0-only",
"LGPL-3.0-or-later",
}
# GNU Affero General Public License (AGPL) variants
agpl_licenses := {
"AGPL-1.0",
"AGPL-1.0-only",
"AGPL-1.0-or-later",
"AGPL-3.0",
"AGPL-3.0-only",
"AGPL-3.0-or-later",
}
# Mozilla Public License (MPL) variants
mpl_licenses := {
"MPL-1.0",
"MPL-1.1",
"MPL-2.0",
}
# Common Development and Distribution License (CDDL) variants
cddl_licenses := {
"CDDL-1.0",
"CDDL-1.1",
}
# Eclipse Public License (EPL) variants
epl_licenses := {
"EPL-1.0",
"EPL-2.0",
}
# Open Software License (OSL) variants
osl_licenses := {
"OSL-1.0",
"OSL-2.0",
"OSL-3.0",
}
# GNU Free Documentation License (GFDL) variants
gfdl_licenses := {
"GFDL-1.1-only",
"GFDL-1.1-or-later",
"GFDL-1.2-only",
"GFDL-1.2-or-later",
"GFDL-1.3-only",
"GFDL-1.3-or-later",
}
# Creative Commons Share Alike (CC-BY-SA) variants
cc_by_sa_licenses := {
"CC-BY-SA-1.0",
"CC-BY-SA-2.0",
"CC-BY-SA-2.5",
"CC-BY-SA-3.0",
"CC-BY-SA-4.0",
}
# Other copyleft licenses
other_copyleft_licenses := {
"QPL-1.0",
"Sleepycat",
"SSPL-1.0",
"copyleft-next-0.3.0",
}
# Combined copyleft license set
copyleft := gpl_licenses | lgpl_licenses | agpl_licenses | mpl_licenses | cddl_licenses | epl_licenses | osl_licenses | gfdl_licenses | cc_by_sa_licenses | other_copyleft_licenses
match if {
input.v0.sbom != null
component := input.v0.sbom.components[_]
component.licenses != null
license_entry := component.licenses[_]
license_entry.license != null
license_id := license_entry.license.id
license_id in copyleft
}Recipe 8: Compare package versions
Use case: Match any package with a specific version range.
What It Does:
- Evaluates the version of a package against a specified package version.
- Triggers if the version of the current package being evaluated is older than the specified package version.
package cloudsmith
default match := false
match if count(reason) > 0
reason contains msg if {
pkg := input.v0.package
pkg.name == "h11"
# Parse versions using Cloudsmith's semantic version comparator
semver.compare(pkg.version, "0.16.0") == -1
msg := sprintf("Package 'h11' version '%s' is older than 0.16.0", [pkg.version])
}Recipe 9: Package Publish Date
Use case: Match new packages for a specific period (e.g. two weeks) after release. Enforcing a time lag before consuming a new package or package version is an effective safeguard to protect against zero-day attacks.
Package publish date is currently only available for npm.
What It Does:
- Evaluates the publish date of your NPM package.
- Triggers if your NPM package was published within the past 14 days.
package cloudsmith
default match := false
# A package is matched if its upstream publish date is within the past N days.
within_past_days := 14
supported_formats := {"npm"}
match if count(reason) != 0
reason contains msg if {
pkg := input.v0.package
within_past_days_date := time.add_date(time.now_ns(), 0, 0, 0 - within_past_days)
publish_date := time.parse_rfc3339_ns(pkg.upstream_metadata.published_at)
# Match if the publish date comes after the date of the set number of days ago.
publish_date >= within_past_days_date
pkg.format in supported_formats
msg := sprintf("Package upstream publish date is %v (falls within the past %v days)", [pkg.upstream_metadata.published_at, within_past_days])
}