MAN-03 Supply Chain Management: Software Dependencies
Manual for software dependency configuration management using Ketryx Software Supply Chain Management
Last updated
Manual for software dependency configuration management using Ketryx Software Supply Chain Management
Last updated
© 2024 Ketryx Corporation
This manual assumes you have access to Ketryx Software Supply Chain Configuration Management, and have created an Organization with Members and Groups.
The purpose of this manual is to instruct users on how to use Ketryx Software Supply Chain Configuration Management to manage software dependencies.
This manual describes how to use Ketryx Software Supply Chain Configuration Management to manage software dependencies including open-source software, and other Software of Unknown Provenance (SOUP).
The definitions of this document conform to the ones of ISO/IEC 62304.
User logs into Ketryx Platform at app.ketryx.com by using their connected Google or GitHub account, or using their email addresses.
User presses the Create project button to create a new project.
User inputs a project name and Git repository URL.
Optionally, the user can specify the main branch or tag to analyze. Otherwise, the default HEAD
branch (usually called main
or master
) will be used.
In addition, the user can specify a release ref pattern, informing how a branch or tag corresponding to each project version is determined. By default, this will be set to refs/tags/v#
. The placeholder #
is replaced by (a part of) the version number of a given version until a match is found; e.g., for a version with the full name App v1.0
(which implies a version number 1.0.0
), the tag names v1.0.0
, v1.0
, v1
would be searched; if the tag v1.0.0
does not exist but v1.0
exists, that tag v1.0
would be associated with the version.
The user can use glob patterns to restrict which dependency manifest files (e.g. a package.json
file) and locked dependency manifest files (e.g. a package-lock.json
file) will be included in the dependency scanning. These glob patterns define the locations of dependency manifest files within a Git repository and Ketryx will scan the repository for files that match these patterns. For example:
Ketryx will scan the repository for:
All files named requirements.txt
in the server/
directory and all its subdirectories
All supported dependency manifest files (including locked dependency manifest files) in the wwwroot/
directory and all its subdirectories
Omit all files in the tests/
directory and all its subdirectories
Then, the user presses the Create project button. The direct dependencies of the repository will be automatically scanned and shown in the dependency screen.
The Dependency screen lists each direct dependency detected as detailed in the dependency scanning section. For each dependency, information is given on its name, used version(s), risk level, vulnerabilities, and status.
The dependency Name column is derived from the dependency files. Note that Java dependencies are specified in the format organizationId:artifactId.
The Used version(s) column is derived from the dependency files. When no locked version can be detected, the used version(s) will show a declared version only.
The Risk level column will store the user-defined risk level upon dependency editing. See dependency editing for information on how to apply a risk level to a dependency.
The Vulnerabilities column shows a warning icon as well as the CVSS v3 severity rating (none, low, medium, high, critical) for each vulnerable dependency. Press the icon for information on the vulnerability name, description, CVE ID, published date, severity score, affected version, and external URLs for more details. See also the Cybersecurity section for details.
The Status column shows the current acceptance status of each dependency. Besides the empty state which indicates that a dependency has not yet been worked on, there are six states a dependency can be in. Namely:
Draft ✔ means that changes have been made to this dependency and once fully approved and moved into a controlled state, it would result in this dependency being accepted, indicated by the checkmark icon on the right.
Draft 𝗫 means that changes have been made to this dependency and once fully approved and moved into a controlled state, it would result in this dependency being rejected, indicated by the X icon on the right.
Accepted ✔ means that a dependency has been fully approved and moved into a controlled state and its usage being accepted.
Rejected 𝗫 means that a dependency has been fully approved and moved into a controlled state and its usage being rejected.
Changed ✔ means that a dependency has been edited after being in a controlled state and the changes would result in this dependency being accepted, indicated by the checkmark icon on the right.
Changed 𝗫 means that a dependency has been edited after being in a controlled state and the changes would result in this dependency being rejected, indicated by the X icon on the right.
Hovering over the status will show information about which groups have already approved a dependency:
Ketryx Platform allows users to mark individual direct dependencies as “approved”, enforcing user-specified approval steps and enabling security and usage metadata to be customized for each dependency.
To approve a dependency, the user must first set up approval steps, as detailed in the Ketryx Installation Guide.
To approve one or more dependencies using the default settings (i.e., accepting the currently used version), the batch approval workflow can be used on the dependencies screen.
Many dependencies can be added automatically by Ketryx by scanning and parsing different types of package manifest files. See dependency scanning. But there are also dependencies on SOUP items that are not explicitly declared in code. These can be manually created in Ketryx with some caveats listed below.
To create a manual dependency, click on the Create dependency button on the dependency screen above the table.
This will open a new page where at least a name for the manual dependency has to be declared. All other inputs are optional.
By default, all versions of the dependency will be set as accepted since there is no source of truth to match against in this case. Custom versions can still be declared to indicate that a certain version of a dependency is accepted or rejected.
While manually created dependencies behave just like the ones scanned automatically by Ketryx in terms of their approval workflow, they differ in certain ways. For example, they don't have their version automatically parsed from a source of truth but rather rely on manual updates by users of Ketryx.
Additionally, Ketryx does not attempt to scan for vulnerabilities for manually created dependencies. Rather, they have to be defined manually as well but do not count towards any vulnerability count on dashboards.
Dependencies can be edited by clicking on their name in the dependencies screen and then clicking Edit dependency on their detail page. Some of their metadata can be changed or supplemented, such as:
Intended use
Security impact
Security impact justification
Reliability impact
Reliability impact justification
Additional notes
Versions to accept
Risk level
Issue tracker (URL)
Manufacturer
License
For manually created dependencies these details can be edited as well:
Name
Vulnerabilities
For each dependency, you have fine-grained control over which versions you accept. For dependencies found in package manifest (lock) files (see dependency scanning), if available, the locked version will be selected, or else the declared version. Additionally, you can select a custom version (range) or simply accept All versions or None.
The accepted version is checked against the used versions found in the package manifest (lock) files. E.g. if in your package-lock.json
file version 2.6.0
of a dependency is found but a custom accepted version range of ^2.9.0
was defined, e.g. because a vulnerability was found in versions less than 2.9.0
, this version would not be accepted and the current usage of this dependency would result in a rejection once put into a controlled state. See below for an example.
When approving custom versions, enter SemVer-compatible version specifications. SemVer-compatible version ranges include:
> =1.0.0
> 1.0.0
(see the section on caveats)
> <1.0.0
> <=1.0.0
> ^1.0.0
> 1.2.3 - 2.3.4
*
~1.0.0
> =0.14 <16
> 0.14.x || 15.x.x
For more information on what each of these ranges means, a helpful resource is this SemVer document.
When entering version ranges for approval, note that whether a dependency is approved is checked following SemVer rules, which differ from standard math. E.g., if approving a range >1
, this does not include the version 1.19.4
, and >2
does not include 2.6.0
. In accordance with SemVer rules, approving either >1.0.0
or >=1
does approve the version 1.19.4
.
Once a dependency is approved, a user can revoke their approval.
Navigate to the history page by clicking History in the sidebar menu. Each given approval will show up as an individual row.
To revoke a particular approval for a dependency, click the Revoke approval button on the right-hand side of the row.
Ketryx scans the GitHub Advisory Database to detect vulnerabilities in the direct dependencies of each project found in supported package manifest files.
When a dependency is found to have a relevant vulnerability (i.e. the dependency versions are within the affected versions of a given vulnerability), a warning will show up on its dependency row. Clicking this warning will give more information on the details, the CVE ID, the published date, the severity, the affected version range, and URLs leading to more information.
These vulnerabilities are also reported in the generated SOUP report Excel file.
To learn more on how to create a vulnerability impact assessment and generate a vulnerability report for a project, see the Vulnerability Management manual.
Ketryx currently supports the following OSV ecosystems for vulnerability scanning:
GitHub Actions
Go
Hex
Maven
NuGet
Packagist
Pub
PyPI
RubyGems
SwiftURL
crates.io
npm
While Ketryx can make use of any packages of any ecosystem submitted via SPDX files, the above ecosystems are the ones that are actively scanned for vulnerabilities. For example SPDX files resulting from container image scans can be submitted, but Ketryx will not scan these packages for vulnerabilities.
To find dependencies, Ketryx employs a scanner that pulls each Git repository and analyzes dependencies from dependency manifest files.
For each supported language, Ketryx analyzes both a declared dependency manifest file (e.g. a package.json
file), which can describe version ranges, and a locked dependency manifest file (e.g. a package-lock.json
), which describes deterministic dependency configurations that can lead to reproducible builds.
For each language, dependencies are determined by searching for declared and locked dependency files in the same directory, matching the specific dependency name, and storing both the declared and locked versions of that dependency.
Ketryx supports the following languages and ecosystems:
CocoaPods
Objective-C, Swift
Podfile.lock
Podfile
, Podfile.lock
Gradle
Java, Kotlin
build.gradle
build.gradle
npm (v5-v10)
JavaScript
package-lock.json
package.json
, package-lock.json
pip
Python
requirements.txt
requirements.txt
, Pipfile
, Pipfile.lock
poetry
Python
pyproject.toml
, poetry.lock
pyproject.toml
, poetry.lock
yarn (v1-v4)
JavaScript
yarn.lock
package.json
, yarn.lock
Below is a detailed description of how Ketryx scans for dependencies in each language.
Ketryx's dependency scanning currently only supports direct dependencies of a project, i.e., top-level dependencies. For transitive dependencies, see section 12.
Declared dependency file: package.json
. The scanner searches for direct dependencies specified in the dependencies
block of the package.json
file. Note that devDependencies
are not being scanned or indexed.
Locked dependency file: package-lock.json
. The scanner searches for locked versions of each dependency found in the dependencies
block of the package.json
manifest.
Locked dependency file: yarn.lock
. The scanner searches for locked versions of each dependency found in the dependencies
block of the package.json
.
Declared and locked dependency file: requirements.txt
. The scanner searches for dependencies specified on each line. When a version is given as an individual number, e.g. ==1.0.0
, this is treated as a locked dependency.
Declared dependency file: Pipfile
. The entries in the packages
block are read, no entries in the dev-packages
blocks are read.
Locked dependency file: Pipfile.lock
. Each package in the corresponding Pipfile
is resolved with a specific version.
Declared dependency file: pyproject.toml
. Each dependency below [tool.poetry.dependencies]
is parsed as a dependency. python
is left out deliberately as it is not technically a library.
Locked dependency file: poetry.lock
. Each matched dependency from the pyproject.toml
file is resolved to a specific version or, if left out, resolved to *
.
Only Gradle is currently supported. Since build.gradle
files specify an arbitrary script to run, Ketryx only supports dependency declarations in the following formats:
Map formatted dependencies, e.g.:
String formatted dependencies in a single line, e.g.:
String formatted dependencies in a block, e.g.:
The dependencies' group ID, artifact ID, or version must be specified literally in the build.gradle
file, not externally. E.g., Ketryx does not support inferring dependency versions with a variable such as javax.xml.bind:jaxb-api:${jaxb_version}
.
Other dependency formats will be scanned. In the above example where a dependency version is a variable, these will still show up in the dependency list but will not execute the build.gradle
script.
build.gradle.kts
files are not currently supported.
Only packages available on Maven have their metadata fetched.
The name of the file must be build.gradle
.
Declared dependency file: Podfile
. Each dependency line prefixed by the pod
keyword is read as a declared dependency. When :subspecs
are specified in a pod
, they are used to modify the dependency name by adding each subspec as a suffix. E.g., for a pod React
with :subspecs Core
, CxxBridge
and others, the dependencies will be React/Core
and React/CxxBridge
.
Locked dependency file: Podfile.lock
. Each dependency matched from the Podfile is resolved to a specific version by finding the corresponding dependency in the PODS
section of the Podfile.lock
file.
We are continuously working on adding support for more ecosystems. If you have a specific ecosystem you would like to see supported, please let us know by contacting us.
Ketryx built-in dependency scanning currently only supports direct dependencies of a project, i.e. top-level dependencies. However, using the Build API it is possible to submit SPDX (Software Package Data Exchange) files in JSON format that contain all dependencies of a project, including transitive dependencies. Ketryx will use this information to build the dependency tree and also scan these dependencies for vulnerabilities for supported ecosystems. See our SPDX manual for more information on how to use the Build API and the SPDX format with Ketryx.
Once the dependencies are submitted, the SBOM Review page in Ketryx will show the submitted top-level packages dependencies for the version it was submitted for. Direct and indirect dependencies of these packages are shown on the Dependencies tab of each individual dependency's detail page. This can be configured to create dependency items for all dependencies, not just the top-level ones. For more details about this, see the Advanced Settings documentation.
For Ketryx to display the transitive dependencies, the submitted SPDX file must contain transitive dependencies in the packages
list and the necessary relationships in the relationships
list for each dependency. If these are missing, Ketryx will not display the transitive dependencies.
Ketryx can generate a SOUP configuration report in tabular form. At least the following information is contained in the generated document:
Dependency name: The name of the dependency.
Registry URL (2): The URL to the registry if the dependency was found in a package registry.
Declared Version(s) (1): The declared version (range) of a dependency found by Ketryx in a package manifest file. E.g. for npm dependencies, if react
was declared using "react:" "^18.0.0"
in package.json
, ^18.0.0
is the declared version range. Can be multiple versions or version ranges if a dependency was found in multiple package manifest files.
Locked Version(s) (1): The resolved, locked version of a dependency found by Ketryx in a package manifest lock file, if available. E.g. for npm dependencies, if react
was declared using "react:" "^18.0.0"
in package.json
and resolved to 18.2.0
as found in package-lock.json
, 18.2.0
is the locked version. Can be multiple versions if a dependency was found in multiple package manifest files.
Earliest Used Version (1): The earliest used version of this dependency. E.g. if react
is used multiple times, once in version 17.0.0
and once in 18.0.0
, 17.0.0
would be the earliest used version.
Latest Used Version (1): The earliest used version of this dependency. E.g. if react
is used multiple times, once in version 17.0.0
and once in 18.0.0
, 18.0.0
would be the latest used version.
Latest Available Version (1): This is the latest available version of a dependency as found on package registries.
Accepted Version(s): The accepted version for this dependency. See versions to accept for more information.
Status: The acceptance status of the dependency. See the dependency screen for an explanation of the different status values.
Risk level: Risk level refers to an estimate of the severity of injury that this dependency could permit or inflict, either directly or indirectly, on a patient or operator as a result of dependency failures, design flaws, or simply by virtue of employing the dependency for its intended use.
Issues URL (2): The URL to the issues of a dependency.
Manufacturer (2): The manufacturer of a dependency.
License (2): The license(s) of a dependency.
Intended Use (2): The intended use for a dependency.
Vulnerabilities: For dependencies discovered by Ketryx automatically (see dependency scanning), Ketryx will attempt to automatically find vulnerabilities. This column will contain the summary of these vulnerbilities. See also cybersecurity. For manual dependencies, this column will contain the contents of the Vulnerabilities input field that's available when creating of editing manually created dependencies. See also manual dependencies.
Vulnerability URLs (1): For the found vulnerabilities, this column will contain the relevant URLs as found in the vulnerability database. For manually defined dependencies, this column will be empty.
Security Impact: The possible impact the dependency could have on the vulnerability of the device to cyberattack.
Security Impact Justification: If a security impact exists for a dependency, the rationale for its inclusion in the device.
Reliability Impact: The possible impact this dependency could have on the efficacy and safety of the device were it to be unreliable.
Reliability Impact Justification: If a reliability impact exists for a dependency, the rationale for its inclusion in the device.
Additional Notes: Field for any other notes about a dependency.
Notes:
(1) Empty for manual dependencies. (2) For automatically resolved dependencies, Ketryx will try to fill out this information by scraping package registries. If not found, this column will be empty but is user-editable to amend missing information. For manual dependencies this field can be filled out by the user.
Select one or more dependencies by clicking on their rows on the dependency page. A menu will pop up at the bottom of the screen.
To approve one or more dependencies, click on the “Approve dependencies” button, then the “Approve” button at the bottom of the dependency approval dialog.
Upon approving one or more dependencies, the corresponding dependency rows will be updated, and the approval status tooltip will show which steps have approved each dependency.
Confirm and approve the approval revocation.