-
Notifications
You must be signed in to change notification settings - Fork 7
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
Enhance Grant Rule to Exclude Packages with "No License" #176
Comments
+1 vote for this. Thank you! Some addition for this topic: In case there would be a possibility to catch the "no license" packages with the rules and deny them, the return code should be obviously non-zero. Our use case: We would like to use grant for a set of projects with a "central" config file containing the generic policies. This policy would deny packages with "no license found". Since the projects differ significantly, we would like to use a local, project-specific config file for the exceptions, mainly for packages without licensing info (in-house libraries or else). Possibly managed by the developer teams. The central and local config could be then merged during execution: We would really appreciate if this case could be covered as well. Thank you! |
Thanks @andrasszalai and @markussiebert - I'm currently over in Syft updating some of the license content options in the SBOM, but I'll try to carve out some time this week to get this enhancement in. Current work is plumbing the |
👋 - just to let you guys know I didn't forget this one and have been working on it in the background: Grant v0.3.0When the request came in for excluding packages with no license it looked like a quick weekend task to add a top level config and get it all working. After thinking more about it and trying a few different designs grant has been given a rather large design upgrade going into v0.3.0. Component Analysis, Constraints and New Rule TypesRules can now use their rules:
# License Rule: Deny all GPL licenses
- name: "Deny all Licenses"
kind: "license" # ✅ Explicitly a LicenseRule
reason: "Licenses are not permitted in this project unless configured with a specific allow rule"
glob: "*"
mode: "deny"
severity: "high"
#License Rule: Allow only permissive licenses for dependencies
- name: "Allow Only Permissive Licenses for Dependencies"
kind: "license"
reason: "All licenses must be permissive licenses"
glob: "*"
mode: "allow"
severity: "medium"
constraints:
- type: "license_group" # ✅ Uses LicenseGroupConstraint
allowed_groups: ["Permissive"] # ❌ Deny copyleft/proprietary licenses
# Component Rule: Deny components if unlicensed
- name: "Deny any component if unlicensed"
kind: "component" # ✅ Explicitly a ComponentRule
reason: "Unlicensed components are not allowed when shipping to production"
glob: "*"
mode: "deny"
severity: "critical"
constraints:
- type: "license_requirement" # ✅ Uses LicenseRequirementConstraint
requirement: "none" # ❌ Deny only if component has NO license
# Component Rule: Deny all outdated OpenSSL versions
- name: "Deny OpenSSL <1.1.1"
kind: "component"
reason: "Older versions of OpenSSL are not secure"
glob: "openssl"
mode: "deny"
severity: "critical"
constraints:
- type: "version" # ✅ Uses VersionConstraint
constraint: ">=1.1.1 <2.0.0" # ❌ Deny anything outside this range We've augmented rules to be able to pull from a short list of new optional constraints:
In the above we have examples of each, but let's cover the example where we create a deny Previous top level configs like Grant API and EvaluationsWith the new update grant I'll post the branch tomorrow as I still have a bit of rebuilding to do after adding constraints onto rules at the core of the application. I think this kind of flexibility should help us extend the program moving forward as SBOM documents add more and more things they can catalog. Notable Breaking changes:
|
I've iterated on the config a bit more to give us more options for the new behavior. Adding this here to provide more options for ergonomics. This new design achieves more simplicity in the config for rules. It also offers the ability to extend/inherit from an org wide policy. Finally it adds an Note the following examples can be inverted to switch the default behavior and specific lists as deny/allows Simple casesSimple: deny licenses while opening some gates for allowCan be inverted to default allow with specific deny policy:
licenses:
default_behavior: "deny" # ❌ Deny all licenses unless explicitly allowed
allow:
- "MIT" # ✅ Allow MIT license
- "Apache-2.0" # ✅ Allow Apache 2.0 license
- "*BSD*" # ✅ Allow all BSD-style licenses (e.g., BSD-2-Clause, BSD-3-Clause, etc.) Simple: allow components while denying specific patterns and version constraints/rangesCan be inverted to default deny with specific allow policy:
components:
default_behavior: "allow" # ✅ Allow all components unless explicitly denied
deny:
- "*log4j*" # ❌ Deny all Log4j versions
- "openssl<1.1.1" # ❌ Deny OpenSSL if version is below 1.1.1
- "nginx>=1.18.0,<1.20.0" # ❌ Deny Nginx versions between 1.18.0 and 1.20.0 Combined with org wide inheritancepolicy:
extends: "org-policy.yaml" # ✅ (Optional) Inherit from an organization-wide policy
licenses:
default_behavior: "deny" # ❌ Deny all licenses unless explicitly allowed
allow:
- "MIT" # ✅ Allow MIT license
- "Apache-2.0" # ✅ Allow Apache 2.0 license
- "*BSD*" # ✅ Allow all BSD-style licenses (e.g., BSD-2-Clause, BSD-3-Clause, etc.)
components:
default_behavior: "allow" # ✅ Allow all components unless explicitly denied
deny:
- "*log4j*" # ❌ Deny all Log4j versions
- "openssl<1.1.1" # ❌ Deny OpenSSL if version is below 1.1.1
- "nginx>=1.18.0,<1.20.0" # ❌ Deny Nginx versions **between 1.18.0 and 1.20.0** EnforceAdding an policy:
components:
enforce:
license: true # ✅ Require a license for all components (global) policy:
licenses:
enforce:
spdx: true # ✅ Require licenses to only be part of the official SPDX list
osi: true # subset of SPDX are osi: y and can be optionally applied on top of SPDX A small tension exists when we try to reconcile between the different Take the following example: Enforce block for allow components, but require them to have a licensepolicy:
components:
enforce:
license: true # ✅ Require a license for all components (global)
default_behavior: "allow" ✅ Allow all components outside of the enforce block requirements Enforce block for allow components, but require them to have a licensepolicy:
components:
enforce:
license: true # ✅ Require a license for all components (global)
default_behavior: "deny" ✅ Allow all components outside of the enforce block requirements Here is a table that outlines what I interpret as the correct behavior where Allow
Deny
Example where specific rules can make exceptions for the globalEnforce block with a deny defult; The allow list has an exception for a package we know has no license, but we want to passpolicy:
components:
enforce:
license: true # ✅ Require a license for all components (global)
default_behavior: "deny" ✅ Allow all components outside of the enforce block requirements
allow:
- "*nginx*" <--- enforce will catch this and deny if it's unlicensed
- pattern: "allowed-unlicense"
enforce:
license: false Example where different rules have just a pattern VS more complex fieldscomponent:
enforce:
licensed: true # ✅ Require component is licensed
not_eol: true # ✅ Require component is not eol
default_behavior: "allow"
deny:
- "*log4j*"
- pattern: "*wordpress*"
severity: "critical"
name: "we want to deny anything from wordpress"
reason: "legal said no" |
Thank you, that looks promising. Once you have some code to try out the behavior, I would like to give it a try. |
We are currently introducing Grant, and I’d love to have this configuration flexibility! 👍 @spiffcs I'm not entirely sure if your concept fully aligns with our needs since we have in-house libraries that are not licensed. It would be great to adjust the component definition to account for this.
Rather than using a |
Code coming soon. We had some internal discussions about the config and came to a conclusion that now looks like this. I've had to do some big refactors around my original prototype branch, but code coming soon now! policy:
components:
allow: all
deny:
- license: missing
- "*log4j*" # ❌ Deny all Log4j versions
- name: "openssl" # ❌ Deny OpenSSL if version is below 1.1.1
version: "<1.1.1"
- name: nginx # ❌ Deny Nginx versions **between 1.18.0 and 1.20.0**
version: ">=1.18.0,<1.20.0"
ignore:
- github.com/anchore/syft
licenses:
deny: all
allow:
- MIT
- GPL-*
- groups: ["permissive", "copyleft", "osi", "spdx-v3.2", "spdx"] |
What would you like to be added:
It would be beneficial if the grant allowed defining a rule that matches "no license." Perhaps this should also be the default in the "deny all" rule.
Currently, there is the --show-packages option that lists the packages, but I haven’t found a way to exclude packages based on a specific rule.
Why is this needed:
At present, packages with "no license" slip through the "deny all" rule and I have not found a way to deny them with a custom rule. This might be intentional behavior, but it can be incorrect depending on definitions. "No license" can potentially mean that I am not permitted to use it. Currently, the grant does not recognize these cases.
The text was updated successfully, but these errors were encountered: