Write policy definitions
When you create SBOM policies, you define rules for open-source component usage based on criteria such as component name, version, license, PURL, and supplier.
The SCS module supports deny list and allow list policies. Your policy files can include both lists. This topic explains how to write rules for each list.
Deny list policies
Use deny list policies to block the use of specific components within your artifacts. If an artifact includes a component that is part of the deny list, the artifact's policy evaluation fails.
For example, you can block a specific version of a component that has known vulnerabilities or doesn't meet your security standards. By adding that version of the component to the deny_list
and enforcing the policy in your pipelines, any attempts to use this component version in your organization's artifacts will be blocked.
Your deny list rules can use any combination of the following attributes, in addition to the component name
:
supplier
license
version
purl
Allow list policies
Use allow list policies to define a list of approved licenses, suppliers, and PURLs. The allow list ensures that your artifacts only include components that meet your specifications, which can help mitigate security and compliance risks. When you enforce policies in your pipelines, if an artifact includes a component that is not included in the allow list, the attribute's policy evaluation fails. Policy evaluation will also fail if the attribute on which the policy is enforced is not present in the corresponding SBOM.
Using OPA policies
You can define OPA policy sets at project, org, and account levels. A typical SBOM policy set has three sections:
deny_list
: Rules for denying the use of components based on specified criteria.allow_list
: Rules for allowed licenses, suppliers, and PURLs.Enforcement Logic
: Don't edit this part. It provides policy examples and logic that ensures your policies are consistently enforced.
When writing SBOM OPA policies, select one of the sample policies from the Policy library and change only the deny_list
and allow_list
sections according to the rules you want to enforce.
Do not change anything below #### DO NOT CHANGE THE FOLLOWING SCRIPT ####
. The content below this comment line is required to consistently enforce your SBOM OPA policy rules.
When creating a policy set for SBOM, set the Entity Type to SBOM.
![Click to view full size image](/assets/images/sbom-opa-policy-set-c68f0fb2331101bd052d1fdb342ccfbc.png)
Sample policies
Harness has the following samples in the Policy Library to help you create rules for SBOM policy enforcement:
- SBOM - Allow list
- SBOM - Deny list
- SBOM - Allow and Deny list
Here is an example of a sample policy:
package sbom
import future.keywords.if
import future.keywords.in
#### DEFINE YOUR DENY RULES BELOW ####
deny_list := fill_default_deny_rules([
{
"name": {"value": "curl", "operator": "=="},
"version": {"value": "3.0.0", "operator": "<="},
},
{
"name": {"value": ".*log4j.*", "operator": "~"},
"version": {"value": "3.0.0", "operator": "<"},
},
])
#### DEFINE YOUR ALLOW RULES BELOW ####
allow_list := {
"licenses": [
{"license": {
"value": "MIT",
"operator": "==",
}},
{"license": {
"value": ".*Apache.*",
"operator": "~",
}},
],
"suppliers": [{"supplier": {
"value": ".*Red Hat.*",
"operator": "~",
}}],
}
#### DO NOT CHANGE THE FOLLOWING SCRIPT ####
does_violate_license(pkg, rules) if {
some package_license in pkg.packageLicense
not does_match_license(package_license, rules)
}
does_match_license(license, rules) if {
some rule in rules
str_compare(license, rule.license.operator, rule.license.value)
}
...........
Supported Operators
In this section you can find the opreators supported by SBOM OPA policies
String Operators
- ==: Equal to
- !=: Not equal to
- ~: Pattern match
Examples:
- {"name":{"value":"abc","operator":"=="}}
Explanation: The package name is equal to abc.
- {"name":{"value":"abc","operator":"!="}}
Explanation: The package name is not equal to abc.
- {"name":{"value":"regex","operator":"~"}}
Explanation: The package name matches the regex pattern.
Version Operators
- ==: Equal to
- !=: Not equal to
- >: Greater than
- <: Less than
- >=: Greater than or equal to
- <=: Less than or equal to
- ><: In between
- >=<: In between (start inclusive)
- ><=: In between (end inclusive)
- >=<=: In between (start and end inclusive)
- ~: Pattern match
Examples:
- {"version":{"value":"1.2.3","operator":"=="}}
Explanation: The version is equal to 1.2.3.
- {"version":{"value":"1.2.3","operator":"!="}}
Explanation: The version is not equal to 1.2.3.
- {"version":{"value":"1.2.3","operator":">"}}
Explanation: The version is greater than 1.2.3.
- {"version":{"value":"1.2.3","operator":"<"}}
Explanation: The version is less than 1.2.3.
- {"version":{"value":"1.2.3","operator":">="}}
Explanation: The version is greater than or equal to 1.2.3.
- {"version":{"value":"1.2.3","operator":"<="}}
Explanation: The version is less than or equal to 1.2.3.
- {"version":{"value":"1.2,2.3.4","operator":"><"}}
Explanation: The version is greater than 1.2.3 and less than 2.3.4.
- {"version":{"value":"1.2,2.3.4","operator":">=<"}}
Explanation: The version is greater than or equal to 1.2.3 and less than 2.3.4.
- {"version":{"value":"1.2,2.3.4","operator":">=<="}}
Explanation: The version is greater than 1.2.3 and less than or equal to 2.3.4.
- {"version":{"value":"1.2,2.3.4","operator":">=<="}}
Explanation: The version is greater than or equal to 1.2.3 and less than or equal to 2.3.4.
- {"version":{"value":"1.2.3","operator":"~"}}
Explanation: The version matches the regex pattern.
Sample Rules
In this section, you can find examples of various rules that you can create for SBOM policy enforcement
Sample deny list rules
Block 'curl' below a Certain Version
Rule: "name": {"value": "curl", "operator": "=="}, "version": {"value": "3.0.0", "operator": "<="}
This rule blocks the usage of 'curl' if the version is 3.0.0 or lower.
Block Versions of 'log4j' using Regex
Rule: "name": {"value": ".*log4j.*", "operator": "~"}, "version": {"value": "3.0.0", "operator": "<"}
Targets any component matching the regex '.log4j.' that is below version 3.0.0.
Block 'busybot' Between Version 3.0.0 and 5.0.0
Rule: "name": {"value": "busybot", "operator": "=="}, "version": {"value": "3.0.0,5.0.0", "operator": "><"}
Prohibits the usage of 'busybot' for versions strictly between 3.0.0 and 5.0.0.
Block 'curl' at or Above a Certain Version
Rule: "name": {"value": "curl", "operator": "=="}, "version": {"value": "3.0.0", "operator": ">="}
Blocks 'curl' if its version is 3.0.0 or higher.
Block 'curl' Above a Certain Version
Rule: "name": {"value": "curl", "operator": "=="}, "version": {"value": "3.0.0", "operator": ">"}
Blocks 'curl' if its version is greater than 3.0.0.
Block 'curl' Except a Specific Version
Rule: "name": {"value": "curl", "operator": "=="}, "version": {"value": "3.0.0", "operator": "!"}
Blocks all versions of 'curl' except for 3.0.0.
Block Specific 'log4j' Version
Rule: "name": {"value": ".*log4j.*", "operator": "~"}, "version": {"value": "3.0.0", "operator": "=="}
Blocks the specific version 3.0.0 of any component matching '.log4j.'.
Block Components with Regex Pattern in Name
Rule: {"name": {"value": "c.*", "operator": "~"}}
Blocks any component whose name starts with 'c'.
Block Components with a Specific License
Rule: {"license": {"value": "BSD-3-Clause", "operator": "=="}}
Blocks components with the 'BSD-3-Clause' license.
Block Components Within a Version Range
Rule: {"version": {"value": "1.3.0,2.12.0", "operator": ">=<"}}
Targets components whose versions are greater than or equal to 1.3.0 and less than 2.12.0.
Block Components from a Specific Supplier
Rule: {"supplier": {"value": "Organization: Red Hat, Inc.", "operator": "=="}}
Blocks components supplied by "Red Hat, Inc."
Sample allow list rules
Allow list rules are grouped under licenses, suppliers or purls
Allow a list of licenses based on various criteria
Rule: "licenses": [ {"license": { "value": "MIT", "operator": "==", }}, {"license": { "value": ".*Apache.*", "operator": "~", }}, {"license": { "value": ".*eclipse.*", "operator": "~", }}, ],
This group of rules permits components based on their license types. The first rule explicitly allows components with the 'MIT' license. The next two rules use regex to allow any licenses containing 'Apache' or 'eclipse' in their names, respectively. This grouping ensures a broad but specific allowance based on license criteria.
Allow a list of suppliers
Rule: "suppliers": [{"supplier": { "value": ".*Red Hat.*", "operator": "~", }, { "value": ".*Apache.*", "operator": "~", }}],
These rules allow components from suppliers that include ‘Red Hat' or 'Apache’ in their names. The use of regex (~) allows for flexible matching to any supplier name that contains 'Red Hat', accommodating variations in naming.