cdx

package
v3.100.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PhaseDesign       = cyclonedx.PhaseDesign
	PhasePreBuild     = cyclonedx.PhasePreBuild
	PhaseBuild        = cyclonedx.PhaseBuild
	PhasePostBuild    = cyclonedx.PhasePostBuild
	PhaseOperations   = cyclonedx.PhaseOperations
	PhaseDiscovery    = cyclonedx.PhaseDiscovery
	PhaseDecommission = cyclonedx.PhaseDecommission
)
View Source
const (
	PropDeploymentProject     = "vulnetix:deployment/project"
	PropDeploymentCluster     = "vulnetix:deployment/cluster"
	PropDeploymentNamespace   = "vulnetix:deployment/namespace"
	PropDeploymentEnvironment = "vulnetix:deployment/environment"
	// PropDeploymentTagPrefix is the prefix for arbitrary key=value labels.
	PropDeploymentTagPrefix = "vulnetix:deployment/tag/"
)

Property names for deployment context in CycloneDX metadata.

metadata.properties is the CycloneDX-sanctioned home for namespaced data, so a document carrying these stays schema-valid and any other tool can read them.

Variables

This section is empty.

Functions

func ApplyDeploymentContext added in v3.97.0

func ApplyDeploymentContext(bom *BOM, d DeploymentContext)

ApplyDeploymentContext stamps deployment labels into a BOM's metadata.

func ApplyVEXAnalysis added in v3.57.0

func ApplyVEXAnalysis(bom *BOM, vexEntries []Vulnerability)

ApplyVEXAnalysis folds auto-generated VEX entries into a BOM.

When the BOM already carries a vulnerability with the same id — the usual case for a finding that a previous run recorded and this run resolved — the entry's analysis and properties are attached to it. Appending a second entry under the same id would leave the BOM asserting both that the vulnerability is open and that it is resolved.

Call this after MergeBOMs, so that vulnerabilities carried over from the previous BOM on disk are visible to the id lookup.

func BuildLocalPurl added in v3.6.0

func BuildLocalPurl(name, version, ecosystem string) string

buildLocalPurl builds a Package URL string for a dependency. BuildLocalPurl is the exported wrapper used by cmd/scan.go and internal/scan to derive the PURL the server-side /v2/cli.sca handler will use to key its vulnerability rows. Keep the result byte-identical with buildLocalPurl so both call sites produce the same purl string for the same package.

func ExportCompRefs

func ExportCompRefs(bom *BOM) map[string]string

ExportCompRefs returns the component reference map built during BuildFromLocalScan. This is a helper to expose compRefs for dependency tree building without changing BuildFromLocalScan's signature.

func FormatSpec

func FormatSpec(specVersion string) string

FormatSpec returns the format string for CLI display.

func GitProjectName added in v3.37.1

func GitProjectName(g *gitctx.GitContext) string

GitProjectName derives a human-readable project name from the git context. Priority: first remote URL path → repo root directory name → "unknown".

func GitProjectVersion added in v3.37.1

func GitProjectVersion(g *gitctx.GitContext) string

GitProjectVersion returns the best available version string for the project. Priority: first tag at HEAD → short commit SHA → empty.

func NormalizeForSchema added in v3.99.0

func NormalizeForSchema(b *BOM)

NormalizeForSchema heals enum values the CycloneDX schema would reject, so the BOM validates regardless of whether a value was freshly generated or carried forward from an older on-disk SBOM during a merge (mergeVulnerabilities keeps existing entries verbatim, so legacy bad values would otherwise persist across rescans). It fixes the two known classes seen in the wild:

  • rating.severity: internal values like "unscored" → "unknown".
  • analysis.justification: a legacy "update" (a response value, not a justification) is recovered into analysis.response; any other invalid justification is dropped.

It is applied at every BOM output path; anything it does not recognise is left untouched so the write-time validation guard still catches new bug classes.

func NormalizeFormat

func NormalizeFormat(format string) (string, bool)

NormalizeFormat maps user-facing format names to spec versions or output type. Returns (specVersion, isRawJSON).

func NormalizeThirdPartyCDX added in v3.93.8

func NormalizeThirdPartyCDX(data []byte) ([]byte, []string)

NormalizeThirdPartyCDX heals a third-party CycloneDX document so that one malformed field does not cost the whole SBOM. An SBOM missing one bogus external reference is strictly better than no SBOM at all.

Two classes are healed, both observed on real scanner output:

  • externalReferences[].url that is not a valid iri-reference. ScanCode passes an opam manifest's URL template through verbatim, producing entries like "{https://opam.ocaml.org/packages}/{name}". There is no unambiguous expansion of a template the scanner itself failed to expand, so the entry is dropped. An external reference is metadata about a component, never the component itself, so no inventory is lost.
  • dependencies[].dependsOn listing the same ref twice. Trivy emits duplicate refs and the schema types that array with uniqueItems, so the duplicates are collapsed, keeping the first occurrence and the original order. The edge is still there, so the graph is unchanged.

