Skip to content

Commit 403f4a1

Browse files
authored
chore(docs): Create quickstart and examples for policy devel CLI tools (#2298)
Signed-off-by: Daniel Liszka <[email protected]>
1 parent a449597 commit 403f4a1

File tree

4 files changed

+228
-0
lines changed

4 files changed

+228
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Policy Development Quickstart
2+
3+
This quickstart guide walks you through creating and validating a basic Chainloop policy that checks SBOM freshness (ensuring SBOMs are not older than 30 days). All steps are CLI-driven and can be run locally.
4+
5+
## Documentation References
6+
7+
- **CLI Reference**: [chainloop policy develop commands](https://docs.chainloop.dev/command-line-reference/cli-reference#chainloop-policy)
8+
- **Policy Concepts**: [Understanding Chainloop Policies](https://docs.chainloop.dev/concepts/policies)
9+
- **Custom Policy Guide**: [Writing Custom Policies](https://docs.chainloop.dev/guides/custom-policies)
10+
- **Material Types**: [Available Material Types](https://docs.chainloop.dev/concepts/material-types#material-types)
11+
12+
## Quick Test
13+
14+
### Step 1: Download the Example Files
15+
16+
```bash
17+
# Download the policy and sample materials
18+
curl -O https://raw.githubusercontent.com/chainloop-dev/chainloop/refs/heads/main/docs/examples/policies/quickstart/cdx-fresh.yaml
19+
curl -O https://raw.githubusercontent.com/chainloop-dev/chainloop/refs/heads/main/docs/examples/policies/quickstart/cdx-old.json
20+
curl -O https://raw.githubusercontent.com/chainloop-dev/chainloop/refs/heads/main/docs/examples/policies/quickstart/cdx-fresh.json
21+
```
22+
23+
### Step 2: Lint the Policy
24+
25+
Check your policy's structure and Rego syntax. Run it with `--format` flag to fix all formatting inconsistencies.
26+
27+
```bash
28+
chainloop policy develop lint --policy cdx-fresh.yaml --format
29+
```
30+
31+
**Expected output:**
32+
```
33+
INF policy is valid!
34+
```
35+
36+
### Step 3: Evaluate the Policy
37+
38+
Use your SBOM CycloneDX material to test your policy logic.
39+
40+
```bash
41+
# Test with old SBOM (should fail)
42+
chainloop policy develop eval --policy cdx-fresh.yaml --material cdx-old.json --kind SBOM_CYCLONEDX_JSON
43+
44+
# Test with fresh SBOM (should pass)
45+
chainloop policy develop eval --policy cdx-fresh.yaml --material cdx-fresh.json --kind SBOM_CYCLONEDX_JSON
46+
```
47+
48+
**Expected Results:**
49+
50+
**Old SBOM (should fail):**
51+
```
52+
INF - cdx-fresh: SBOM created at: 2024-06-15T10:30:00Z which is too old (freshness limit set to 30 days)
53+
INF policy evaluation failed
54+
```
55+
56+
**Fresh SBOM (should pass):**
57+
```
58+
INF policy evaluation passed
59+
```
60+
61+
## Create Your Own Policy
62+
63+
### Step 1: Initialize a Policy Template
64+
65+
Create a new policy with the embedded format (single YAML file):
66+
67+
```bash
68+
chainloop policy develop init --embedded --name my-policy --description "My custom policy description"
69+
```
70+
71+
**Note**: This creates a file named `my-policy.yaml` (based on the `--name` parameter). Without `--embedded`, it creates separate `chainloop-policy.yaml` and `chainloop-policy.rego` files.
72+
73+
### Step 2: Write Your Policy Rules
74+
75+
Edit the generated YAML file and replace the placeholder code in the `embedded` section with your Rego logic.
76+
77+
**Important**: Remove the `default violations := []` line to avoid conflicts with your `violations contains msg if` rules.
78+
79+
### Step 3: Test Your Policy
80+
81+
Follow steps 2-3 above with your own policy and materials.
82+
83+
## Policy Logic Explained
84+
85+
The SBOM freshness policy calculates a 30-day threshold in nanoseconds and compares it against the SBOM's `metadata.timestamp` field:
86+
87+
1. **Converts 30 days to nanoseconds**: `30 * 24 * 60 * 60 * 1000 * 1000 * 1000`
88+
2. **Parses the SBOM timestamp** using `time.parse_rfc3339_ns()`
89+
3. **Checks if current time minus (SBOM time + threshold) is positive**
90+
4. **If positive, the SBOM is too old** and a violation is raised
91+
92+
## Available Material Types
93+
94+
For the complete list of supported material types, see the [Material Types documentation](https://docs.chainloop.dev/concepts/material-types#material-types).
95+
96+
Common material types for the `--kind` parameter:
97+
98+
- `SBOM_CYCLONEDX_JSON` - CycloneDX SBOM files
99+
- `SBOM_SPDX_JSON` - SPDX SBOM files
100+
- `CONTAINER_IMAGE` - Container images
101+
- `ATTESTATION` - Generic attestations
102+
- `SARIF` - SARIF security scan results
103+
- `SLSA_PROVENANCE` - SLSA provenance attestations
104+
105+
Run `chainloop policy develop eval --help` for the complete list.
106+
107+
## Common Issues
108+
109+
1. **Rego type conflicts**: Remove `default violations := []` when using `violations contains msg if` rules
110+
2. **Missing material kind**: Always specify `--kind` parameter in eval command
111+
3. **File naming**: Policy files are named based on the `--name` parameter, not always `policy.yaml`
112+
4. **Time calculations**: Use nanoseconds for time comparisons in Rego policies
113+
114+
## Next Steps
115+
116+
Once you've mastered the basics:
117+
118+
1. Explore more complex examples in the [policy examples]](../) directory
119+
2. Learn about policy inputs and annotations
120+
3. Practice with different material types
121+
4. Deploy policies to your Chainloop workflows
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"bomFormat": "CycloneDX",
3+
"specVersion": "1.5",
4+
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b80",
5+
"version": 1,
6+
"metadata": {
7+
"timestamp": "2025-07-27T10:30:00Z",
8+
"tools": [
9+
{
10+
"vendor": "chainloop",
11+
"name": "chainloop",
12+
"version": "0.1.0"
13+
}
14+
]
15+
},
16+
"components": [
17+
{
18+
"type": "library",
19+
"bom-ref": "pkg:npm/[email protected]",
20+
"name": "express",
21+
"version": "4.18.0",
22+
"purl": "pkg:npm/[email protected]"
23+
}
24+
]
25+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
apiVersion: workflowcontract.chainloop.dev/v1
2+
kind: Policy
3+
metadata:
4+
name: cdx-fresh
5+
description: Checks that SBOM is maximum of 30 days old
6+
annotations:
7+
category: quickstart
8+
spec:
9+
policies:
10+
- embedded: |
11+
package main
12+
13+
import rego.v1
14+
15+
################################
16+
# Common section do NOT change #
17+
################################
18+
19+
result := {
20+
"skipped": skipped,
21+
"violations": violations,
22+
"skip_reason": skip_reason,
23+
"ignore": ignore,
24+
}
25+
26+
default skip_reason := ""
27+
28+
skip_reason := m if {
29+
not valid_input
30+
m := "invalid input"
31+
}
32+
33+
default skipped := true
34+
35+
skipped := false if valid_input
36+
37+
default ignore := false
38+
39+
########################################
40+
# EO Common section, custom code below #
41+
########################################
42+
# Validates if the input is valid and can be understood by this policy
43+
valid_input := true
44+
45+
limit := 30
46+
nanosecs_per_second := (1000 * 1000) * 1000
47+
nanosecs_per_day := ((24 * 60) * 60) * nanosecs_per_second
48+
maximum_age := limit * nanosecs_per_day
49+
50+
# If the input is valid, check for any policy violation here
51+
violations contains msg if {
52+
sbom_ns = time.parse_rfc3339_ns(input.metadata.timestamp)
53+
exceeding = time.now_ns() - (sbom_ns + maximum_age)
54+
exceeding > 0
55+
msg := sprintf("SBOM created at: %s which is too old (freshness limit set to %d days)", [input.metadata.timestamp, limit])
56+
}
57+
kind: SBOM_CYCLONEDX_JSON
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"bomFormat": "CycloneDX",
3+
"specVersion": "1.5",
4+
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
5+
"version": 1,
6+
"metadata": {
7+
"timestamp": "2024-06-15T10:30:00Z",
8+
"tools": [
9+
{
10+
"vendor": "chainloop",
11+
"name": "chainloop",
12+
"version": "0.1.0"
13+
}
14+
]
15+
},
16+
"components": [
17+
{
18+
"type": "library",
19+
"bom-ref": "pkg:npm/[email protected]",
20+
"name": "express",
21+
"version": "4.18.0",
22+
"purl": "pkg:npm/[email protected]"
23+
}
24+
]
25+
}

0 commit comments

Comments
 (0)