Documentation
¶
Overview ¶
Package binpkg discovers packages from compiled artefacts — the case where a dependency exists in a container image or release archive but no manifest, lockfile or package database mentions it.
Three evidence sources are read, all offline and metadata-only:
- Go build info embedded by the toolchain (ELF, PE, Mach-O and XCOFF): the main module, every dependency module with its go.sum H1 hash, and the toolchain itself (reported as the `stdlib` package in the Go ecosystem, which is how Go toolchain advisories are indexed).
- Rust `cargo auditable` data (the zlib-compressed JSON in the ELF `.dep-v0` section), including its crate-level dependency edges.
- JVM archives: Maven coordinates from `META-INF/maven/**/pom.properties`, `MANIFEST.MF` attributes, or the archive filename, including jars nested one level deep inside a fat/Spring-Boot jar.
Nothing here executes the artefact or reads a byte of its payload beyond the metadata sections named above.
Index ¶
Constants ¶
const ( MethodGoBuildInfo = "go-buildinfo" MethodCargoAuditable = "cargo-auditable" MethodJVMArchive = "jvm-archive" MethodOSFileOwner = "os-file-owner" )
Discovery methods, written verbatim into Package.Method and surfaced as CycloneDX evidence on the component.
const ( ScopeProduction = "production" ScopeDevelopment = "development" )
Scope values mirror internal/scan's scope vocabulary without importing it — binpkg is deliberately dependency-free so it can be reused by the analyze and container paths.
Variables ¶
This section is empty.
Functions ¶
func HasFileOwnership ¶
HasFileOwnership reports whether the root filesystem carries any package database whose file lists this package can read. It is false for rpm-only images and for arbitrary directories, which is the signal callers need before concluding a binary belongs to no package.
func LooksExecutable ¶
LooksExecutable reports whether a file is worth handing to FromBinary: an ELF, PE, Mach-O or XCOFF magic number, or a JVM archive extension. Callers use it to avoid reading every file in a container filesystem twice.
func RelativePath ¶
RelativePath renders a path inside the scanned tree for use as a CycloneDX locator: slash-separated and relative to root when possible.
Types ¶
type Artifact ¶
type Artifact struct {
Path string
Format string
Owner *Owner
Attributes map[string]string
Packages []Package
}
Artifact is one compiled file that yielded package metadata or an ownership attribution.
type Edge ¶
Edge is a dependency relation between two discovered packages, expressed with the same "name@version" keys the caller uses to build bom-refs.
type Owner ¶
type Owner struct {
Name string
Version string
Ecosystem string // deb, apk or arch
// Source is the package-database file the attribution came from, relative to
// the container root.
Source string
}
Owner identifies the OS package that installed a file inside a container root filesystem.
type OwnerIndex ¶
OwnerIndex maps an absolute in-container path ("/usr/bin/curl") to the package that installed it. Paths are stored slash-separated and rooted, exactly as the package databases record them.
func BuildOwnerIndex ¶
func BuildOwnerIndex(root string) OwnerIndex
BuildOwnerIndex reads the file lists of every package database present under a container root filesystem: dpkg (`var/lib/dpkg/info/*.list`), apk (`lib/apk/db/installed` F:/R: records) and pacman (`var/lib/pacman/local/*/files`).
RPM is intentionally absent: its database is a Berkeley DB or SQLite file that cannot be read without linking a native library, so rpm-based images get package components (from the `sca` container pass) without per-file attribution. Callers should not treat a missing owner as "unpackaged" for those images — see HasFileOwnership.
type Package ¶
type Package struct {
Name string
Version string
Ecosystem string
Scope string
IsDirect bool
Method string
Detail string
// Confidence is how strongly the evidence identifies the package: "high" for
// what the build tool itself recorded, "medium" for archive metadata a human
// can set freely, "low" for a name/version read off a filename.
Confidence string
Checksum string // go.sum-style H1 hash when the source provides one
BinaryPath string
}
Package is one dependency recovered from a compiled artefact.
type Result ¶
type Result struct {
// Format identifies what was recognised: "go", "rust", "jvm" or "" when the
// artefact carries no package metadata at all.
Format string
Packages []Package
Edges []Edge
// Attributes are extra facts about the artefact itself (VCS revision, build
// settings, toolchain) that belong on the binary component, not on a package.
Attributes map[string]string
// Errors records metadata that was present but unreadable. A file with no
// metadata at all is not an error.
Errors []string
}
Result is everything one artefact yielded.
func FromArtifact ¶
FromArtifact dispatches on file shape: JVM archives by extension, everything else through the compiled-binary readers. It never returns an error — an unreadable or uninteresting file yields an empty Result, because callers walk whole container filesystems where most files are neither.
func FromBinary ¶
FromBinary reads package metadata embedded in a compiled binary.
func FromJVMArchive ¶
FromJVMArchive recovers Maven coordinates from a jar/war/ear. The three evidence sources, in descending confidence:
- META-INF/maven/<group>/<artifact>/pom.properties — written by Maven itself
- META-INF/MANIFEST.MF Implementation-* / Bundle-SymbolicName attributes
- the archive filename ("commons-lang3-3.14.0.jar")
Fat jars are unpacked one level: every jar under BOOT-INF/lib, WEB-INF/lib or lib/ is inspected the same way, which is where a Spring Boot application's real dependency set lives.
type TreeOptions ¶
type TreeOptions struct {
Root string
// SkipDirs are additional directory base names to prune.
SkipDirs []string
// MaxFileSize overrides defaultMaxFileSize when positive.
MaxFileSize int64
// Owners attributes each artefact to the OS package that installed it. Build
// it with BuildOwnerIndex for a container root filesystem; leave nil
// otherwise.
Owners OwnerIndex
}
TreeOptions configures ScanTree.
type TreeResult ¶
type TreeResult struct {
Artifacts []Artifact
Packages []Package
Edges []Edge
// Examined counts files that looked like a compiled artefact and were parsed.
Examined int
// Unowned counts artefacts that no package database claims. It is only
// meaningful when Owners was supplied — an unclaimed binary in an image with a
// package database is a file that arrived outside the package manager.
Unowned []string
Errors []string
}
TreeResult aggregates a whole-tree scan.
func ScanTree ¶
func ScanTree(opts TreeOptions) TreeResult
ScanTree walks a directory tree and extracts embedded package metadata from every compiled artefact it finds. It is offline and read-only, and never returns an error for the tree as a whole: unreadable files are recorded in Errors so one bad file cannot abort an SBOM.