Healing is keyed on the JSON key name at any depth, so nested components, services, metadata.component and the document root are all covered without hard-coding a path per spec version.

It returns the healed bytes and one note per change, so a repair is reported rather than silent. When nothing needed healing the input bytes are returned unchanged, so a valid document is byte-for-byte untouched.

func ParseUpstreamFromJSON added in v3.6.0

func ParseUpstreamFromJSON(raw []byte) (map[string]any, error)

ParseUpstreamFromJSON decodes a JSON CycloneDX document into the untyped map shape that MergeUpstream consumes. Useful when the upstream data arrived as raw bytes (e.g. read from disk) rather than via the CLI client.

func PopulateLicenses

func PopulateLicenses(bom *BOM, licenseMap map[string]string, canonicalSPDXID func(string) string)

PopulateLicenses sets the Licenses field on BOM components using a license map. The map key is "name@version" → SPDX license ID or expression.

canonicalSPDXID reports whether a bare value is a recognised SPDX identifier, returning its canonical spelling (or "" when unrecognised) — pass license.CanonicalSPDXID. It is required because CycloneDX constrains license.id to the SPDX enum while leaving license.expression and license.name free text: an unrecognised value (a registry license string, a proprietary name, a typo from the detector) emitted as license.id fails schema validation, so it must be demoted to license.name instead. A nil predicate is treated as "nothing is a recognised id", which is still schema-valid (every value becomes a free-form name/expression) — just less precise.

func Score added in v3.99.0

func Score(v float64) *float64

Score wraps a rating score for the pointer field, so call sites that have a number stay one line. A rating with no score omits the member entirely rather than claiming zero.

func ToolVersion added in v3.99.0

func ToolVersion() string

ToolVersion is the version every metadata.tools entry this CLI writes carries.

func ValidSpecVersions

func ValidSpecVersions() []string

ValidSpecVersions returns the list of supported CycloneDX spec versions.

Types

type Advisory

type Advisory = cyclonedx.Advisory

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type Affect

type Affect = cyclonedx.Affect

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type Analysis

type Analysis = cyclonedx.Analysis

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

func AnalysisForStateChange added in v3.34.0

func AnalysisForStateChange(status, detail string) *Analysis

AnalysisForStateChange builds a CycloneDX VEX analysis block for an auto-generated finding state transition. status is the Vulnetix finding status (e.g. "fixed", "under_investigation"); detail carries free-text context. Returns nil for statuses that carry no analysis block.

A "fixed" finding maps to state=resolved with response=["update"] — "update" is an impactAnalysisResponse value (the remediation taken), NOT a justification. justification (impactAnalysisJustification) is reserved for state=not_affected and would fail CycloneDX schema validation here.

type Approach added in v3.35.0

type Approach = cyclonedx.Approach

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type Authorship added in v3.99.0

type Authorship = cyclonedx.Authorship

Authorship, LifecyclePhase and the phase constants are re-exported so callers in this repository work in one vocabulary rather than importing the library alongside this package for a single enum.

func Authoring added in v3.99.0

func Authoring(toolName string, manufacturer *OrganizationalEntity, phases ...LifecyclePhase) Authorship

Authoring builds the Authorship for a document this CLI creates. It is the only place in this repository that assembles a tool entry.

type BOM

type BOM = cyclonedx.Document

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

func BuildFromLocalScan

func BuildFromLocalScan(results []LocalScanResult, specVersion string, scanCtx *ScanContext, seed *BOM) *BOM

BuildFromLocalScan creates a CycloneDX BOM from locally-parsed manifest data and VDB findings.

Components are deduplicated by (name, version). Each component carries its ecosystem scope (required = production/runtime, optional = dev/test/peer/provided/system) and a PURL. Vulnerabilities include CVSS ratings and links back to affected components.

When scanCtx is non-nil the BOM metadata is enriched with git-repository context (branch, commit, dirty state, worktree, VCS remotes, recent authors) and host environment context (hostname, shell, OS, arch, user).

func MergeBOMs added in v3.27.0

func MergeBOMs(existing, incoming *BOM) *BOM

MergeBOMs merges two locally-built CycloneDX documents. It is designed for the shared .vulnetix/sbom.cdx.json file where SCA and container scans both write component inventory. Existing data is preserved, incoming data fills gaps and adds new components, tools, vulnerabilities, and dependencies.

func MergeUpstream added in v3.6.0

