Documentation
¶
Overview ¶
Package types defines shared data structures for supplyscan.
Index ¶
- Constants
- Variables
- func NormalizePyPIName(name string) string
- type CheckResult
- type CheckSupplyChainResult
- type CheckTiming
- type CompromisedPackage
- type CoverageGap
- type Dependency
- type IOCDatabase
- type IOCDatabaseStatus
- type IOCMeta
- type IssueCounts
- type LockfileInfo
- type LockfileTiming
- type RefreshResult
- type RefreshTiming
- type ScanResult
- type ScanSummary
- type ScanTiming
- type SkippedLockfile
- type SourceData
- type SourcePackage
- type SourceRefreshInfo
- type SourceStatusInfo
- type StatusResponse
- type SupplyChainAdvisory
- type SupplyChainFinding
- type SupplyChainResult
- type SupplyChainWarning
- type VulnerabilityFinding
- type VulnerabilityInfo
- type VulnerabilityResult
- type WorkspaceCoverage
Constants ¶
const ( SeverityCritical = "critical" SeverityHigh = "high" SeverityModerate = "moderate" SeverityLow = "low" SeverityInfo = "info" SeverityUnknown = "unknown" )
severity indicates the threat level of a vulnerability or supply chain compromise. it is used in both supply chain and vulnerability findings.
const ( EcosystemNPM = "npm" EcosystemPyPI = "pypi" )
Ecosystem identifies the package registry a dependency belongs to. Package names collide across registries (both npm and PyPI ship a "requests", "six", etc.) so IOC matching must be scoped by ecosystem, not name alone.
Variables ¶
var SupportedLockfiles = []string{
"package-lock.json",
"npm-shrinkwrap.json",
"yarn.lock",
"pnpm-lock.yaml",
"bun.lock",
"deno.lock",
"requirements.txt",
"poetry.lock",
"Pipfile.lock",
"uv.lock",
"pdm.lock",
}
SupportedLockfiles is the list of lockfile formats we can parse.
var Version = "dev"
Version is the application version. Set at build time via -ldflags. Falls back to module version from go install, or "dev" for local builds.
Functions ¶
func NormalizePyPIName ¶
NormalizePyPIName applies PEP 503 normalisation: lowercase and collapse any run of "-", "_" or "." into a single "-". OSV stores PyPI names normalised, so we normalise lockfile names the same way for matching to line up.
Types ¶
type CheckResult ¶
type CheckResult struct {
SupplyChain CheckSupplyChainResult `json:"supply_chain"`
Vulnerabilities []VulnerabilityInfo `json:"vulnerabilities"`
// AuditError is set when the vuln-audit backend failed, so an unreachable API
// is distinguishable from a package with no known vulnerabilities.
AuditError string `json:"audit_error,omitempty"`
Timing *CheckTiming `json:"timing,omitempty"`
}
CheckResult is the output of checking a single package.
type CheckSupplyChainResult ¶
type CheckSupplyChainResult struct {
Compromised bool `json:"compromised"`
Campaign string `json:"campaign,omitempty"` // Deprecated: use Campaigns instead
Campaigns []string `json:"campaigns,omitempty"` // Attack campaigns that flagged this
AdvisoryIDs []string `json:"advisory_ids,omitempty"` // GHSA IDs, CVE IDs, etc.
Sources []string `json:"sources,omitempty"` // IOC sources that reported this
}
CheckSupplyChainResult indicates if a package is compromised.
type CheckTiming ¶
type CheckTiming struct {
TotalMs int64 `json:"total_ms"`
IOCLoadMs int64 `json:"ioc_load_ms"`
SupplyChainMs int64 `json:"supply_chain_ms"`
AuditMs int64 `json:"audit_ms"`
}
CheckTiming records timing for a single package check.
type CompromisedPackage ¶
type CompromisedPackage struct {
Name string `json:"name"`
Ecosystem string `json:"ecosystem,omitempty"` // "npm" (default when empty) or "pypi"
Versions []string `json:"versions"`
Sources []string `json:"sources"`
Campaigns []string `json:"campaigns,omitempty"` // Multiple campaigns that flagged this package
AdvisoryIDs []string `json:"advisory_ids,omitempty"` // GHSA IDs, CVE IDs, etc.
FirstSeen string `json:"first_seen,omitempty"` // When first detected (RFC3339)
}
CompromisedPackage represents a known malicious package from IOC data.
type CoverageGap ¶ added in v1.16.0
type CoverageGap struct {
Path string `json:"path"`
Kind string `json:"kind"` // "unpinned_dependency" | "manifest_without_lockfile"
Detail string `json:"detail"`
}
CoverageGap records something present in the project that could not be audited (an unpinned requirement, or a manifest with no lockfile). Surfacing these keeps a clean scan from implying coverage it doesn't have.
type Dependency ¶
type Dependency struct {
Name string `json:"name"`
Version string `json:"version"`
Ecosystem string `json:"ecosystem,omitempty"` // "npm" (default when empty) or "pypi"
Dev bool `json:"dev,omitempty"`
Optional bool `json:"optional,omitempty"`
Resolved string `json:"resolved,omitempty"` // resolved download URL, when the lockfile records one
HasInstallScript bool `json:"has_install_script,omitempty"` // runs a lifecycle/install script (npm)
}
Dependency represents a single package dependency from a lockfile.
type IOCDatabase ¶
type IOCDatabase struct {
Packages map[string]CompromisedPackage `json:"packages"`
LastUpdated string `json:"last_updated"`
Sources []string `json:"sources"`
}
IOCDatabase represents the cached IOC data.
type IOCDatabaseStatus ¶
type IOCDatabaseStatus struct {
Packages int `json:"packages"`
Versions int `json:"versions"`
LastUpdated string `json:"last_updated"`
Sources []string `json:"sources"`
SourceDetails map[string]SourceStatusInfo `json:"source_details,omitempty"` // Per-source details
}
IOCDatabaseStatus reports on the IOC database state.
type IOCMeta ¶
type IOCMeta struct {
LastUpdated string `json:"last_updated"`
ETag string `json:"etag,omitempty"`
PackageCount int `json:"package_count"`
VersionCount int `json:"version_count"`
SourceStatuses map[string]SourceStatusInfo `json:"source_statuses,omitempty"` // Per-source status
}
IOCMeta contains metadata about the IOC cache.
type IssueCounts ¶
type IssueCounts struct {
Critical int `json:"critical"`
High int `json:"high"`
Moderate int `json:"moderate"`
SupplyChain int `json:"supply_chain"`
}
IssueCounts breaks down issues by severity.
type LockfileInfo ¶
type LockfileInfo struct {
Path string `json:"path"`
Type string `json:"type"`
Dependencies int `json:"dependencies"`
}
LockfileInfo contains metadata about a parsed lockfile.
type LockfileTiming ¶
type LockfileTiming struct {
Path string `json:"path"`
ParseMs int64 `json:"parse_ms"`
SupplyChainMs int64 `json:"supply_chain_ms"`
AuditMs int64 `json:"audit_ms"`
TotalMs int64 `json:"total_ms"`
}
LockfileTiming records per-lockfile phase timing.
type RefreshResult ¶
type RefreshResult struct {
Updated bool `json:"updated"`
PackagesCount int `json:"packages_count"`
VersionsCount int `json:"versions_count"`
CacheAgeHours int `json:"cache_age_hours"`
SourceResults map[string]SourceRefreshInfo `json:"source_results,omitempty"` // Per-source refresh results
Timing *RefreshTiming `json:"timing,omitempty"`
}
RefreshResult is the output of refreshing the IOC database.
type RefreshTiming ¶
type RefreshTiming struct {
TotalMs int64 `json:"total_ms"`
Sources map[string]int64 `json:"sources,omitempty"`
}
RefreshTiming records timing for the refresh operation.
type ScanResult ¶
type ScanResult struct {
Summary ScanSummary `json:"summary"`
SupplyChain SupplyChainResult `json:"supply_chain"`
Vulnerabilities VulnerabilityResult `json:"vulnerabilities"`
Lockfiles []LockfileInfo `json:"lockfiles"`
Skipped []SkippedLockfile `json:"skipped,omitempty"`
Coverage []CoverageGap `json:"coverage,omitempty"`
WorkspaceCoverage []WorkspaceCoverage `json:"workspace_coverage,omitempty"`
// AuditErrors records vuln-audit backends that failed (npm/OSV unreachable or
// erroring) so a scan that could not reach an audit API reads differently from
// a genuinely clean one rather than silently reporting no findings.
AuditErrors []string `json:"audit_errors,omitempty"`
// Timing not shown by default, pass --time to the cli to see
Timing *ScanTiming `json:"timing,omitempty"`
}
ScanResult is the complete output of a security scan.
type ScanSummary ¶
type ScanSummary struct {
LockfilesScanned int `json:"lockfiles_scanned"`
LockfilesSkipped int `json:"lockfiles_skipped,omitempty"`
TotalDependencies int `json:"total_dependencies"`
CoverageGaps int `json:"coverage_gaps,omitempty"`
Issues IssueCounts `json:"issues"`
}
ScanSummary contains aggregated scan statistics.
type ScanTiming ¶
type ScanTiming struct {
TotalMs int64 `json:"total_ms"`
IOCLoadMs int64 `json:"ioc_load_ms"`
FindLockfilesMs int64 `json:"find_lockfiles_ms"`
Lockfiles []LockfileTiming `json:"lockfiles,omitempty"`
}
ScanTiming records per-phase timing for a scan operation.
type SkippedLockfile ¶ added in v1.16.0
SkippedLockfile records a lockfile that was discovered but could not be scanned (e.g. unreadable or an unrecognised format).
type SourceData ¶
type SourceData struct {
// Source is the name of the IOC provider (e.g., "datadog", "github").
Source string `json:"source"`
// Campaign identifies the attack campaign (e.g., "shai-hulud-v2", "GHSA-xxx").
Campaign string `json:"campaign"`
// Packages maps package names to their compromised version information.
Packages map[string]SourcePackage `json:"packages"`
// FetchedAt is when this data was retrieved.
FetchedAt string `json:"fetched_at"`
// Partial is set when the fetch returned an incomplete result (e.g. pagination
// failed midway). Partial data is still usable for the current run but must not
// be cached as authoritative.
Partial bool `json:"-"`
}
SourceData contains IOC data retrieved from a single source.
type SourcePackage ¶
type SourcePackage struct {
// Name is the package name (e.g., "lodash", "@ctrl/tinycolor", "litellm").
Name string `json:"name"`
// Ecosystem is the registry the package belongs to ("npm" or "pypi").
// Empty is treated as "npm" for backwards compatibility.
Ecosystem string `json:"ecosystem,omitempty"`
// Versions lists the compromised versions.
Versions []string `json:"versions"`
// AdvisoryID is an optional identifier (e.g., "GHSA-xxx", "CVE-xxx").
AdvisoryID string `json:"advisory_id,omitempty"`
// Severity indicates the threat level (e.g., "critical", "high").
Severity string `json:"severity,omitempty"`
}
SourcePackage represents a compromised package from a single source.
type SourceRefreshInfo ¶
type SourceRefreshInfo struct {
Name string `json:"name"`
Updated bool `json:"updated"`
PackageCount int `json:"package_count"`
Error string `json:"error,omitempty"`
FetchMs int64 `json:"fetch_ms,omitempty"`
}
SourceRefreshInfo contains the result of refreshing a single IOC source.
type SourceStatusInfo ¶
type SourceStatusInfo struct {
LastFetched string `json:"last_fetched"`
Success bool `json:"success"`
Error string `json:"error,omitempty"`
PackageCount int `json:"package_count"`
}
SourceStatusInfo contains status information for a single IOC source.
type StatusResponse ¶
type StatusResponse struct {
Version string `json:"version"`
IOCDatabase IOCDatabaseStatus `json:"ioc_database"`
SupportedLockfiles []string `json:"supported_lockfiles"`
}
StatusResponse is the output of the status tool.
type SupplyChainAdvisory ¶
type SupplyChainAdvisory struct {
Type string `json:"type"` // "install_script" | "suspicious_unicode"
Package string `json:"package"`
InstalledVersion string `json:"installed_version"`
Ecosystem string `json:"ecosystem,omitempty"`
Detail string `json:"detail,omitempty"` // e.g. the offending codepoint
Note string `json:"note"`
Lockfile string `json:"lockfile,omitempty"`
}
SupplyChainAdvisory is a low-noise heuristic flag that complements IOC matching. It is advisory only and does not affect exit status: the package isn't known-compromised, but it carries a trait worth a human glance (an install script, or non-ASCII/invisible characters in its name or URL).
type SupplyChainFinding ¶
type SupplyChainFinding struct {
Severity string `json:"severity"`
Type string `json:"type"`
Package string `json:"package"`
InstalledVersion string `json:"installed_version"`
CompromisedVersions []string `json:"compromised_versions,omitempty"`
SafeVersion string `json:"safe_version,omitempty"`
Lockfile string `json:"lockfile"`
Action string `json:"action"`
Campaigns []string `json:"campaigns,omitempty"` // Attack campaigns that flagged this
AdvisoryIDs []string `json:"advisory_ids,omitempty"` // GHSA IDs, CVE IDs, etc.
Sources []string `json:"sources,omitempty"` // IOC sources that reported this
}
SupplyChainFinding represents a detected supply chain compromise.
type SupplyChainResult ¶
type SupplyChainResult struct {
Findings []SupplyChainFinding `json:"findings"`
Warnings []SupplyChainWarning `json:"warnings"`
Advisories []SupplyChainAdvisory `json:"advisories,omitempty"`
}
SupplyChainResult contains all supply chain findings.
type SupplyChainWarning ¶
type SupplyChainWarning struct {
Type string `json:"type"`
Package string `json:"package"`
InstalledVersion string `json:"installed_version"`
Namespace string `json:"namespace,omitempty"` // e.g. "@tanstack"
Campaign string `json:"campaign,omitempty"` // e.g. "TeamPCP / Mini Shai-Hulud"
CampaignWhen string `json:"campaign_when,omitempty"` // e.g. "Apr–May 2026"
Note string `json:"note"`
}
SupplyChainWarning represents a package from an at-risk namespace. It is informational only — the installed version is not on any IOC list, but the namespace has been targeted by a past supply-chain campaign.
type VulnerabilityFinding ¶
type VulnerabilityFinding struct {
Severity string `json:"severity"`
Package string `json:"package"`
InstalledVersion string `json:"installed_version"`
ID string `json:"id"`
Title string `json:"title"`
PatchedIn string `json:"patched_in,omitempty"`
Lockfile string `json:"lockfile"`
}
VulnerabilityFinding represents a known security vulnerability.
type VulnerabilityInfo ¶
type VulnerabilityInfo struct {
ID string `json:"id"`
Severity string `json:"severity"`
Title string `json:"title"`
PatchedIn string `json:"patched_in,omitempty"`
}
VulnerabilityInfo is a simplified vulnerability record.
type VulnerabilityResult ¶
type VulnerabilityResult struct {
Findings []VulnerabilityFinding `json:"findings"`
}
VulnerabilityResult contains all vulnerability findings.
type WorkspaceCoverage ¶ added in v1.16.0
type WorkspaceCoverage struct {
Manifest string `json:"manifest"` // the member manifest (e.g. apps/web/package.json)
Lockfile string `json:"lockfile"` // the workspace root lockfile that covers it
}
WorkspaceCoverage records a manifest that has no co-located lockfile but is a member of a workspace whose root lockfile we scanned, i.e. its dependencies were audited via that root rather than being a coverage gap.