Documentation
¶
Index ¶
- Constants
- func AllLicenses() map[string]LicenseRecord
- func BatchFetchGitHubLicenses(packages []PackageLicense, onProgress func(resolved, total int))
- func BatchFetchLicenses(packages []PackageLicense, onProgress func(resolved, total int))
- func BatchFetchRegistryLicenses(packages []PackageLicense, onProgress func(resolved, total int))
- func ClassifyLicenseText(text string) string
- func CountFindingsAtOrAbove(findings []Finding, threshold string) int
- func FetchContainerLicense(name, version, ecosystem string) string
- func FetchFromEcosystemRegistry(pkg PackageLicense) string
- func FetchLicenseFromDepsDev(name, version, ecosystem string) string
- func FetchLicenseFromGitHub(name, ecosystem string) string
- func FindLicenseInDir(dir string) string
- func FindLicenseInModuleCache(moduleName, version string) string
- func FindingsToCDXVulnerabilities(findings []Finding, packages []PackageLicense) []cdx.Vulnerability
- func MarshalSPDXJSON(doc *SPDXDocument) ([]byte, error)
- func MergeBOM(existingPath string, newVulns []cdx.Vulnerability, source string) error
- func NormalizeSPDX(id string) string
- func ParseSPDXExpression(expr string) []string
- func PopulateBOMLicenses(bomPath string, packages []PackageLicense, groups []scan.ManifestGroup)
- type AllowList
- type AnalysisResult
- type AnalysisSummary
- type Category
- type ConflictSeverity
- type EvalConfig
- type EvidenceStep
- type Finding
- type LicenseConflict
- type LicenseRecord
- type PackageLicense
- type SPDXCreationInfo
- type SPDXDocument
- type SPDXExternalRef
- type SPDXExtractedLicense
- type SPDXPackage
- type SPDXRelationship
Constants ¶
const CDXSourceName = "vulnetix-license-analyzer"
Variables ¶
This section is empty.
Functions ¶
func AllLicenses ¶
func AllLicenses() map[string]LicenseRecord
AllLicenses returns the full embedded SPDX license database.
func BatchFetchGitHubLicenses ¶
func BatchFetchGitHubLicenses(packages []PackageLicense, onProgress func(resolved, total int))
BatchFetchGitHubLicenses resolves licenses for GitHub-hosted packages concurrently. Handles github.com/ prefixed packages (Go), owner/repo packages (GHA, Terraform), and any other package that maps to a GitHub repository.
func BatchFetchLicenses ¶
func BatchFetchLicenses(packages []PackageLicense, onProgress func(resolved, total int))
BatchFetchLicenses resolves licenses for multiple packages concurrently via deps.dev. It modifies the slice in place, setting LicenseSpdxID and LicenseSource for resolved packages.
func BatchFetchRegistryLicenses ¶
func BatchFetchRegistryLicenses(packages []PackageLicense, onProgress func(resolved, total int))
BatchFetchRegistryLicenses resolves licenses for packages whose ecosystems have native registry APIs not covered by deps.dev. Modifies slice in place, setting LicenseSpdxID and LicenseSource = "registry" for resolved packages.
func ClassifyLicenseText ¶
ClassifyLicenseText identifies a license SPDX ID from the full text content. Uses keyword matching — not a full license parser, but handles the vast majority of standard open-source licenses.
func CountFindingsAtOrAbove ¶
CountFindingsAtOrAbove counts findings at or above the given severity threshold.
func FetchContainerLicense ¶
FetchContainerLicense attempts to resolve a license for a container image or infrastructure-as-code package. Tries local tools first, then registry APIs.
Handles:
- Docker/OCI images (podman/docker inspect → labels/annotations → registry)
- Terraform providers (registry API → GitHub source repo)
- Nix flakes (nix CLI if available)
func FetchFromEcosystemRegistry ¶
func FetchFromEcosystemRegistry(pkg PackageLicense) string
FetchFromEcosystemRegistry attempts to resolve a license from the package's native ecosystem registry for ecosystems not covered by deps.dev.
func FetchLicenseFromDepsDev ¶
FetchLicenseFromDepsDev queries api.deps.dev for a package's license. Returns the SPDX license ID or "" if not found/unsupported.
func FetchLicenseFromGitHub ¶
FetchLicenseFromGitHub resolves a license for a GitHub-hosted package. Uses a multi-strategy approach:
- GitHub repo API .license.spdx_id field (via gh CLI or REST API)
- Dedicated /repos/{owner}/{repo}/license endpoint
- Fetch LICENSE/COPYING file content and classify text
- Discover license files via directory listing
func FindLicenseInDir ¶
FindLicenseInDir searches for a license file in the given directory and classifies it. Works for any ecosystem where deps are on the filesystem.
func FindLicenseInModuleCache ¶
FindLicenseInModuleCache looks for a license file in the Go module cache for the given module and version, reads it, and classifies the license. Returns "" if not found or unclassifiable.
func FindingsToCDXVulnerabilities ¶
func FindingsToCDXVulnerabilities(findings []Finding, packages []PackageLicense) []cdx.Vulnerability
FindingsToCDXVulnerabilities converts license findings to CycloneDX vulnerability entries.
func MarshalSPDXJSON ¶
func MarshalSPDXJSON(doc *SPDXDocument) ([]byte, error)
MarshalSPDXJSON serialises an SPDX document to indented JSON.
func MergeBOM ¶
func MergeBOM(existingPath string, newVulns []cdx.Vulnerability, source string) error
MergeBOM reads an existing BOM from path, replaces all vulnerabilities with the given source name, appends the new vulnerabilities, and writes back. If the file doesn't exist, it creates a minimal BOM with just the new vulnerabilities.
func NormalizeSPDX ¶
NormalizeSPDX returns the canonical SPDX ID for a case-insensitive input, or the input unchanged if not found in the database.
func ParseSPDXExpression ¶
ParseSPDXExpression splits a simple SPDX license expression into constituent IDs. Handles "MIT", "MIT OR Apache-2.0", "GPL-2.0-only WITH Classpath-exception-2.0", and parenthesised groups. WITH exceptions are stripped.
func PopulateBOMLicenses ¶
func PopulateBOMLicenses(bomPath string, packages []PackageLicense, groups []scan.ManifestGroup)
PopulateBOMLicenses reads an existing BOM, populates component licenses and the dependency tree, then writes it back. This is used by the standalone license command to enrich an existing BOM without rebuilding it. If the BOM has no components, they are created from the package list.
Types ¶
type AllowList ¶
type AllowList struct {
Licenses []string `yaml:"licenses"`
}
AllowList is a set of approved SPDX license IDs.
func LoadAllowListFromFile ¶
LoadAllowListFromFile reads a YAML allow list file. Expected format:
licenses: - MIT - Apache-2.0
func ParseAllowListCSV ¶
ParseAllowListCSV parses a comma-separated list of SPDX IDs.
type AnalysisResult ¶
type AnalysisResult struct {
Mode string `json:"mode"`
Packages []PackageLicense `json:"packages"`
Conflicts []LicenseConflict `json:"conflicts"`
Findings []Finding `json:"findings"`
Summary AnalysisSummary `json:"summary"`
}
AnalysisResult is the complete output of a license analysis run.
func Evaluate ¶
func Evaluate(packages []PackageLicense, cfg EvalConfig) *AnalysisResult
Evaluate runs all license evaluation rules against the detected packages.
type AnalysisSummary ¶
type AnalysisSummary struct {
TotalPackages int `json:"totalPackages"`
LicenseCounts map[string]int `json:"licenseCounts"`
CategoryCounts map[Category]int `json:"categoryCounts"`
ConflictCount int `json:"conflictCount"`
FindingsBySev map[string]int `json:"findingsBySeverity"`
OsiApproved int `json:"osiApproved"`
FsfLibre int `json:"fsfLibre"`
Deprecated int `json:"deprecated"`
Unknown int `json:"unknown"`
}
AnalysisSummary provides aggregate counts.
type Category ¶
type Category string
Category classifies a license by its copyleft characteristics.
func ClassifyCategory ¶
ClassifyCategory returns the license category for a given SPDX ID.
type ConflictSeverity ¶
ConflictSeverity describes a conflict rule result.
func CategoryConflict ¶
func CategoryConflict(cat1, cat2 Category) *ConflictSeverity
CategoryConflict checks if two license categories conflict and returns severity info. Returns nil if the combination is compatible.
func IDConflict ¶
func IDConflict(id1, id2 string) *ConflictSeverity
IDConflict checks for specific SPDX ID pair overrides. Returns nil if no specific rule exists.
type EvalConfig ¶
type EvalConfig struct {
Mode string // "inclusive" or "individual"
AllowedLicenses []string // SPDX IDs; empty = no allow list
SeverityThreshold string // "critical", "high", "medium", "low"
}
EvalConfig controls evaluation behaviour.
type EvidenceStep ¶
type EvidenceStep struct {
Rule string `json:"rule"`
Input string `json:"input"`
Expected string `json:"expected,omitempty"`
Actual string `json:"actual,omitempty"`
Result string `json:"result"` // "PASS" or "FAIL"
}
EvidenceStep is one step in a rule evaluation trace.
type Finding ¶
type Finding struct {
ID string `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
Severity string `json:"severity"`
Confidence float64 `json:"confidence"`
Package PackageLicense `json:"package"`
Category string `json:"category"` // rule category
Evidence []EvidenceStep `json:"evidence"`
IntroducedPaths [][]string `json:"introducedPaths,omitempty"`
PathCount int `json:"pathCount,omitempty"`
}
Finding is a single license issue produced by evaluation.
type LicenseConflict ¶
type LicenseConflict struct {
Type string `json:"type"` // "incompatible", "copyleft-mixing", "deprecated", "version-incompatible"
Severity string `json:"severity"` // critical, high, medium, low
License1 string `json:"license1"`
License2 string `json:"license2"`
Package1 string `json:"package1"`
Package2 string `json:"package2"`
Description string `json:"description"`
Recommendation string `json:"recommendation"`
Package1Paths [][]string `json:"package1Paths,omitempty"`
Package2Paths [][]string `json:"package2Paths,omitempty"`
}
LicenseConflict describes an incompatibility between two licenses.
type LicenseRecord ¶
type LicenseRecord struct {
SpdxID string `json:"spdxId" yaml:"spdx_id"`
Name string `json:"name" yaml:"name"`
Category Category `json:"category" yaml:"category"`
IsOsiApproved bool `json:"isOsiApproved" yaml:"osi_approved"`
IsFsfLibre bool `json:"isFsfLibre" yaml:"fsf_libre"`
IsDeprecated bool `json:"isDeprecated" yaml:"deprecated"`
}
LicenseRecord describes a single SPDX license entry.
func LookupSPDX ¶
func LookupSPDX(id string) *LicenseRecord
LookupSPDX returns the license record for the given SPDX ID, or nil if not found. Lookup is case-insensitive.
type PackageLicense ¶
type PackageLicense struct {
PackageName string `json:"packageName"`
PackageVersion string `json:"packageVersion"`
Ecosystem string `json:"ecosystem"`
Scope string `json:"scope"`
LicenseSpdxID string `json:"licenseSpdxId"`
LicenseSource string `json:"licenseSource"` // "manifest", "lockfile", "embedded-db"
SourceFile string `json:"sourceFile"`
IsDirect bool `json:"isDirect"`
GitHubURL string `json:"-"` // optional: "owner/repo" from manifest, used for license resolution
Record *LicenseRecord `json:"record,omitempty"`
IntroducedPaths [][]string `json:"introducedPaths,omitempty"`
PathCount int `json:"pathCount,omitempty"`
}
PackageLicense ties a detected package to its resolved license.
func DetectLicenses ¶
func DetectLicenses(packages []scan.ScopedPackage, groups []scan.ManifestGroup) []PackageLicense
DetectLicenses takes already-parsed packages and resolves their licenses. It reads the original manifest files to extract license fields where possible, falling back to the embedded SPDX database for well-known packages. When groups is non-nil, dependency paths are computed for each package.
type SPDXCreationInfo ¶
type SPDXCreationInfo struct {
Created string `json:"created"`
Creators []string `json:"creators"`
}
SPDXCreationInfo describes when and by whom the SPDX document was created.
type SPDXDocument ¶
type SPDXDocument struct {
SPDXVersion string `json:"spdxVersion"`
DataLicense string `json:"dataLicense"`
SPDXID string `json:"SPDXID"`
Name string `json:"name"`
DocumentNamespace string `json:"documentNamespace"`
CreationInfo SPDXCreationInfo `json:"creationInfo"`
Packages []SPDXPackage `json:"packages"`
Relationships []SPDXRelationship `json:"relationships,omitempty"`
ExtractedLicensingInfos []SPDXExtractedLicense `json:"extractedLicensingInfos,omitempty"`
}
SPDXDocument represents an SPDX 2.3 JSON document.
func BuildSPDXDocument ¶
func BuildSPDXDocument(result *AnalysisResult, name string) *SPDXDocument
BuildSPDXDocument creates an SPDX 2.3 JSON document from license analysis results.
type SPDXExternalRef ¶
type SPDXExternalRef struct {
ReferenceCategory string `json:"referenceCategory"`
ReferenceType string `json:"referenceType"`
ReferenceLocator string `json:"referenceLocator"`
}
SPDXExternalRef is a package external reference.
type SPDXExtractedLicense ¶
type SPDXExtractedLicense struct {
LicenseID string `json:"licenseId"`
ExtractedText string `json:"extractedText"`
Name string `json:"name"`
}
SPDXExtractedLicense captures non-standard license text.
type SPDXPackage ¶
type SPDXPackage struct {
SPDXID string `json:"SPDXID"`
Name string `json:"name"`
VersionInfo string `json:"versionInfo,omitempty"`
DownloadLocation string `json:"downloadLocation"`
LicenseConcluded string `json:"licenseConcluded"`
LicenseDeclared string `json:"licenseDeclared"`
CopyrightText string `json:"copyrightText"`
FilesAnalyzed bool `json:"filesAnalyzed"`
ExternalRefs []SPDXExternalRef `json:"externalRefs,omitempty"`
}
SPDXPackage is an SPDX package entry.
type SPDXRelationship ¶
type SPDXRelationship struct {
Element string `json:"spdxElementId"`
RelType string `json:"relationshipType"`
RelatedElement string `json:"relatedSpdxElement"`
}
SPDXRelationship defines a relationship between SPDX elements.