Turning complex policies into custom Advisories using Open Policy Agent
As well as the inbuilt functionality to flag Advisories in your software, dependency-management-data provides the ability to write your own custom advisories, which can also be shared as part of the -contrib project.
Although very useful, they lack the ability to perform much more complex rules against dependencies.
Since dependency-management-data v0.54.0, it is possible to use Open Policy Agent's Policy Language, Rego to write much more complex advisories, also called Policies.
Requirements
The following technical requirements are true for writing an OPA policy:
- The
package
must be set topolicy
- There may be a string variable,
msg
, which indicates why the violation has occurred. This is a user-facing description, so add as much detail as would be useful to diagnose, including links to supporting documentation - There must be a variable,
deny
orwarn
:- The variable
deny
, which indicates whether there should be a policy violation flagged for the given dependency. Not settingdeny
means no violation will occur. Setting thedeny
variable to contain the value ofmsg
(or a hardcoded error message) results in a violation. See below for more details - The variable
warn
, which indicates whether there should be a policy warning flagged for the given dependency. Not settingwarn
means no violation will occur. Setting thewarn
variable to contain the value ofmsg
(or a hardcoded error message) results in a warning. See below for more details
- The variable
- There must be a string variable
advisory_type
, which indicates the Advisory type, which aligns with one of the types from the underlying database. The default isPOLICY
, but can be adjusted to point to a more appropriate Advisory type by explicitly setting theadvisory_type
variable - Each
.rego
file must be its own standalone policy
As of dependency-management-data v0.55.0, linting will occur when running dmd policy evaluate
command, or can be run ad-hoc with dmd policy lint
command.
With that in mind, the following is a good starting point for fresh policies:
package policy
import rego.v1
# can be any value that matches one of the valid `advisory_type`s in https://dmd.tanna.dev/schema/#internaladvisorydbschemasql
# if not set, will default to `POLICY`
default advisory_type := "POLICY"
deny contains msg if {
false
msg := "This will deny the dependency"
}
warn contains msg if {
false
msg := "This will warn about the usage of the dependency"
}
Flagging a violation
package policy
import rego.v1
deny contains "This will trigger a violation, and set the respective error message as this string"
No violation
package policy
import rego.v1
default deny := []
default advisory_type := "UNMAINTAINED"
Flagging a warning
package policy
import rego.v1
warn contains msg if {
some license in input.dependency.licenses
license in ["non-standard"]
msg := sprintf("Dependency uses a non-standard license (%s)", [license])
}
Input data
When creating an OPA Policy, you'll receive consistently-formatted input data. For more detail, you can see field-level documentation on pkg.go.dev.
From DMD v0.102.0, only the data you query in your Policy will be retrieved from the database, providing much improved performance.
For instance, if we had the following rows from the sboms
table:
platform | organisation | repo | package_name | version | current_version | package_type |
---|---|---|---|---|---|---|
github | deepmap | oapi-codegen | github.com/stretchr/testify | 1.8.4 | 1.8.4 | golang |
Then we would receive the following input:
{
"project": {
"organisation": "deepmap",
"platform": "github",
"repo": "oapi-codegen"
},
"dependency": {
"current_version": "1.8.4",
"dep_types": [],
"package_file_path": "",
"package_manager": "golang",
"package_name": "github.com/stretchr/testify",
"version": "1.8.4",
"licenses": [
]
}
}
And from the renovate
table:
platform | organisation | repo | package_name | version | current_version | package_manager | package_file_path | datasource | dep_types |
---|---|---|---|---|---|---|---|---|---|
github | deepmap | oapi-codegen | github.com/stretchr/testify | v1.8.4 | v1.8.4 | gomod | internal/test/go.mod | go | ["require"] |
Then we would receive the following input:
{
"project": {
"organisation": "deepmap",
"platform": "github",
"repo": "oapi-codegen"
},
"dependency": {
"current_version": "v1.8.4",
"dep_types": ["require"],
"package_file_path": "internal/test/go.mod",
"package_manager": "gomod",
"package_name": "github.com/stretchr/testify",
"version": "v1.8.4",
"licenses": [
]
}
}
Licensing data
If you have generated licensing information via dmd db generate advisories
command, you can access that data in your OPA policy.
For instance, if the depsdev_licenses
table contains the following data:
package_name | version | license | updated_at |
---|---|---|---|
github.com/stretchr/testify | v1.8.4 | MIT | 2023-11-23T10:52:19Z |
You will then receive the following input:
{
"project": {
"organisation": "deepmap",
"platform": "github",
"repo": "oapi-codegen"
},
"dependency": {
"current_version": "v1.8.4",
"dep_types": ["require"],
"package_file_path": "internal/test/go.mod",
"package_manager": "gomod",
"package_name": "github.com/stretchr/testify",
"version": "v1.8.4",
"licenses": [
"MIT"
]
}
}
Note that not every package may have a license. In this case, you will receive the following input - note the empty dependency.licenses
array:
{
"project": {
"organisation": "deepmap",
"platform": "github",
"repo": "oapi-codegen"
},
"dependency": {
"current_version": "v1.8.4",
"dep_types": ["require"],
"package_file_path": "internal/test/go.mod",
"package_manager": "gomod",
"package_name": "github.com/stretchr/testify",
"version": "v1.8.4",
"licenses": [
]
}
}
Repository metadata
If you're taking advantage of the ability to store repository_metadata
, you will be able to leverage the data as part of policies.
For instance, if you have the following repository metadata:
platform | organisation | repo | is_monorepo | is_fork | repository_type | repository_usage | visibility | description | additional_metadata |
---|---|---|---|---|---|---|---|---|---|
github | deepmap | oapi-codegen | false | false | TOOL | TOOL LIBRARY | PUBLIC | {"last_push":"2024-01-12T04:44:23Z","stability":"stable"} |
You will then receive the following input:
{
"project": {
"organisation": "deepmap",
"platform": "github",
"repo": "oapi-codegen",
"metadata": {
"is_monorepo": false,
"is_fork": false,
"repository_type": "TOOL",
"repository_usage": "TOOL LIBRARY",
"visibility": "PUBLIC",
"additional_metadata": {
"last_push": "2024-01-12T04:44:23Z",
"stability": "stable"
}
}
},
"dependency": {
"current_version": "v1.8.4",
"dep_types": ["require"],
"package_file_path": "internal/test/go.mod",
"package_manager": "gomod",
"package_name": "github.com/stretchr/testify",
"version": "v1.8.4",
"licenses": [
]
}
}
Note that not every package may have repository metadata. In this case, you will receive the following input - note that project.metadata
is absent:
{
"project": {
"organisation": "deepmap",
"platform": "github",
"repo": "oapi-codegen"
},
"dependency": {
"current_version": "v1.8.4",
"dep_types": ["require"],
"package_file_path": "internal/test/go.mod",
"package_manager": "gomod",
"package_name": "github.com/stretchr/testify",
"version": "v1.8.4",
"licenses": [
]
}
}
Dependency health data
If you have fetched dependency health data via dmd db generate dependency-health
, then you may have collected health metadata around your dependencies into the dependency_health
table:
package_name | package_manager | scorecard_score | scorecard_codereview | scorecard_maintained | scorecard_ciibestpractices | scorecard_license | scorecard_dangerousworkflow | scorecard_packaging | scorecard_tokenpermissions | scorecard_signedreleases | scorecard_branchprotection | scorecard_binaryartifacts | scorecard_fuzzing | scorecard_securitypolicy | scorecard_sast | scorecard_vulnerabilities | scorecard_pinneddependencies | ecosystems_repo_archived | ecosystems_repo_pushed_at | ecosystems_repo_updated_at | ecosystems_repo_last_synced_at | ecosystems_last_synced_at | ecosystems_latest_release_published_at | ecosystems_status |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@codemirror/history | npm | 3.40000009536743 | 0 | 0 | 0 | 10 | 10 | -1 | 0 | -1 | 0 | 10 | 0 | 0 | 0 | 10 | 0 | 1 | 2022-02-16T16:57:16.000Z | 2024-01-16T20:35:36.300Z | 2024-01-16T20:35:36.299Z | 2024-01-17T01:45:03Z | 2022-01-03T13:52:35Z |
This would result in input of the form:
{
"project": {
"platform": "github",
"organisation": "DDDEastMidlandsLimited",
"repo": "dddem-blog"
},
"dependency": {
"package_name": "@codemirror/history",
"version": "0.18.1",
"current_version": "0.18.1",
"package_manager": "npm",
"package_file_path": "package.json",
"dep_types": [
"lockfile"
],
"licenses": [
],
"health": {
"ecosystems": {
"last_synced_at": "2024-01-17T01:45:03Z",
"latest_release_published_at": "2022-01-03T13:52:35Z",
"repo": {
"archived": true,
"last_synced_at": "2024-01-16T20:35:36.299Z",
"pushed_at": "2022-02-16T16:57:16.000Z",
"updated_at": "2024-01-16T20:35:36.300Z"
}
},
"security_scorecard": {
"score": 3.4000000953674316,
"binary_artifacts": 10,
"branch_protection": 0,
"cii_best_practices": 0,
"code_review": 0,
"dangerous_workflow": 10,
"fuzzing": 0,
"license": 10,
"maintained": 0,
"packaging": -1,
"pinned_dependencies": 0,
"sast": 0,
"security_policy": 0,
"signed_releases": -1,
"token_permissions": 0,
"vulnerabilities": 10
}
}
}
}
If a dependency does not have any dependency health information available, the health
field will be absent.
A number of these fields are optional, and can be found further documented in the field-level documentation on pkg.go.dev.
Pre-filtering the data
From DMD v0.102.0, only the data you query in your Policy will be retrieved from the database, providing much improved performance.
As well as this, you can pre-filter the data using a number of directives, which are defined through comments in your Policies.
These can be found defined in a comment, of the form:
# DMD: <DIRECTIVE>: <ARGUMENTS>
filter
directive
By using the filter
directive, you can further pre-filter the data before it is passed into your Policy, which further improves performance of the overall evaluations.
This should be used in addition to any if
statements in your Policies to match Advisories to your dependencies.
It is currently possible to filter on the following fields:
package_name
package_type
These can be found defined in a comment, of the form:
# DMD: filter: <FIELD>: <ARGUMENT>
For instance, if we had the following Policy:
package policy
# DMD: filter: package_name: *oapi-codegen*
# DMD: filter: package_name: */huma
# DMD: filter: package_type: golang
This would pre-filter the data in DMD to only Go dependencies whose package name include the term oapi-codegen
or end with /huma
.
Alternatively, this statement when written as SQL:
SELECT
...
FROM
...
WHERE
(
package_name LIKE '%oapi-codegen%'
OR
package_name LIKE '%/huma'
)
AND
(
package_type LIKE 'golang'
)
Testing out policies
You can use the dmd policy evaluate
command to evaluate a policy, giving you the opportunity to understand the impact it may have when applied.
Below you can find example policies, and the result that using dmd policy evaluate
would bring, based on the example project's data.
Once you've written the policies, you'll then need to process + persist them.
Example: Flagging use of legacy GitLab server repositories
Let's say that as an organisation you're moving from a self-hosted GitLab server to GitLab.com, and want to find all usages of the old package URLs.
To do this, we could craft the following policy.rego
:
package policy
import rego.v1
default advisory_type := "UNMAINTAINED"
deny contains "Use the new GitLab.com server" if startswith(input.dependency.package_name, "gitlab.example.com/")
With this applied, we can then run the policy evaluate
command:
dmd policy evaluate --db /path/to/dmd.db policy.rego
This will then print out, for instance:
Processing policy.rego resulted in 10 policy violations, from ... dependencies:
+----------+--------------+---------------------------------------+-----------------------------------------------+-----------+------------------+-------------------+---------------+-------------------------------+
| PLATFORM | ORGANISATION | REPO | PACKAGE | VERSION | DEPENDENCY TYPES | FILEPATH | ADVISORY TYPE | DESCRIPTION |
+----------+--------------+---------------------------------------+-----------------------------------------------+-----------+------------------+-------------------+---------------+-------------------------------+
| github | ........ | ............... | gitlab.example.com/.......... | ........ | [] | go.mod | UNMAINTAINED | Use the new GitLab.com server |
| | | | | | | | | |
+----------+--------------+---------------------------------------+-----------------------------------------------+-----------+------------------+-------------------+---------------+-------------------------------+
Example: Flagging use of bytedance/sonic
Let's say that you're working on applications that need to abide by US federal restrictions on the use of software produced by ByteDance.
If we wanted to:
- Flag uses of the Gin web framework that now include
bytedance/sonic
as a transitive dependency (since v1.9.0) - Flag uses of any Bytedance Go libraries, with additional checks based on whether it's a direct or indirect usage
- Work with both the
renovate
andsboms
Datasources
To do this, we could craft the following policy.rego
:
package policy
import rego.v1
default advisory_type := "POLICY"
prefix := "The US Federal government in June highlighted that usage of ByteDance software on government equipment or networks is prohibited (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), which may extend as far as Open Source projects they have produced."
default versions := []
# prefer the `version` with Go modules, as versions are always exactly pinned, and means we don't need to handle the absense of the `current_version` i.e. https://gitlab.com/tanna.dev/dependency-management-data/-/issues/77
versions := split(input.dependency.version, ".")
is_bytedance if {
input.dependency.package_manager in {"gomod", "golang"}
startswith(input.dependency.package_name, "github.com/bytedance/")
}
is_direct if {
input.dependency.package_manager in {"gomod", "golang"}
"require" in input.dependency.dep_types
}
is_indirect if {
input.dependency.package_manager in {"gomod", "golang"}
"indirect" in input.dependency.dep_types
}
deny contains msg if {
input.dependency.package_manager in {"gomod", "golang"}
input.dependency.package_name = "github.com/gin-gonic/gin"
versions[0] in {"v1", "1"}
to_number(versions[1]) >= 9
msg := sprintf("%s. Versions of Gin since v1.9.0 have shipped ByteDance/sonic as an optional dependency, but it still appears as a dependency, and could be in use - more details in https://github.com/gin-gonic/gin/issues/3653", [prefix])
}
deny contains msg if {
is_bytedance
is_direct
msg := sprintf("%s. This is an explicit use of a ByteDance-owned dependency", [prefix])
}
deny contains msg if {
is_bytedance
is_indirect
msg := sprintf("%s. This is a transitive use of a ByteDance-owned dependency", [prefix])
}
deny contains msg if {
is_bytedance
not is_direct
not is_indirect
msg := sprintf("%s. (Unclear whether a direct or transitive dependency)", [prefix])
}
With this applied, we can then run the policy evaluate
command:
dmd policy evaluate --db /path/to/dmd.db policy.rego
This will then print out, for instance:
Processing policy.rego resulted in 10 policy violations, from 129268 dependencies:
+----------+--------------+----------------+----------------------------+-------------+------------------+----------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
| PLATFORM | ORGANISATION | REPO | PACKAGE | VERSION | DEPENDENCY TYPES | FILEPATH | ADVISORY TYPE | DESCRIPTION |
+----------+--------------+----------------+----------------------------+-------------+------------------+----------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
| github | deepmap | oapi-codegen | github.com/bytedance/sonic | 1.10.0-rc3 | [] | | POLICY | The US Federal government in June highlighted that usage of |
| | | | | / | | | | ByteDance software on government equipment or networks is |
| | | | | 1.10.0-rc3 | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. (Unclear whether a direct or transitive |
| | | | | | | | | dependency) |
| github | deepmap | oapi-codegen | github.com/bytedance/sonic | v1.10.0-rc3 | [] | examples/go.mod | POLICY | The US Federal government in June highlighted that usage of |
| | | | | / | | | | ByteDance software on government equipment or networks is |
| | | | | v1.10.0-rc3 | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. (Unclear whether a direct or transitive |
| | | | | | | | | dependency) |
| github | deepmap | oapi-codegen | github.com/bytedance/sonic | v1.10.0-rc3 | [] | internal/test/go.mod | POLICY | The US Federal government in June highlighted that usage of |
| | | | | / | | | | ByteDance software on government equipment or networks is |
| | | | | v1.10.0-rc3 | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. (Unclear whether a direct or transitive |
| | | | | | | | | dependency) |
| github | deepmap | oapi-codegen | github.com/gin-gonic/gin | 1.9.1 / | [] | | POLICY | The US Federal government in June highlighted that usage of |
| | | | | 1.9.1 | | | | ByteDance software on government equipment or networks is |
| | | | | | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. Versions of Gin since v1.9.0 have shipped |
| | | | | | | | | ByteDance/sonic as an optional dependency, but it still |
| | | | | | | | | appears as a dependency, and could be in use - more details |
| | | | | | | | | in https://github.com/gin-gonic/gin/issues/3653 |
| github | deepmap | oapi-codegen | github.com/gin-gonic/gin | v1.9.1 / | [] | examples/go.mod | POLICY | The US Federal government in June highlighted that usage of |
| | | | | v1.9.1 | | | | ByteDance software on government equipment or networks is |
| | | | | | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. Versions of Gin since v1.9.0 have shipped |
| | | | | | | | | ByteDance/sonic as an optional dependency, but it still |
| | | | | | | | | appears as a dependency, and could be in use - more details |
| | | | | | | | | in https://github.com/gin-gonic/gin/issues/3653 |
| github | deepmap | oapi-codegen | github.com/gin-gonic/gin | v1.9.1 / | [] | internal/test/go.mod | POLICY | The US Federal government in June highlighted that usage of |
| | | | | v1.9.1 | | | | ByteDance software on government equipment or networks is |
| | | | | | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. Versions of Gin since v1.9.0 have shipped |
| | | | | | | | | ByteDance/sonic as an optional dependency, but it still |
| | | | | | | | | appears as a dependency, and could be in use - more details |
| | | | | | | | | in https://github.com/gin-gonic/gin/issues/3653 |
| github | oapi-codegen | gin-middleware | github.com/bytedance/sonic | v1.9.1 / | [] | go.mod | POLICY | The US Federal government in June highlighted that usage of |
| | | | | v1.9.1 | | | | ByteDance software on government equipment or networks is |
| | | | | | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. (Unclear whether a direct or transitive |
| | | | | | | | | dependency) |
| github | oapi-codegen | runtime | github.com/bytedance/sonic | v1.10.0-rc3 | [] | go.mod | POLICY | The US Federal government in June highlighted that usage of |
| | | | | / | | | | ByteDance software on government equipment or networks is |
| | | | | v1.10.0-rc3 | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. (Unclear whether a direct or transitive |
| | | | | | | | | dependency) |
| github | oapi-codegen | runtime | github.com/gin-gonic/gin | v1.9.1 / | [] | go.mod | POLICY | The US Federal government in June highlighted that usage of |
| | | | | v1.9.1 | | | | ByteDance software on government equipment or networks is |
| | | | | | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. Versions of Gin since v1.9.0 have shipped |
| | | | | | | | | ByteDance/sonic as an optional dependency, but it still |
| | | | | | | | | appears as a dependency, and could be in use - more details |
| | | | | | | | | in https://github.com/gin-gonic/gin/issues/3653 |
| github | oapi-codegen | gin-middleware | github.com/gin-gonic/gin | v1.9.1 / | [] | go.mod | POLICY | The US Federal government in June highlighted that usage of |
| | | | | v1.9.1 | | | | ByteDance software on government equipment or networks is |
| | | | | | | | | prohibited |
| | | | | | | | | (https://www.federalregister.gov/documents/2023/06/02/2023-11756/federal-acquisition-regulation-prohibition-on-a-bytedance-covered-application), |
| | | | | | | | | which may extend as far as Open Source projects they have |
| | | | | | | | | produced.. Versions of Gin since v1.9.0 have shipped |
| | | | | | | | | ByteDance/sonic as an optional dependency, but it still |
| | | | | | | | | appears as a dependency, and could be in use - more details |
| | | | | | | | | in https://github.com/gin-gonic/gin/issues/3653 |
+----------+--------------+----------------+----------------------------+-------------+------------------+----------------------+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
Example: Flagging uses of licenses
Let's say that as an organisation you want to flag the usage of licenses you'd prefer not to be used.
To do this, we could craft the following policy.rego
:
package policy
import rego.v1
deny contains msg if {
some license in input.dependency.licenses
license in ["AGPL-3.0", "non-standard"]
msg := sprintf("Dependency uses a Banned license (%s)", [license])
}
With this applied, we can then run the policy evaluate
command:
dmd policy evaluate --db /path/to/dmd.db policy.rego
This will then print out, for instance:
Processing licensing.rego resulted in 1593 policy violations, from 131070 dependencies, but as `--limit` was set to 10, only showing that many results:
+----------+------------------------+-------------------+-------------------------------------------------+-----------+---------------------------------------------+------------------+---------------+-------------------------------------------------+
| PLATFORM | ORGANISATION | REPO | PACKAGE | VERSION | DEPENDENCY TYPES | FILEPATH | ADVISORY TYPE | DESCRIPTION |
+----------+------------------------+-------------------+-------------------------------------------------+-----------+---------------------------------------------+------------------+---------------+-------------------------------------------------+
| github | DDDEastMidlandsLimited | dddem-web | regjsparser | ^0.1.4 / | ["lockfile","lockfile-yarn-pinning-^0.1.4"] | package.json | POLICY | Dependency uses a Banned license (non-standard) |
| | | | | 0.1.5 | | | | |
| github | IndiePass | indiepass-android | jakarta.activation:jakarta.activation-api | 1.2.1 / | ["dependencies","missing-data"] | build.gradle | POLICY | Dependency uses a Banned license (non-standard) |
| | | | | 1.2.1 | | | | |
| github | IndiePass | indiepass-android | jakarta.xml.bind:jakarta.xml.bind-api | 2.3.2 / | ["dependencies","missing-data"] | build.gradle | POLICY | Dependency uses a Banned license (non-standard) |
| | | | | 2.3.2 | | | | |
| github | IndiePass | indiepass-android | javax.annotation:javax.annotation-api | 1.3.2 / | ["dependencies","missing-data"] | build.gradle | POLICY | Dependency uses a Banned license (non-standard) |
| | | | | 1.3.2 | | | | |
| github | alphagov | pay-publicapi | com.google.auth:google-auth-library-credentials | 1.10.0 / | ["test","missing-data"] | pom.xml | POLICY | Dependency uses a Banned license (non-standard) |
| | | | | 1.10.0 | | | | |
| github | IndiePass | indiepass-android | org.bouncycastle:bcprov-jdk15on | 1.67 / | ["dependencies","missing-data"] | build.gradle | POLICY | Dependency uses a Banned license (non-standard) |
| | | | | 1.67 | | | | |
| github | IndiePass | indiepass-android | org.glassfish.jaxb:txw2 | 2.3.2 / | ["dependencies","missing-data"] | build.gradle | POLICY | Dependency uses a Banned license (non-standard) |
| | | | | 2.3.2 | | | | |
| github | IndiePass | indiepass-android | org.hamcrest:hamcrest-core | 2.2 / 2.2 | ["dependencies","missing-data"] | app/build.gradle | POLICY | Dependency uses a Banned license (non-standard) |
| github | IndiePass | indiepass-android | org.hamcrest:hamcrest-library | 1.3 / 1.3 | ["dependencies","missing-data"] | app/build.gradle | POLICY | Dependency uses a Banned license (non-standard) |
| github | alphagov | pay-connector | antlr:antlr | 2.7.7 / | ["test","missing-data"] | pom.xml | POLICY | Dependency uses a Banned license (non-standard) |
| | | | | 2.7.7 | | | | |
+----------+------------------------+-------------------+-------------------------------------------------+-----------+---------------------------------------------+------------------+---------------+-------------------------------------------------+
Example: Checking End-Of-Life status using endoflife.date
As noted in Dynamically querying EndOfLife.date data for internal packages with Open Policy Agent and Dependency Management Data, we could write the following Policy:
package policy
import rego.v1
days_until_warn := 60
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# below is for the Policy author to determine, as it's dependency specific
version := split(input.dependency.current_version, "-")[0]
versions := split(version, ".")
default cycle := null
cycle := sprintf("%s.%s", [versions[0], versions[1]])
default the_product := null
# DMD: filter: package_name: docker.internal.tld/python
the_product := "python" if {
input.dependency.package_name == "docker.internal.tld/python"
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# below here is boilerplate
default advisory_type := "DEPRECATED"
# we need to override this from the default DEPRECATED
advisory_type := "UNMAINTAINED" if {
[is_eol, msg] := endoflifedate_is_eol(the_product, cycle)
is_eol
}
deny contains msg if {
[is_eol, msg] := endoflifedate_is_eol(the_product, cycle)
is_eol
}
deny contains msg if {
[approaching_eol, msg] := endoflifedate_approaching_eol(the_product, cycle, days_until_warn)
approaching_eol
}
deny contains msg if {
[is_unsupported, msg] := endoflifedate_is_unsupported(the_product, cycle)
is_unsupported
}
deny contains msg if {
[approaching_unsupported, msg] := endoflifedate_approaching_unsupported(the_product, cycle, days_until_warn)
approaching_unsupported
}
supported_until := supported_until if {
[supported_until, ok] := endoflifedate_supported_until(the_product, cycle)
ok
}
eol_from := eol_from if {
[eol_from, ok] := endoflifedate_eol_from(the_product, cycle)
ok
}
This would then report any cases of:
- is it already End-of-Life?
- is it soon End-of-Life?
- is it already out of active support?
- is it soon out of active support?
As well as recording the dates, if known.
Processing and persisting policies
When using the dmd policy evaluate
command to evaluate a policy, you only see what would happen if the policy was applied, but it doesn't actually write the data to the database.
Similar to how advisories data is generated, to actually process + persist the defined policies, you can use the dmd db generate policy-violations
command.
This then writes data to the advisories
table that can be queried manually, or reported through 👇
Reporting violations
To report violations, you can use dmd report policy-violations
, or use the web application's reports viewer.
Additionally, any policy violations are exposed through dmd report advisories
.