Skip to contents

sbom_package() describes one package and everything it depends on. sbom_installed() describes the packages in an R library. Both read the DESCRIPTION files that are on disk and nothing else: they run no package code and make no network requests, except that advisories = TRUE downloads OSV's advisory data.

Usage

sbom_package(
  path = ".",
  dependencies = c("Depends", "Imports", "LinkingTo", "Suggests"),
  lib = .libPaths(),
  r_version = NULL,
  author = getOption("sbom.author"),
  organization = getOption("sbom.organization"),
  regid = getOption("sbom.regid"),
  timestamp = NULL,
  overrides = NULL,
  embedded = TRUE,
  system = TRUE,
  advisories = FALSE,
  advisories_on_error = c("error", "continue")
)

sbom_installed(
  pkgs = NULL,
  lib = .libPaths(),
  name = "R library",
  r_version = NULL,
  author = getOption("sbom.author"),
  organization = getOption("sbom.organization"),
  regid = getOption("sbom.regid"),
  timestamp = NULL,
  overrides = NULL,
  embedded = TRUE,
  system = TRUE,
  advisories = FALSE,
  advisories_on_error = c("error", "continue")
)

Arguments

path

A package directory, a DESCRIPTION file or a source tarball (.tar.gz). A tarball is also hashed, and its file name recorded.

dependencies

The DESCRIPTION fields to follow, from "Depends", "Imports", "LinkingTo" and "Suggests". Only the root's own Suggests are listed, and the packages they name are not followed.

lib

Library paths to read installed packages from. Each must exist. When a package is in more than one, the first path wins, as it does when R loads it.

r_version

The R version, as a string, to record exactly. NULL picks it as described in Details.

author, organization

Who made the SBOM, recorded in its metadata. author may name several people; NA and empty names are dropped. Without either, an issue is recorded.

regid

The registration id of organization: the domain name, or URL, of the organization, under which it registers SWID tags (ISO/IEC 19770-2). A SWID tag names the organization as its creator with this regid. It must be a single string, from which leading and trailing white space is dropped. NULL, NA and an empty or blank string mean none; then the tag uses the placeholder http://invalid.unavailable, and when an organization was given, an issue is recorded. The default is the sbom.regid option, as author and organization read sbom.author and sbom.organization.

timestamp

The creation time, as a date-time or as seconds since 1970-01-01 UTC. An explicit timestamp wins. Without one, the SOURCE_DATE_EPOCH environment variable is used when it is set, so that builds are reproducible, and a note says so; otherwise it is now. Nix sets SOURCE_DATE_EPOCH to 1980-01-01 in every nix-shell, and when the timestamp is that value a note says it is a placeholder.

overrides

Values to assert where sbom found none, or found something different. NULL, a data frame or the path to a CSV file, with the character columns component (the name or ref of one component, as sbom built it, before any row moves it; embedded and system components only by ref), field, value, asserted_by and reason. field is one of "version", "license_spdx", "supplier_name", "supplier_url", "maintainer", "purl" and "download_location". Rows are applied in order, and each is recorded with who asserted it and why. An override that contradicts a found value wins and adds an override-conflict issue. Asserting "version" makes it the exact version, and moves the component's package URL to it unless a row asserts the "purl": a package URL at the old version takes the new one, and one without a version gains it when its type is cran, github, gitlab or bitbucket. A package file named for the old version is renamed for the new one, and any other is dropped, as are the checksums of the version found. An asserted version of R is also the version of the base packages, each with a record of the assertion. Asserting a CRAN "purl" (pkg:cran) makes the component a CRAN package, or a Bioconductor package when its repository_url names bioconductor.org. When a component's ref is its package URL, the ref follows the package URL that the overrides leave, and every reference to it moves too; a ref that another component already has is an error. Any other ref, such as unknown/<name>, stays as it is. An asserted field removes the component's issues that it answers, such as version-missing or purl-inferred. An issue that also states a fact that stays true is reworded instead, as info: that a package came from a git repository, once its package URL is asserted; that a dependency is missing, once its version and package URL are both asserted; and that a LinkingTo package is not installed, once its version is. The issues that name the components without a version, such as system-version-unknown, name only those still without one, and go when none is left. A blank value, an unknown component or field, or a missing column, is an error.

embedded