func MergeUpstream(local *BOM, upstream map[string]any) (*BOM, error)

MergeUpstream returns local mutated with upstream's vulns and component gap-fills applied. It is safe to pass nil for either side — a nil local is initialised as an empty BOM; a nil upstream is a no-op.

upstream is accepted as map[string]any because the API delivers an unmarshalled JSON object (not our local typed BOM struct) — see CliSCAResponse.CycloneDX in pkg/vdb/api_cli.go.

type CDXDependency

type CDXDependency = cyclonedx.Dependency

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

func BuildDependencies

func BuildDependencies(groups []scan.ManifestGroup, compRefs map[string]string) []CDXDependency

BuildDependencies creates the CycloneDX dependencies array from ManifestGroup edges. compRefs maps "name@version" → bom-ref for cross-referencing.

type Component

type Component = cyclonedx.Component

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

func Participating added in v3.99.0

func Participating(toolName string) Component

Participating returns the tool component this CLI appends to a document it is transforming but did not author.

type DeploymentContext added in v3.97.0

type DeploymentContext struct {
	Project     string            `json:"project,omitempty"`
	Cluster     string            `json:"cluster,omitempty"`
	Namespace   string            `json:"namespace,omitempty"`
	Environment string            `json:"environment,omitempty"`
	Tags        map[string]string `json:"tags,omitempty"`
}

DeploymentContext is the set of deployment labels for one run.

Every field is optional, and an unset field stays empty rather than being guessed at: a scan that does not know its cluster must not claim one.

func DeploymentContextFromBOM added in v3.97.0

func DeploymentContextFromBOM(bom *BOM) DeploymentContext

DeploymentContextFromBOM reads deployment labels back out of a document.

The inverse of ApplyDeploymentContext, so a document that has been through this CLI can be re-tagged or grouped without the caller re-supplying flags.

func (DeploymentContext) Empty added in v3.97.0

func (d DeploymentContext) Empty() bool

Empty reports whether no deployment context was supplied or inferred.

func (DeploymentContext) String added in v3.97.0

func (d DeploymentContext) String() string

String renders the context as a compact one-line label for terminal output.

type ExternalReference

type ExternalReference = cyclonedx.ExternalReference

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type Hash added in v3.15.0

type Hash = cyclonedx.Hash

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type LicenseChoice

type LicenseChoice = cyclonedx.LicenseChoice

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type LicenseData

type LicenseData = cyclonedx.LicenseData

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type Lifecycle

type Lifecycle = cyclonedx.Lifecycle

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type LifecyclePhase added in v3.99.0

type LifecyclePhase = cyclonedx.LifecyclePhase

Authorship, LifecyclePhase and the phase constants are re-exported so callers in this repository work in one vocabulary rather than importing the library alongside this package for a single enum.

func DerivePhases added in v3.99.0

func DerivePhases(src LifecycleSources) []LifecyclePhase

DerivePhases maps what a pass read to the lifecycle phases it may claim.

CycloneDX defines lifecycles as "the stage(s) in which data in the BOM was captured", and it is an array precisely because one pass can read several kinds of source. Every builder used to hardcode `build`, which is wrong for the most common case of all: reading a manifest tells you what a build is *intended* to resolve, and the artefacts do not exist yet. That is pre-build.

An empty result means the pass cannot honestly claim any stage, and the document says nothing rather than something convenient.

func ParseLifecyclePhases added in v3.99.0

func ParseLifecyclePhases(csv string) ([]LifecyclePhase, error)

ParseLifecyclePhases parses a comma-separated phase list, as --lifecycle supplies. An unrecognised phase is an error rather than a custom-phase fallback, because a typo silently becoming a custom lifecycle name is indistinguishable downstream from a deliberate one.

type LifecycleSources added in v3.99.0

type LifecycleSources struct {
	// Manifests is true when declared dependencies were read from manifests or
	// lockfiles.
	Manifests bool
	// InstalledTree is true when a resolved, installed dependency tree was
	// walked — node_modules, site-packages, vendor/ and the like.
	InstalledTree bool
	// ContainerImage is true when a built image or its package databases were
	// read, and CompiledArtifacts when package metadata was recovered out of
	// compiled binaries.
	ContainerImage    bool
	CompiledArtifacts bool
	// Discovery is true for a pass that identifies assets by observation rather
	// than by resolving a declared set — the AI and crypto inventories.
	Discovery bool
	// Deployed is true when the run was given deployment context, which is a
	// statement that this inventory describes something running.
	Deployed bool
}

LifecycleSources describes what a pass actually read, which is what decides the phases it may claim.

type LocalScanResult

type LocalScanResult struct {
	File          scan.DetectedFile
	Packages      []scan.ScopedPackage
	Vulns         []scan.VulnFinding
	EnrichedVulns []scan.EnrichedVuln // populated after enrichment; used for full ratings
}

