SecureChain

User guide

Fix vulnerabilities

How to close the findings of a project: with an upgrade to a fixed version, or with a TuxCare build of the version that you use now. The CLI makes the change, checks it, and keeps it current.

Two ways to fix #

Upgrade the packageUse a TuxCare build
What changesThe version: you move to the lowest version that fixes the advisory.The source: the same version, built by TuxCare from source with the fix added. Its version ends in -tuxcare.N (Python: +tuxcare.N).
Use it whenThe fixed version is close, and its changes do not break your code.The fix is in a new major version, or the project that made the package no longer fixes your version.
HowYour package manager, for example npm install lodash@4.17.21.securechain harden. See TuxCare builds.
NeedsNothing more.A subscription with TuxCare builds.

The portal tells you which fix applies:

Upgrade a package #

  1. Open the Fix plan tab of the repository. A package with a known-exploited finding comes first.
  2. Change the version of the package with your package manager. For a transitive package, upgrade the direct dependency that pulls it in, or add an override.
  3. Run your tests, and commit the manifest and the lockfile.
  4. Run securechain sca, or let the CI job run it. The finding closes when the portal gets a scan that does not have it.

The fix plan marks an upgrade to a new major version with major version. Such an upgrade can break your code. A TuxCare build avoids it.

TuxCare builds #

TuxCare builds the open-source packages that your projects use from their source, and serves the builds from the TuxCare registry. When a vulnerability is found in a version, TuxCare adds the fix to that version and publishes a new build. TuxCare also fixes versions that the project that made them no longer maintains. A new upstream version reaches the registry only after TuxCare checks it, for example for malicious code.

The CLI moves a project to the builds in three steps: init one time for each repository, registry login one time for each computer, and harden each time you want to apply the builds.

What you need #

Set up a project #

cd path/to/your/project
securechain init             # one time for each repository
securechain registry login   # one time for each computer

Move the project to the builds: harden #

securechain harden --dry-run   # show the plan and the changes; write nothing
securechain harden
  1. harden asks the portal which TuxCare builds your subscription has for the dependencies of the project.
  2. It writes those builds into the manifest and the lockfile.
  3. It runs the install command of your package manager.
  4. It checks that each planned build is installed. If the check fails, it puts your files back and exits with code 6.
  5. It sends the new package list to your workspace.

Then run your tests, and commit the manifest and the lockfile.

Keep the builds current: update #

securechain update --check-only   # exit code 1 when a newer build exists; write nothing
securechain update

TuxCare publishes a new build when it fixes a new vulnerability in a version. update moves each TuxCare build of the project to the newest build of the same version, for example from 1.3.1-tuxcare.2 to 1.3.1-tuxcare.3. It installs and checks the result, as harden does. Run it on a schedule, or when the portal shows a finding that a newer build fixes.

The gate: check #

securechain check reads the installed dependencies and changes nothing. It exits with code 1 when the project is not in the state that harden made:

--explain prints the evidence and the fix for each problem.

TuxCare builds in CI #

A job that installs TuxCare builds needs the registry credential before the install step. The job does three things in this order: get the credential, install, run check.

GitHub Actions:

permissions:
  contents: read
  security-events: write
steps:
  - uses: actions/checkout@v4
  - uses: TuxCare/securechain-action@v0
    with:
      command: registry
      portal-token: ${{ secrets.SECURECHAIN_PORTAL_TOKEN }}
  - run: npm ci
  - uses: TuxCare/securechain-action@v0
    if: always()
    with:
      portal-token: ${{ secrets.SECURECHAIN_PORTAL_TOKEN }}
      registry-login: none

GitLab CI:

securechain:
  image: node:22        # any image that has curl and your package manager
  script:
    - curl -fsSL https://securechain.tuxcare.com/get/securechain | sh
    - out="$(securechain registry env --job-dir "/tmp/securechain-job-$CI_JOB_ID" --format shell)"; eval "$out"
    - env -u SECURECHAIN_PORTAL_TOKEN npm ci
    - securechain check --output junit > report.xml
  after_script:
    - rm -rf "/tmp/securechain-job-$CI_JOB_ID"
  artifacts:
    reports:
      junit: report.xml
include:
  - component: $CI_SERVER_FQDN/tuxcare/securechain-ci/check@0
    inputs:
      stage: test
      install: npm ci

Rules for a project with TuxCare builds #

Renovate and Dependabot #

An update bot does not know TuxCare builds. Without a rule, it opens a pull request that replaces 1.4.5-tuxcare.1 with the public 1.4.6.

npm: the two paths of the registry #

For npm, the TuxCare registry has two paths on one host:

So a new TuxCare build never changes what an existing lockfile installs, and the install does not fail with EINTEGRITY. pnpm and Yarn 2 or later keep no package address in the lockfile: for them, the CLI writes /npm/ as the source.

Remove TuxCare builds: unharden #

securechain unharden --dry-run   # show the changes; write nothing
securechain unharden

unharden undoes init and harden. Use it when you stop the subscription, or to go back to the public packages.

Then run your tests, and commit the changed files.

Next: Reference