Using Templates
Syft lets you define custom output formats using Go templates. This is useful for generating custom reports, integrating with specific tools, or extracting only the data you need.
How to use templates
Set the output format to template
and specify the template file path:
syft <image> -o template -t ./path/to/custom.tmpl
You can also configure the template path in your configuration file:
#.syft.yaml
format:
template:
path: "/path/to/template.tmpl"
Available fields
Templates receive the same data structure as the syft-json
output format. The Syft JSON schema is the source of truth for all available fields and their structure.
To see what data is available:
# View the full JSON structure
syft <image> -o json
# Explore specific fields
syft <image> -o json | jq '.artifacts[0]'
Key fields commonly used in templates:
.artifacts
- Array of discovered packages.files
- Array of discovered files.source
- Information about what was scanned.distro
- Detected Linux distribution (if applicable).descriptor
- Syft version and configuration
Common package (artifact) fields:
.name
,.version
,.type
- Basic package info.licenses
- License information (array).purl
- Package URL.cpes
- Common Platform Enumerations.locations
- Where the package was found
Template functions
Syft templates support:
- Go template built-ins - See the Go template documentation
- Sprig functions - Additional helpers from Sprig
- Syft-specific functions:
Function | Arguments | Description |
---|---|---|
getLastIndex |
collection |
Returns the last index of a slice (length - 1), useful for comma-separated lists |
hasField |
obj , field |
Checks if a field exists on an object, returns boolean |
Examples
The following examples show template source code and the rendered output when run against alpine:3.9.2
:
CSV output
"Package","Version","Type","Found by"
{{- range .artifacts}}
"{{.name}}","{{.version}}","{{.type}}","{{.foundBy}}"
{{- end}}
"Package","Version","Type","Found by"
"alpine-baselayout","3.1.0-r3","apk","apk-db-cataloger"
"alpine-keys","2.1-r1","apk","apk-db-cataloger"
"apk-tools","2.10.3-r1","apk","apk-db-cataloger"
"busybox","1.29.3-r10","apk","apk-db-cataloger"
"ca-certificates-cacert","20190108-r0","apk","apk-db-cataloger"
"libc-utils","0.7.1-r0","apk","apk-db-cataloger"
"libcrypto1.1","1.1.1a-r1","apk","apk-db-cataloger"
"libssl1.1","1.1.1a-r1","apk","apk-db-cataloger"
"libtls-standalone","2.7.4-r6","apk","apk-db-cataloger"
"musl","1.1.20-r3","apk","apk-db-cataloger"
"musl-utils","1.1.20-r3","apk","apk-db-cataloger"
"scanelf","1.2.3-r0","apk","apk-db-cataloger"
"ssl_client","1.29.3-r10","apk","apk-db-cataloger"
"zlib","1.2.11-r1","apk","apk-db-cataloger"
Filter by package type
{{range .artifacts}}
{{- if eq .type "apk"}}
{{.name}}@{{.version}}{{end}}
{{- end}}
alpine-baselayout@3.1.0-r3
alpine-keys@2.1-r1
apk-tools@2.10.3-r1
busybox@1.29.3-r10
ca-certificates-cacert@20190108-r0
libc-utils@0.7.1-r0
libcrypto1.1@1.1.1a-r1
libssl1.1@1.1.1a-r1
libtls-standalone@2.7.4-r6
musl@1.1.20-r3
musl-utils@1.1.20-r3
scanelf@1.2.3-r0
ssl_client@1.29.3-r10
zlib@1.2.11-r1
Markdown report
# SBOM Report: {{.source.metadata.userInput}}
Scanned: {{.source.name}}:{{.source.version}} ({{.source.type}})
{{- if .distro}}
Distribution: {{.distro.prettyName}}
{{- end}}
## Packages ({{len .artifacts}})
| Package | Version | Type |
|---------|---------|------|
{{- range .artifacts}}
| {{.name}} | {{.version}} | {{.type}} |
{{- end}}
# SBOM Report: alpine:3.9.2
Scanned: alpine:3.9.2 (image)
Distribution: Alpine Linux v3.9
## Packages (14)
| Package | Version | Type |
| ---------------------- | ----------- | ---- |
| alpine-baselayout | 3.1.0-r3 | apk |
| alpine-keys | 2.1-r1 | apk |
| apk-tools | 2.10.3-r1 | apk |
| busybox | 1.29.3-r10 | apk |
| ca-certificates-cacert | 20190108-r0 | apk |
| libc-utils | 0.7.1-r0 | apk |
| libcrypto1.1 | 1.1.1a-r1 | apk |
| libssl1.1 | 1.1.1a-r1 | apk |
| libtls-standalone | 2.7.4-r6 | apk |
| musl | 1.1.20-r3 | apk |
| musl-utils | 1.1.20-r3 | apk |
| scanelf | 1.2.3-r0 | apk |
| ssl_client | 1.29.3-r10 | apk |
| zlib | 1.2.11-r1 | apk |
License compliance
{{range .artifacts}}
{{- if .licenses}}
{{.name}}: {{range .licenses}}{{.value}} {{end}}{{end}}
{{- end}}
alpine-baselayout: GPL-2.0
alpine-keys: MIT
apk-tools: GPL2
busybox: GPL-2.0
ca-certificates-cacert: GPL-2.0-or-later MPL-2.0
libc-utils: BSD
libcrypto1.1: OpenSSL
libssl1.1: OpenSSL
libtls-standalone: ISC
musl: MIT
musl-utils: BSD GPL2+ MIT
scanelf: GPL-2.0
ssl_client: GPL-2.0
zlib: zlib
Custom JSON subset
{
"scanned": "{{.source.metadata.userInput}}",
"packages": [
{{- $last := sub (len .artifacts) 1}}
{{- range $i, $pkg := .artifacts}}
{"name": "{{$pkg.name}}", "version": "{{$pkg.version}}"}{{if ne $i $last}},{{end}}
{{- end}}
]
}
{
"scanned": "alpine:3.9.2",
"packages": [
{ "name": "alpine-baselayout", "version": "3.1.0-r3" },
{ "name": "alpine-keys", "version": "2.1-r1" },
{ "name": "apk-tools", "version": "2.10.3-r1" },
{ "name": "busybox", "version": "1.29.3-r10" },
{ "name": "ca-certificates-cacert", "version": "20190108-r0" },
{ "name": "libc-utils", "version": "0.7.1-r0" },
{ "name": "libcrypto1.1", "version": "1.1.1a-r1" },
{ "name": "libssl1.1", "version": "1.1.1a-r1" },
{ "name": "libtls-standalone", "version": "2.7.4-r6" },
{ "name": "musl", "version": "1.1.20-r3" },
{ "name": "musl-utils", "version": "1.1.20-r3" },
{ "name": "scanelf", "version": "1.2.3-r0" },
{ "name": "ssl_client", "version": "1.29.3-r10" },
{ "name": "zlib", "version": "1.2.11-r1" }
]
}
Executable file digests
{{range .files -}}
{{- if .executable}}
{{.location.path}}: {{range .digests}}{{if eq .algorithm "sha256"}}{{.value}}{{end}}{{end}}
{{end}}
{{- end}}
/bin/busybox: 2c1276c3c02ccec8a0e1737d3144cdf03db883f479c86fbd9c7ea4fd9b35eac5
/lib/ld-musl-aarch64.so.1: 0132814479f1acc1e264ef59f73fd91563235897e8dc1bd52765f974cde382ca
/lib/libcrypto.so.1.1: 6c597c8ad195eeb7a9130ad832dfa4cbf140f42baf96304711b2dbd43ba8e617
/lib/libssl.so.1.1: fb72f4615fb4574bd6eeabfdb86be47012618b9076d75aeb1510941c585cae64
/lib/libz.so.1.2.11: 19e790eb36a09eba397b5af16852f3bea21a242026bbba3da7b16442b8ba305b
/sbin/apk: 22d7d85bd24923f1f274ce765d16602191097829e22ac632748302817ce515d8
/sbin/mkmntdirs: a14a5a28525220224367616ef46d4713ef7bd00d22baa761e058e8bdd4c0af1b
/usr/bin/getconf: 82bcde66ead19bc3b9ff850f66c2dbf5eaff36d481f1ec154100f73f6265d2ef
/usr/bin/getent: 53ffb508150e91838d795831e8ecc71f2bc3a7db036c6d7f9512c3973418bb5e
/usr/bin/iconv: 1c99d1f4edcb8da6db1da60958051c413de45a4c15cd3b7f7285ed87f9a250ff
/usr/bin/scanelf: 908da485ad2edea35242f8989c7beb9536414782abc94357c72b7d840bb1fda2
/usr/bin/ssl_client: 67ab7f3a1ba35630f439d1ca4f73c7d95f8b7aa0e6f6db6ea1743f136f074ab4
/usr/lib/engines-1.1/afalg.so: ea7c2f48bc741fd828d79a304dbf713e20e001c0187f3f534d959886af87f4af
/usr/lib/engines-1.1/capi.so: b461ed43f0f244007d872e84760a446023b69b178c970acf10ed2666198942c6
/usr/lib/engines-1.1/padlock.so: 0ccb04f040afb0216da1cea2c1db7a0b91d990ce061e232782aedbd498483649
/usr/lib/libtls-standalone.so.1.0.0: 7f4c2ff4010e30a69f588ab4f213fdf9ce61a524a0eecd3f5af31dc760e8006c
Find binaries importing a library
{{range .files -}}
{{- if .executable}}
{{- $path := .location.path}}
{{- range .executable.importedLibraries}}
{{- if eq . "libcrypto.so.1.1"}}
{{$path}}
{{break}}
{{- end}}
{{- end}}
{{- end}}
{{- end}}
/lib/libssl.so.1.1
/sbin/apk
/usr/lib/engines-1.1/afalg.so
/usr/lib/libtls-standalone.so.1.0.0
Troubleshooting
“can’t evaluate field” errors: The field doesn’t exist or is misspelled. Check field names with syft <image> -o json | jq
.
Empty output: Verify your field paths are correct. Use syft <image> -o json
to see the actual data structure.
Template syntax errors: Refer to the Go template documentation for syntax help.
Note
If you have templates from before Syft v0.102.0 that no longer work, set format.template.legacy: true
in your configuration. This uses internal Go structs instead of the JSON output schema.
Long-term support for this legacy option is not guaranteed.
Additional resources
- Go template documentation - Template syntax reference
- Sprig function documentation - Helper functions
- Output formats - Other output format options
- Configuration options - Advanced settings