You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -12,7 +12,7 @@ One of the benefits of buildpacks is they can also populate the app image with m
12
12
* The buildpacks were used to create the app image
13
13
* And more...!
14
14
15
-
You can find all of this information using `pack` via its `inspect-image` command.
15
+
You can find some of this information using `pack` via its `inspect-image` command. The bill-of-materials information will be available using `pack sbom download`.
16
16
17
17
<!-- test:exec -->
18
18
```bash
@@ -38,18 +38,77 @@ Processes:
38
38
39
39
Apart from the above standard metadata, buildpacks can also populate information about the dependencies they have provided in form of a `Bill-of-Materials`. Let's see how we can use this to populate information about the version of `ruby` that was installed in the output app image.
40
40
41
-
To add the `ruby` version to the output of `pack inspect-image`, we will have to provide a `Bill-of-Materials` (`BOM`) containing this information. You'll need to update the `launch.toml` created at the end of your `build` script:
41
+
To add the `ruby` version to the output of `pack download sbom`, we will have to provide a [Software `Bill-of-Materials`](https://en.wikipedia.org/wiki/Software_bill_of_materials) (`SBOM`) containing this information. There are three "standard" ways to report SBOM data. You'll need to choose to use on of [CycloneDX](https://cyclonedx.org/), [SPDX](https://spdx.dev/) or [Syft](https://github.com/anchore/syft) update the `ruby.sbom.<ext>` (where `<ext>` is the extension appropriate for your SBOM standard, one of `cdx.json`, `spdx.json` or `syft.json`) at the end of your `build` script. Discussion of which SBOM format to choose is outside the scope of this tutorial, but we will note that the SBOM format you choose to use is likely to be the output format of any SBOM scanner (eg: [`syft cli`](https://github.com/anchore/syft)) you might choose to use. In this example we will use the CycloneDX json format.
42
+
43
+
First, annotate the `buildpack.toml` to specify that it emits CycloneDX:
Then, in our buildpack implemetnation we will generate the necessary SBOM metadata:
42
62
43
63
```bash
44
64
# ...
45
65
46
66
# Append a Bill-of-Materials containing metadata about the provided ruby version
47
-
cat >>"$layersdir/launch.toml"<<EOL
48
-
[[bom]]
49
-
name = "ruby"
50
-
[bom.metadata]
51
-
version = "$ruby_version"
67
+
cat >>"$layersdir/ruby.sbom.cdx.json"<<EOL
68
+
{
69
+
"bomFormat": "CycloneDX",
70
+
"specVersion": "1.4",
71
+
"version": 1,
72
+
"components": [
73
+
{
74
+
"type": "library",
75
+
"name": "ruby",
76
+
"version": "$ruby_version"
77
+
}
78
+
]
79
+
}
80
+
EOL
81
+
```
82
+
83
+
We can also add an SBOM entry for each dependency listed in `Gemfile.lock`. Here we use `jq` to add a new record to the `components` array in `bundler.sbom.cdx.json`:
84
+
85
+
```bash
86
+
crubybom="${layersdir}/ruby.sbom.cdx.json"
87
+
cat >>${rubybom}<<EOL
88
+
{
89
+
"bomFormat": "CycloneDX",
90
+
"specVersion": "1.4",
91
+
"version": 1,
92
+
"components": [
93
+
{
94
+
"type": "library",
95
+
"name": "ruby",
96
+
"version": "$ruby_version"
97
+
}
98
+
]
99
+
}
52
100
EOL
101
+
if [[ -f Gemfile.lock ]] ;then
102
+
forgemin$(gem dep -q | grep ^Gem | sed 's/^Gem //')
103
+
do
104
+
version=${gem##*-}
105
+
name=${gem%-${version}}
106
+
DEP=$(jq --arg name "${name}" --arg version "${version}" \
You should then be able to inspect your Ruby app for its Bill-of-Materials via:
227
+
Viewing your bill-of-materials requires extracting (or `download`ing) the bill-of-materials from your local image. This command can take some time to return.
150
228
151
229
<!-- test:exec -->
152
230
```bash
153
-
pack inspect-image test-ruby-app --bom
231
+
pack sbom download test-ruby-app
154
232
```
155
233
<!--+- "{{execute}}"+-->
156
234
235
+
The SBOM information is now downloaded to the local file system:
You should find that the included `ruby` version is `2.5.0` as expected.
158
243
159
-
<!-- test:assert=contains -->
244
+
<!-- test:assert=contains;ignore-lines=...-->
160
245
```text
246
+
{
247
+
"bomFormat": "CycloneDX",
248
+
"specVersion": "1.4",
249
+
"version": 1,
250
+
"components": [
161
251
{
252
+
"type": "library",
162
253
"name": "ruby",
163
-
"metadata": {
164
-
"version": "2.5.0"
165
-
},
166
-
"buildpacks": {
167
-
"id": "examples/ruby",
168
-
"version": "0.0.1"
169
-
}
170
-
}
254
+
"version": "2.5.0"
255
+
},
256
+
...
257
+
]
258
+
}
171
259
```
172
260
173
261
Congratulations! You’ve created your first configurable Cloud Native Buildpack that uses detection, image layers, and caching to create an introspectable and runnable OCI image.
@@ -177,7 +265,6 @@ Congratulations! You’ve created your first configurable Cloud Native Buildpack
177
265
Now that you've finished your buildpack, how about extending it? Try:
178
266
179
267
- Caching the downloaded Ruby version
180
-
- Updating the BOM with all the gems provided by bundler
181
268
- [Packaging your buildpack for distribution][package-a-buildpack]
0 commit comments