LocalScanResult holds the parsed packages and found vulnerabilities for one manifest file.

type ManufacturerSources added in v3.99.0

type ManufacturerSources struct {
	// Override is an explicit --bom-manufacturer value.
	Override string
	// Env is VULNETIX_BOM_MANUFACTURER.
	Env string
	// CIOwner is the repository owner the CI provider states. Populated for
	// GitHub, GitLab, Azure DevOps, Bitbucket and Jenkins by internal/config.
	CIOwner string
	// Git is the repository itself, used when nothing above answered.
	Git *gitctx.GitContext
	// OrgID is the Vulnetix organisation this run authenticated as. It names the
	// document's manufacturer by identifier when no human-readable name resolves
	// well enough to print, and rides along as bom-ref when one does.
	OrgID string
}

ManufacturerSources are the places a run can learn which organization it is running on behalf of, most direct first.

type Metadata

type Metadata = cyclonedx.Metadata

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type ModelCard added in v3.35.0

type ModelCard = cyclonedx.ModelCard

CycloneDX modelCard (spec 1.5+). modelCard / modelParameters / approach all set additionalProperties:false, so every field is a recognised schema key — per-detection evidence belongs in the owning component's properties array, never inside the model card. A modelCard may only be attached to a component of type "machine-learning-model".

type ModelParameters added in v3.35.0

type ModelParameters = cyclonedx.ModelParameters

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type OrganizationalContact

type OrganizationalContact = cyclonedx.OrganizationalContact

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type OrganizationalEntity added in v3.99.0

type OrganizationalEntity = cyclonedx.OrganizationalEntity

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

func ResolveManufacturer added in v3.99.0

func ResolveManufacturer(src ManufacturerSources) *OrganizationalEntity

ResolveManufacturer answers "which organization created this BOM".

CycloneDX is explicit that metadata.manufacturer is "the organization that created the BOM", and that it is the field to use for documents produced by automated processes. For a scan that means the organization running the scan, not the vendor of the scanner — the scanner is named in metadata.tools. A document claiming Vulnetix created an inventory of somebody else's repository says something different, and something untrue.

It returns nil rather than guessing. An absent manufacturer is honest and costs a consumer one unknown; a wrong one is a false statement they have no way to detect.

type Property

type Property = cyclonedx.Property

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type Rating

type Rating = cyclonedx.Rating

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type ScanContext

type ScanContext struct {
	// Git is the git repository context collected from the scanned directory.
	Git *gitctx.GitContext
	// System is the host/process environment at scan time.
	System *gitctx.SystemInfo
	// ToolVersion is the version string injected at build time (e.g. "1.2.3").
	ToolVersion string
	// ToolName is the CycloneDX metadata tool component name. Defaults to
	// vulnetix-sca for backward compatibility.
	ToolName string
	// Manufacturer is the organization that created the BOM — the one running
	// this scan, resolved by ResolveManufacturer. Nil when nothing resolved it,
	// which leaves metadata.manufacturer absent rather than guessed.
	Manufacturer *OrganizationalEntity
	// Phases are the lifecycle stages at which this pass captured its data,
	// derived by DerivePhases from what the pass actually read.
	Phases []LifecyclePhase
}

ScanContext carries optional environment-enrichment data passed to BOM builders. All fields are optional; nil pointers are silently ignored.

type Source

type Source = cyclonedx.VulnSource

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type Tools

type Tools = cyclonedx.Tools

The CycloneDX document model is owned by vdb-cyclonedx.

These are aliases, not wrappers: cdx.BOM and cyclonedx.Document are the same type, so every composite literal in this repository compiles unchanged, and a document handed to the shared builders is not narrowed on the way through.

This package used to declare the model itself. Two declarations of one shape is two sets of omissions, and they did not match: the local one had no metadata.manufacturer and no metadata.supplier, which is most of what CycloneDX uses to say who produced a document. Worse, it was lossy — decoding a third-party BOM into it dropped every member it did not declare — and that lossiness is why internal/scanopts carried a second, map-based implementation of deployment labelling rather than reuse ApplyDeploymentContext. The shared model round-trips unmodelled members, so one implementation suffices.

What stays in this package is what is genuinely this CLI's: which lifecycle phase a scan captured, how git and host context become metadata, how two documents merge, and the vulnetix:* property vocabulary.

type Vulnerability

type Vulnerability = cyclonedx.Vulnerability

Vulnerability and its parts. Rating.Score is a *float64 here where this package used to declare a float64: an unscored rating is common, and a value type emitted "score": 0 next to "severity": "high", which asserts a score of zero rather than the absence of one.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL