Packer
hcp-sbom provisioner
Official
The hcp-sbom provisioner uploads software bill of materials (SBOM) files from artifacts built by Packer to HCP Packer and associates them with individual artifact versions. You must format SBOM files you want to upload as JSON and follow either the SPDX or CycloneDX specification.
The provisioner supports the following operation methods:
- Manual SBOM Upload (
source): Upload a self-generated SBOM file from the remote host. - Automatic SBOM Generation (
auto_generate): Packer downloads and runs an SBOM generation tool on the remote host. By default, Packer uses Syft for SBOM generation. Refer to Automatic SBOM generation for more information.
Examples
The following example uploads an SBOM from the local /tmp directory and stores a copy at ./sbom/sbom_cyclonedx.json on the local machine.
provisioner "hcp-sbom" {
source = "/tmp/sbom_cyclonedx.json"
destination = "./sbom/sbom_cyclonedx.json"
sbom_name = "sbom-cyclonedx"
}
Automatic SBOM generation
You can configure the provisioner to automatically download and run an SBOM generation tool on the remote host. By default, Packer downloads and uses Syft for SBOM generation.
The following example configures the provisioner to download Syft and automatically generate an SBOM, associate it with the HCP Packer artifact version, and store a copy at ./sbom/sbom_cyclonedx.json on the local machine.
provisioner "hcp-sbom" {
auto_generate = true
destination = "./sbom/sbom_cyclonedx.json"
sbom_name = "auto-generated-sbom"
}
When you set auto_generate to true, Packer automatically detects the remote host's OS and architecture and downloads the appropriate Syft binary for SBOM generation. Packer then uploads the SBOM generation tool to the remote host, executes the tool to generate an SBOM, downloads the SBOM, and uploads it to HCP Packer.
After Packer completes your build, it cleans up all temporary files it created to download the SBOM generation tool.
Note: Packer validates the operating system and architecture at runtime when it connects to the remote host. If the detected platform is not supported, the provisioner will fail with an error message indicating the unsupported platform.
Custom SBOM generation tool
You can specify a custom SBOM generation tool and configuration instead of using the default Syft. The following example tells the provisioner where to download the tool, the arguments to pass to it, and where to perform the scan.
provisioner "hcp-sbom" {
auto_generate = true
scanner_url = "https://example.com/my-sbom-tool-linux-amd64" # Must be direct binary, not archive
scanner_checksum = "abc123..."
scanner_args = ["-o", "spdx-json", "--verbose"]
scan_path = "/opt/myapp"
destination = "./sbom"
sbom_name = "custom-tool-sbom"
}
Elevated execution
You can customize the provisioner if your remote system requires different permissions to perform a scan and generate an SBOM.
Note: Running the SBOM generation tool with elevated privileges such as sudo or administrator access provides more complete scan results. Without elevated permissions, the tool may not be able to access all files and directories on the system, which can result in an incomplete SBOM.
By default, Packer runs the following command to run the SBOM generation tool:
chmod +x {{.Path}} && sudo {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}
You can set the execute_command to override this default behavior. Packer provides template variables to fill in information at run time such as the path to the SBOM generation tool, arguments for the tool, and the path to scan. Refer to Template variables in execute_command for a complete list of supported variables.
The following example overrides the default execute_command value to provide a password for the sudo command:
provisioner "hcp-sbom" {
auto_generate = true
execute_command = "chmod +x {{.Path}} && echo 'mypassword' | sudo -S {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}"
destination = "./sbom"
sbom_name = "sbom-sudo-password"
}
The following example removes sudo from the command in cases where you do not require elevated permissions:
provisioner "hcp-sbom" {
auto_generate = true
execute_command = "chmod +x {{.Path}} && {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}"
destination = "./sbom"
sbom_name = "sbom-no-sudo"
}
Windows with a custom user
For Windows hosts that require administrator privileges, you can set the elevated_user and elevated_password parameters to tell Packer to execute the SBOM generation as a specific user.
provisioner "hcp-sbom" {
auto_generate = true
elevated_user = "Administrator"
elevated_password = "MySecurePassword123!"
destination = "./sbom"
sbom_name = "windows-elevated-sbom"
}
Configuration reference
You can specify the following configuration options.
Required parameters:
Exactly one of the following is required:
source(string) - The file path or URL to the SBOM file in the Packer artifact. This file must either be in the SPDX or CycloneDX format. Mutually exclusive withauto_generate.auto_generate(bool) - Enable automatic SBOM generation by downloading and running a scanner tool on the remote host. When enabled, the provisioner will detect the remote OS and architecture, download an appropriate scanner (Syft by default), and execute it to generate an SBOM. Mutually exclusive withsource.
Optional parameters:
destination(string) - The path on the local machine to store a copy of the SBOM file. You can specify an absolute or a path relative to the working directory when you execute the Packer build. If the file already exists on the local machine, Packer overwrites the file. If the destination is a directory, the directory must already exist.sbom_name(string) - The name of the SBOM file stored in HCP Packer. If omitted, HCP Packer uses the build fingerprint as the file name. This value must be between three and 36 characters from the following set:[A-Za-z0-9_-]. You must specify a unique name for each build in an artifact version.scanner_url(string) - URL to scanner tool. Supports go-getter syntax including HTTP, local files, Git, S3, etc. If empty andauto_generateis true, Syft will be automatically downloaded based on detected OS and architecture. When specified, only direct binary URLs are supported (archives are not extracted).scanner_checksum(string) - Expected SHA256 checksum of scanner binary for verification. Provide as a hex string without prefix, for example:abc123def456.... If provided,scanner_urlmust also be specified. The checksum is verified after download and before upload to the remote host.scanner_args([]string) - Arguments to pass to the scanner tool. Default for Syft:["-o", "cyclonedx-json", "-q"].scan_path(string) - Path to scan on remote host. Defaults to/(root directory).execute_command(string) - The command template used to execute the scanner on the remote host. Available template variables:{{.Path}}- Path to the scanner binary on the remote host{{.Args}}- Scanner arguments (fromscanner_args){{.ScanPath}}- Path to scan (fromscan_path){{.Output}}- Output file path for the SBOM
Default for Unix:
chmod +x {{.Path}} && sudo {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}Default for Windows:
{{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}Examples:
Without sudo:
execute_command = "chmod +x {{.Path}} && {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}"With sudo password:
execute_command = "chmod +x {{.Path}} && echo 'password' | sudo -S {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}"With sudo -n (no password):
execute_command = "chmod +x {{.Path}} && sudo -n {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}"With specific user:
execute_command = "chmod +x {{.Path}} && sudo -u myuser {{.Path}} {{.Args}} {{.ScanPath}} > {{.Output}}"elevated_user(string) - A username to use for elevated permissions when running the scanner on Windows. This is only used for Windows hosts when the scanner needs administrative privileges. For Unix-like systems, useexecute_commandwith sudo instead.elevated_password(string) - The password for theelevated_user. Required ifelevated_useris specified. Only applicable for Windows hosts.
Operating system and architecture detection
When you enable auto_generate, the provisioner automatically detects the remote host's operating system and architecture by running the following commands:
- SSH communicators:
uname -s -m - WinRM communicators:
echo %PROCESSOR_ARCHITECTURE%
The provisioner uses this information to download and extract the correct build of the SBOM generation tool and set platform-specific default execution commands.
SBOM Generation Tool Download and Archive Handling
Automatic Syft Download
When you enable auto_generate without specifying scanner_url, Packer automatically downloads the latest Syft v1.x.x release for compatibility and stability. If you need to use a specific version of Syft, you can provide a direct URL to that version's binary using the scanner_url parameter.
Note: Packer downloads Syft v1.x.x releases to ensure compatibility and avoid breaking changes that may occur in major version updates.
The download and extraction process varies by platform:
- Unix, Linux, and macOS: Packer downloads a
.tar.gzarchive, extracts it locally, and uploads the binary to the remote host. - Windows: Packer downloads a
.ziparchive, uploads the zip file to the remote host, and extracts it remotely. This approach optimizes for WinRM's slower upload speeds.
Note: Windows WinRM file uploads can be significantly slower than SSH due to protocol overhead. For better performance on Windows hosts, consider using SSH instead of WinRM as your communicator when possible. The provisioner includes optimizations to mitigate WinRM's slow upload speeds, but SSH will still provide better performance.
Custom SBOM Generation Tool
When you specify scanner_url to use a custom SBOM generation tool, the URL must point directly to a standalone binary file. Archive formats are not supported for custom scanner URLs.
Ensure the binary you provide is compatible with your target operating system and architecture.
Correct custom scanner URL example:
scanner_url = "https://example.com/my-scanner-linux-amd64"
Incorrect custom scanner URL example:
scanner_url = "https://example.com/my-scanner.tar.gz"
Complete example with manual SBOM generation
packer {
required_plugins {
docker = {
version = ">= 1.0.0"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "ubuntu" {
image = "ubuntu:20.04"
commit = true
}
build {
sources = ["source.docker.ubuntu"]
hcp_packer_registry {
bucket_name = "test-bucket"
}
provisioner "shell" {
inline = [
"apt-get update -y",
"apt-get install -y curl gpg",
"bash -c \"$(curl -sSL https://install.mondoo.com/sh)\"",
"cnquery sbom --output cyclonedx-json --output-target /tmp/sbom_cyclonedx.json",
]
}
provisioner "hcp-sbom" {
source = "/tmp/sbom_cyclonedx.json"
destination = "./sbom"
sbom_name = "sbom-cyclonedx"
}
}
Complete Example with automatic SBOM generation
packer {
required_plugins {
docker = {
version = ">= 1.0.0"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "ubuntu" {
image = "ubuntu:20.04"
commit = true
}
build {
sources = ["source.docker.ubuntu"]
hcp_packer_registry {
bucket_name = "test-bucket"
}
provisioner "hcp-sbom" {
auto_generate = true
scan_path = "/"
destination = "./sbom"
sbom_name = "auto-generated-sbom"
}
}
Template variables in execute_command
The execute_command configuration option supports the following template variables:
{{.Path}}- Path to the SBOM generation tool binary on the remote host{{.Args}}- Tool arguments (fromscanner_args){{.ScanPath}}- Path to scan (fromscan_path){{.Output}}- Output file path for the SBOM
These variables allow you to customize how the provisioner executes the SBOM generation tool while maintaining flexibility across different environments and security requirements.