Skip to content

Commit 006ccfe

Browse files
authored
docs: update sbom license policy (#1175)
Signed-off-by: Miguel <[email protected]>
1 parent d6f4f3b commit 006ccfe

File tree

2 files changed

+24
-70
lines changed

2 files changed

+24
-70
lines changed
Lines changed: 13 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
title: Policies
33
---
44

5+
import PolicyYAML from "!!raw-loader!/examples/policies/sbom/cyclonedx-licenses.yaml";
6+
import CodeBlock from "@theme/CodeBlock";
7+
58
Starting with Chainloop [0.93.8](https://github.com/chainloop-dev/chainloop/releases/tag/v0.93.8), operators can attach policies to contracts.
69
These policies will be evaluated against the different materials and the statement metadata, if required. The result of the evaluation is informed as a list of possible violations and added to the attestation statement
710
before signing and sending it to Chainloop.
@@ -11,32 +14,15 @@ be used for building server side control gates.
1114

1215
### Policy specification
1316
A policy can be defined in a YAML document, like this:
14-
```yaml
15-
# cyclonedx-licenses.yaml
16-
apiVersion: workflowcontract.chainloop.dev/v1
17-
kind: Policy
18-
metadata:
19-
name: cyclonedx-licenses # (1)
20-
spec:
21-
type: SBOM_CYCLONEDX_JSON # (2)
22-
embedded: | # (3)
23-
package main
2417

25-
deny[msg] {
26-
count(without_license) > 0
27-
msg := "SBOM has components without licenses"
28-
}
18+
<CodeBlock language="yaml" title="cyclonedx-licenses.yaml" showLineNumbers>
19+
{PolicyYAML}
20+
</CodeBlock>
2921

30-
without_license = {comp.purl |
31-
some i
32-
comp := input.components[i]
33-
not comp.licenses
34-
}
35-
```
3622
In this particular example, we see:
37-
* (1) policies have a name
38-
* (2) they can be optionally applied to a specific type of material (check [the documentation](./operator/contract#material-schema) for the supported types). If no type is specified, a material name will need to be provided explicitly in the contract.
39-
* (3) they have a policy script that it's evaluated against the material (in this case a CycloneDX SBOM report). Currently, only [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/#learning-rego) policies are supported.
23+
* policies have a name (cyclonedx-licenses)
24+
* they can be optionally applied to a specific type of material (check [the documentation](./operator/contract#material-schema) for the supported types). If no type is specified, a material name will need to be provided explicitly in the contract.
25+
* they have a policy script that it's evaluated against the material (in this case a CycloneDX SBOM report). Currently, only [Rego](https://www.openpolicyagent.org/docs/latest/policy-language/#learning-rego) policies are supported.
4026

4127
Policy scripts could also be specified in a detached form:
4228
```yaml
@@ -97,35 +83,12 @@ There are two ways to attach a policy to a contract:
9783
are both equivalent. The advantage of having remote policies is that they can be easily reused, allowing organizations to create policy catalogs.
9884

9985
* If preferred, authors could create self-contained contracts **embedding policy specifications**. The main advantage of this method is that it ensures that the policy source cannot be changed, as it's stored and versioned within the contract:
100-
```yaml
101-
schemaVersion: v1
102-
materials:
103-
- name: sbom
104-
type: SBOM_CYCLONEDX_JSON
105-
policies:
106-
materials:
107-
- policy: # (1)
108-
apiVersion: workflowcontract.chainloop.dev/v1
109-
kind: Policy
110-
metadata:
111-
name: sbom-licenses
112-
spec:
113-
type: SBOM_CYCLONEDX_JSON
114-
embedded: |
115-
package main
11686

117-
deny[msg] {
118-
count(without_license) > 0
119-
msg := "SBOM has components without licenses"
120-
}
87+
<CodeBlock language="yaml" title="cyclonedx-licenses.yaml" showLineNumbers>
88+
{PolicyYAML}
89+
</CodeBlock>
12190

122-
without_license = {comp.purl |
123-
some i
124-
comp := input.components[i]
125-
not comp.licenses
126-
}
127-
```
128-
In the example above, we can see that, when referenced by the `policy` attribute (1), a full policy can be embedded in the contract.
91+
In the example above, we can see that, when referenced by the `policy` attribute (1), a full policy can be embedded in the contract.
12992

13093
### Rego scripts
13194
Currently, policy scripts are assumed to be written in [Rego language](https://www.openpolicyagent.org/docs/latest/policy-language/#learning-rego). Other policy engines might be implemented in the future.
Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,3 @@
1-
# Copyright 2024 The Chainloop Authors.
2-
#
3-
# Licensed under the Apache License, Version 2.0 (the "License");
4-
# you may not use this file except in compliance with the License.
5-
# You may obtain a copy of the License at
6-
#
7-
# http://www.apache.org/licenses/LICENSE-2.0
8-
#
9-
# Unless required by applicable law or agreed to in writing, software
10-
# distributed under the License is distributed on an "AS IS" BASIS,
11-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
# See the License for the specific language governing permissions and
13-
# limitations under the License.
14-
151
apiVersion: workflowcontract.chainloop.dev/v1
162
kind: Policy
173
metadata:
@@ -23,13 +9,18 @@ spec:
239
type: SBOM_CYCLONEDX_JSON
2410
embedded: |
2511
package main
26-
12+
2713
import rego.v1
2814
29-
deny contains ref if {
30-
some i
31-
comp := input.components[i]
15+
deny contains msg if {
16+
count(without_license) > 0
17+
msg := sprintf("Missing licenses for %s", [components_str])
18+
}
19+
20+
components_str := concat(", ", [comp.purl | some comp in without_license])
21+
22+
without_license contains comp if {
23+
some comp in input.components
3224
not comp.licenses
33-
# log name and bom-ref fields
34-
ref := sprintf("Missing licenses for %v (%v)", [comp.name, comp["bom-ref"]])
3525
}
26+

0 commit comments

Comments
 (0)