Whether to record the code that packages carry inside them. A package named in LinkingTo is recorded as an embedded component of the package that compiles it in, nested under that package, as inferred, at the version and with the license that the library, lockfile or manifest records for it now. A C or C++ library that a package copies into its src/ folder (source packages), or names in its COPYRIGHTS file or cph entries (source and installed packages), is recorded as a vendored component of that package, from the rules in inst/extdata/vendored.csv. The version is read from the library's header when there is one, and is otherwise unknown. A JavaScript or CSS library declared in htmlwidgets YAML, or found by the header comment of a file under www/, htmlwidgets/lib/ or lib/ (under inst/ in source packages), is recorded as an npm component of that package, from the rules in inst/extdata/javascript.csv. Its license is not read.

system

Whether to detect system libraries. A package's SystemRequirements text is mapped to system libraries and programs with the rules of the pak package, when it is installed. sbom turns off pak's update of those rules, so pak uses the rules it has cached or ships and makes no network request. The shared libraries that installed compiled code links are read with otool (macOS) or ldd (Linux).

advisories

Whether to list the OSV security advisories for the SBOM's packages, from the R Consortium advisory database that OSV publishes; see sbom_advisories(). Only exact versions are compared, of the packages whose package URL is a CRAN one (pkg:cran), packages from CRAN-like repositories among them, matched by name. A package with a CRAN package URL and a minimum version, or none, is named in an advisories-no-exact-version issue. An R package that is not known to come from CRAN, because sbom could not tell where it came from (as for a package that is not installed), or because it was installed from a local source or from GitHub, GitLab, Bitbucket or git, is named in an advisories-not-cran issue. Bioconductor packages are not compared: OSV does not cover them yet, and when the SBOM holds one a note says so. Matching is local, with the versions and package URLs after overrides, so no package name leaves the machine.

FALSE, the default, lists none, makes no network request and adds a note that no advisory data was on hand. TRUE downloads OSV's CRAN export, https://osv-vulnerabilities.storage.googleapis.com/CRAN/all.zip, and looks up the CVSS ratings of the upstream records it names at https://api.osv.dev, sending only their public ids. On a machine without network access, download that all.zip elsewhere and pass its path: it is read where it is, without the network and without ratings.

The SBOM lists what OSV says about these exact versions: a package without an advisory is not shown to be free of flaws, and an upstream CVSS rating describes the upstream flaw, not how exposed the R package is.

advisories_on_error

What happens when the advisory data cannot be downloaded or read, as when the download fails or the zip is damaged: "error", the default, is an error of class sbom_advisories_error that names the problem; "continue" builds the SBOM without advisories, with an R warning of class sbom_advisories_unavailable, a warning issue and a note that no advisory data was on hand. A download larger than 50 MB is refused as an error too. A CVSS rating that cannot be looked up never fails the call: it is left out, with an issue. The lookups stop at the first that times out or fails at the connection, and take at most two minutes in all.

pkgs

Names of the installed packages to list. NULL lists every package in lib, and an issue is recorded when there are none. The dependencies of the listed packages are listed too. A name that is not installed in lib, other than a base package, is an error.

name

The name of the library, used for its root component.

Value

An <sbom> object. See sbom_components() to read it.

Details

The root of sbom_package() is the package at path, recorded as declared. Every dependency is looked up in lib and recorded as observed, at the version installed there. A dependency that is not installed becomes an unknown component with an issue, and an installed version that fails the declared constraint is listed as installed, with an issue. Packages reached only through Suggests have scope "optional".

R is always a component. When lib is the current library search path and r_version is NULL, it is listed at the running version. With any other library, the lowest version that the dependency tree states, the highest R (>= x) found, is used as a minimum. The base packages used come with R: when R's version is exact, they are listed at that version, with R's evidence, and otherwise without a version.

Examples

x <- sbom_package(system.file("DESCRIPTION", package = "sbom"), system = FALSE)
x
#> <sbom> sbom 0.1.0
#> Components: 19
#> Relationships: 28
#> Issues: 3 (see sbom_issues())
#> Advisories: not requested.
sbom_installed("sbom", system = FALSE)
#> <sbom> R library
#> Components: 10
#> Relationships: 19
#> Issues: 3 (see sbom_issues())
#> Advisories: not requested.