Using Templates

Create custom SBOM output formats using Go templates with available data fields to build tailored reports for specific tooling or compliance requirements.

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:

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.

Additional resources

Last modified October 10, 2025: fix reference links (1594d93)