Reference
Look up the details here: the ways to install the securechain CLI, its commands, options, exit codes, and configuration file, the access tokens, the REST API, and the MCP server. To set up the CLI for the first time, read Get started.
This page describes version 0.1.22 of the CLI. securechain version prints the version that you have.
Install the CLI #
The CLI is one file. Select the method that fits your computer or your CI job:
For Linux and macOS. The script finds your operating system and processor, downloads the file, checks its checksum, and installs it. It does not need root access.
curl -fsSL https://securechain.tuxcare.com/get/securechain | sh
- The script installs to
/usr/local/binwhen it can write there, else to~/.local/bin. SetSECURECHAIN_INSTALL_DIRto select another directory. - Set
SECURECHAIN_VERSION, for exampleSECURECHAIN_VERSION=v0.1.22, to install one version. See Pin the CLI version. - On Windows, use npm, Python, or Manual download.
For macOS and Linux with Homebrew:
brew install tuxcare/tap/securechain
The package @tuxcare/securechain holds the file for your platform. It downloads nothing when you install it.
npm install --global @tuxcare/securechain
Or run it without an installation:
npx @tuxcare/securechain sca
The package securechain on PyPI holds the file for your platform. pipx and uv keep it out of the environment of your project:
pipx install securechain
Or run it without an installation:
uvx securechain sca
The image tuxcare/securechain is on Docker Hub. Mount your project and pass the token:
docker run --rm -v "$PWD":/work -w /work -e SECURECHAIN_PORTAL_TOKEN tuxcare/securechain:latest-toolchains sca
| Tag | What it holds |
|---|---|
tuxcare/securechain:latest | The CLI only. Use it as a base image, or where your image has the package manager. |
tuxcare/securechain:latest-toolchains | The CLI with npm, mvn, and pip, for a job that has no package manager of its own. |
latest follows the promoted release (see When a new release reaches you). In CI, pin a version, for example tuxcare/securechain:0.1.22-toolchains.
For Debian and Ubuntu. The TuxCare SecureChain key signs the repository, and the CLI updates with the other packages of the system.
curl -fsSL https://securechain.tuxcare.com/apt/tuxcare-securechain.gpg | sudo tee /etc/apt/keyrings/tuxcare-securechain.gpg >/dev/null
curl -fsSL https://securechain.tuxcare.com/apt/securechain.sources | sudo tee /etc/apt/sources.list.d/securechain.sources >/dev/null
sudo apt-get update && sudo apt-get install -y securechain
For RHEL, AlmaLinux, Rocky Linux, and Fedora. The TuxCare SecureChain key signs the repository.
sudo curl -fsSL -o /etc/yum.repos.d/securechain.repo https://securechain.tuxcare.com/yum/securechain.repo
sudo dnf install -y securechain
On a system without dnf, use yum install -y securechain.
A Java build needs no installation: the plugin downloads the CLI for your platform, checks its checksum, keeps it in ~/.m2, and runs it. Add the TuxCare plugin repository to pom.xml:
<pluginRepositories>
<pluginRepository>
<id>tuxcare</id>
<url>https://artifacts.tuxcare.com/repository/maven-plugin-securechain/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
Then add the plugin inside <build><plugins>:
<plugin>
<groupId>com.tuxcare</groupId>
<artifactId>securechain-maven-plugin</artifactId>
<version>0.1.0</version>
<executions>
<execution><goals><goal>check</goal></goals><phase>verify</phase></execution>
</executions>
</plugin>
Or run it one time, with no change to pom.xml:
mvn com.tuxcare:securechain-maven-plugin:check
The Gradle plugin works as the Maven plugin does: it downloads the CLI for your platform, checks its checksum, keeps it, and runs it. In settings.gradle.kts:
pluginManagement {
repositories {
maven { url = uri("https://artifacts.tuxcare.com/repository/maven-plugin-securechain/") }
gradlePluginPortal()
}
}
In build.gradle.kts:
plugins {
id("com.tuxcare.securechain") version "0.1.0"
}
Then:
./gradlew securechainCheck
Each release is at https://securechain.tuxcare.com/get/<version>/, with checksums.txt, a signature for each file, and the public key securechain.pub. https://securechain.tuxcare.com/get/latest/ always has the files of the promoted release (see When a new release reaches you).
| Platform | File |
|---|---|
| Linux x86-64 | securechain-linux-amd64 |
| Linux ARM64 | securechain-linux-arm64 |
| macOS Intel | securechain-darwin-amd64 |
| macOS Apple silicon | securechain-darwin-arm64 |
| Windows x86-64 | securechain-windows-amd64.exe |
| Windows ARM64 | securechain-windows-arm64.exe |
For example, on Linux x86-64:
curl -fsSLO https://securechain.tuxcare.com/get/latest/securechain-linux-amd64
curl -fsSLO https://securechain.tuxcare.com/get/latest/checksums.txt
sha256sum --check --ignore-missing checksums.txt
install -m 0755 securechain-linux-amd64 /usr/local/bin/securechain
On Windows, download the .exe file, rename it to securechain.exe, and put it in a directory of your PATH.
macOS quarantines a file that a web browser downloads, and blocks it at the first start. Download the file with curl, as above.
Then check the installation:
securechain version
securechain --version prints the same line. A CLI of version 0.1.74 or earlier does not know the option, and exits with code 2.
When a new release reaches you #
Since release 0.1.86, a new release of the CLI comes out in two steps. At its tag, the release is out under its version number. 48 hours after the tag, TuxCare promotes it, and the channels with no version move to it.
- These channels follow the promoted release: the Docker tags
latestandlatest-toolchains, the GitHub Action@v0, npm (npm install @tuxcare/securechainandnpx), Homebrew, PyPI, apt, dnf and yum, the install script with noSECURECHAIN_VERSION, andhttps://securechain.tuxcare.com/get/latest/.securechain upgradealso moves to the promoted release. - The GitLab CI/CD component gets a new version when the release is promoted, not at its tag (since release 0.1.87):
@0and@~latestfollow the promoted release, and@vX.Y.Zof the component exists only for a promoted release. To run a newer CLI release before that, set the inputversionof the component. - A pinned version gets the new release at once: the Docker tag
tuxcare/securechain:X.Y.Z, the GitHub Action@vX.Y.Z,SECURECHAIN_VERSION=vX.Y.Zof the install script,npm install @tuxcare/securechain@X.Y.Z, and the Maven and Gradle plugins, whose version names the CLI.
Upgrade the CLI #
When the CLI is 75 or more releases behind the newest release, it prints a warning on each run that connects to your workspace. The warning does not change the exit code. securechain version names a newer release at any distance. When the CLI is older than the oldest version that the portal accepts, the CLI stops and tells you to upgrade. To upgrade, run:
securechain upgrade
upgradefinds the method that installed the CLI. It needs no token and no project.- For Homebrew, npm, pipx, uv, the install script, and a manual download on Linux or macOS, it prints the step and runs it.
- For apt, dnf, Docker, Maven, and Gradle, it prints the step only. Do the step yourself: apt and dnf need root, a Docker image needs a new pull or a new tag, and the Maven and Gradle plugins use the version that your build file names.
| Installation method | Upgrade step |
|---|---|
| Install script | Run the script again. If you set SECURECHAIN_VERSION, set the new version. |
| Homebrew | brew upgrade tuxcare/tap/securechain |
| npm | npm install --global @tuxcare/securechain. With npx, run npx @tuxcare/securechain@latest. |
| Python | pipx upgrade securechain, or uv tool upgrade securechain. With uvx, run uvx securechain@latest. |
| Docker | Pull the image again, for example docker pull tuxcare/securechain:latest-toolchains. For a pinned tag, set a newer version in the CI job. |
| apt | sudo apt-get update && sudo apt-get install --only-upgrade securechain |
| dnf / yum | sudo dnf upgrade --refresh securechain, or sudo yum update securechain |
| Maven, Gradle | Set a newer version of the plugin in the build file. The plugin downloads the CLI of that version. |
| Manual download | Download the file again from https://securechain.tuxcare.com/get/latest/, check it against checksums.txt, and replace the old file. |
| GitHub Action, GitLab CI/CD component | The major tag (@v0, @0) follows the promoted release (see When a new release reaches you). A pinned tag, or the input version, keeps one release: set a newer one. |
Sign in the CLI #
The CLI uses one secret: an access token of your workspace.
- On your computer
- Run
securechain auth login. The CLI shows a link and a code, and opens the link in your browser. Sign in, check that the page shows the same code, select your workspace, select the box that says that you started this sign-in, and select Approve CLI access. If you did not accept the terms in that workspace yet, the next page shows them: select the box to accept them, and select Accept. Then approve CLI access again. SecureChain sends you an email about each new CLI sign-in. If you did not start a sign-in in that email, revoke its token on the Access tokens page. The CLI keeps the token in the keychain of your computer. Over SSH, or on a computer with no browser, open the link on another device. With no terminal and nothing on standard input, for exampledocker runwith no-iand no-t, the CLI opens no browser: it prints the link and the code, and waits while you open the link on any device. A standard input that stays open, as withdocker run -i, makes the CLI wait for a token: after 2 seconds with no input, it prints a line that tells you to pipe the token, or to press Ctrl-D in a Unix terminal for the browser sign-in (see Troubleshooting). - In CI
- Make a token in the portal and keep it in a masked CI variable with the name
SECURECHAIN_PORTAL_TOKEN. The CLI reads the variable and writes the token nowhere. In a CI job, the browser sign-in does not start, andauth loginwith no token stops. Where standard input is not a terminal, which is the usual case in CI, it stops with exit code 3. Where standard input is a terminal, it stops with exit code 2. The message names the two ways: setSECURECHAIN_PORTAL_TOKEN, or pipe the token tosecurechain auth login --with-token. See Get started: CI/CD.
| Command | What it does |
|---|---|
securechain auth login | Signs in with the browser, as above. The CLI keeps one sign-in for each workspace (CLI 0.1.46 or later). A new sign-in to the same workspace replaces its old sign-in and revokes the old token. A sign-in to another workspace keeps the others. Then it writes the TuxCare registry into the files of your package managers, and lists them: see The files that auth login and registry login write. |
securechain auth login --with-token | Asks you to paste a token, in place of the browser sign-in. A token that you pipe to auth login works the same way. |
securechain auth status | Lists each workspace that the computer has a sign-in to. Prints the workspace that this directory uses and why, the portal address, and the subscription of the workspace (the line subscription). |
securechain auth use workspace | Sends the scans of this repository to that workspace. --default makes it the default workspace of the computer. |
securechain auth logout | Removes every sign-in, or with --tenant workspace the sign-in of that workspace only. It removes the token from the keychain, and revokes it when it came from a browser sign-in. It also removes the registry credential and the registry lines, with their securechain header line, that auth login and registry login wrote. --keep-token keeps the token valid. --keep-registry keeps the registry credential and the registry lines. --tenant also keeps them. |
- The CLI has no option for the token: a token on the command line shows in the process list and in the shell history.
- When
SECURECHAIN_PORTAL_TOKENis set, the CLI uses it, not the token in the keychain. - The CLI finds your workspace from the token. The portal address is
https://sc.tuxcare.cloud. You do not type the address of your workspace. - A browser sign-in makes a token with the name
CLI login: computer
on the Access tokens page. The token has your role. It expires after 90 days: then runsecurechain auth loginagain. - To make sure that a job sends to the correct workspace, set
--tenant name, the variableSECURECHAIN_TENANT, or the keytenantin.securechain.yaml. When the token belongs to another workspace, the CLI stops with exit code 3 and sends nothing.
The files that auth login and registry login write #
After the sign-in, securechain auth login also does what securechain registry login does: it writes the address of the TuxCare registry and the registry credential into the configuration files of the package managers in your home directory. It does this for the package managers of the directory where you run it. It writes nothing, for example, when the setting Use the TuxCare registry is off, when the workspace has neither SecureChain nor ELS, when the directory has no package manager, and in a CI job. The files are:
| Package manager | File |
|---|---|
| npm, pnpm, Yarn 1 | ~/.npmrc, or the file that npm_config_userconfig names. For pnpm, also its own user files, for example auth.ini. |
| Bun | ~/.npmrc, or .npmrc in XDG_CONFIG_HOME when that variable is set |
| Yarn 2 or later | ~/.yarnrc.yml |
| pip | the user pip.conf of pip (on Linux ~/.config/pip/pip.conf, on Windows pip.ini), or the file that an absolute PIP_CONFIG_FILE names when that file exists |
| PDM | the user config.toml of PDM |
| uv | the user uv.toml of uv |
| pip, Pipenv, PDM, uv, Poetry | ~/.netrc, for the credential |
| Maven | ~/.m2/settings.xml |
| Gradle | ~/.gradle/init.d/securechain.gradle, or init.d/securechain.gradle in GRADLE_USER_HOME |
With CLI 0.1.69 or later, the first line of each file that the CLI writes a registry line into tells you where the line came from and how to remove it:
# securechain wrote the TuxCare registry lines in this file. Run "securechain auth logout" to remove them.
In ~/.m2/settings.xml, the same text is an XML comment after the XML declaration:
<!-- securechain wrote the TuxCare registry lines in this file. Run "securechain auth logout" to remove them. -->
The CLI writes the Gradle init script whole. Its first lines name securechain registry login and say Delete this file to undo it.
A second sign-in does not add a second header line. A file that an earlier release of the CLI wrote gets the header line at the next sign-in, and nothing else in it changes.
After the sign-in lines, the CLI lists the files that it changed, and the command that removes its lines. For example, for pip:
wrote /home/u/.config/pip/pip.conf, for pip
wrote /home/u/.netrc, for pip
the files that this login changed:
/home/u/.config/pip/pip.conf
/home/u/.netrc
to undo: securechain auth logout removes the registry lines from these files. It also signs this machine out of the portal.
A file that is already current is not in the list. When the run changes no file, it prints no list. If a file has a format with no comments, it gets no header line, and its line in the list ends with (no securechain header: its format has no comments)
. With --output json, auth login gives the list in registry_login.files (for each file: path, managers, and header) and the command in registry_login.undo.
To undo the changes:
securechain auth logoutremoves the registry lines and the header line from these files, and deletes the Gradle init script. It changes no other line: your own lines and comments stay. It also removes every sign-in of the computer.securechain auth logout --keep-registryandsecurechain auth logout --tenant workspacekeep the files as they are.- No command removes only the registry lines and keeps the sign-in. Run
securechain auth logout, thensecurechain auth loginagain. The new sign-in writes no registry line when the setting Use the TuxCare registry is off, or when you run it in a directory with no package manager. Do not edit the lines out by hand: the Gradle init script and the entries of~/.yarnrc.ymland~/.m2/settings.xmlstop working when you remove only a part of them.
More than one workspace #
You can sign in the CLI to more than one workspace, for example your own workspace and the workspace of your company (CLI 0.1.46 or later). Each repository then sends its scans to one workspace. The CLI selects it in this order:
--tenant, the variableSECURECHAIN_TENANT, or the keytenantin.securechain.yaml.- The workspace that the CLI saved for this repository on your computer.
- The only workspace, when the computer has a sign-in to one workspace.
When none of these applies, the CLI asks Which workspace gets the scans of this repository?
and saves your answer. Without a terminal, for example in a script, it stops with exit code 3 and sends nothing. The first scan of a repository saves its workspace, so a later sign-in to another workspace does not move the repository. Each run prints the workspace on a line that starts with workspace:. To move a repository to another workspace, run securechain auth use workspace in the repository.
A CI job is not affected: it uses the token in SECURECHAIN_PORTAL_TOKEN.
Commands #
| Command | What it does | What it changes |
|---|---|---|
sca | Sends the package list of the project to your workspace and prints the findings. | Nothing |
sca vuln <id> | Prints one advisory in full, as your workspace has it. For example securechain sca vuln CVE-2024-0001. | Nothing |
compare | Sends the scan and prints the findings that the latest scan of a base branch does not have. Use it for a pull request. See Pull and merge requests. | Nothing |
sbom | Writes the package list as a CycloneDX or SPDX file. sbom --preview writes exactly what an upload sends, sends nothing, and needs no token. | The file that you name |
status | Reports the package managers that it found, the subscription, and the packages that have a TuxCare build. | Nothing |
init | Sets up a repository for TuxCare builds. See Set up a project. | Configuration files in the project |
registry login | Gives the package managers on this computer the credential of the TuxCare registry, and lists the files that it changed. securechain auth logout removes its lines. See The files that auth login and registry login write. | Configuration files in your home directory |
registry use on|off|default | Sets the setting Use the TuxCare registry of the repository of the current directory: on, off, or default (the value of the workspace applies). It prints the value that applies now. It needs the sign-in of a member or an admin of the repository (a CLI release after 0.1.67). | The setting in the portal; no file |
registry check | Asks the registry that the files of the project name, for example your own mirror, whether it serves the TuxCare builds, and says what to fix. It checks npm, pnpm, Yarn 1, and Bun (CLI 0.1.85 or later), and Maven, Gradle, pip, uv, Poetry, and PDM (CLI 0.1.86 or later). It does not check Yarn 2 or later, or Pipenv. See Check the mirror. | Nothing |
registry env --job-dir <dir> | Gives the package managers of one CI job the registry credential. See A CI job that installs TuxCare builds. | Files in the job directory only |
fix | Writes the upstream fix for each open finding, installs it, and checks the result. It needs a portal token and no TuxCare registry. It covers npm, pnpm, Yarn classic, Yarn Berry, Bun, Deno, uv, PDM, Poetry, Pipenv, pip, pip-tools, conda, Maven, Gradle, and Cargo (CLI 0.1.81 or later), and NuGet, Bundler, Composer, Stack, Cabal, CocoaPods, Julia, renv, CPAN, Pub, Mix, SwiftPM, Paket, Bazel rules_jvm_external, Go modules, GitHub Actions, and Conan (a CLI release after 0.1.81). It runs your package manager, so the tool must be on the computer: Cargo needs cargo. See securechain fix. | The manifest and the lockfile. On GitHub Actions: the workflow file |
harden | Changes the project to TuxCare builds, installs them, and checks the result. See harden. | The manifest and the lockfile |
update | Moves each TuxCare build of the project to the newest build of the same version. See update. | The manifest and the lockfile |
check | The CI gate for a project that uses TuxCare builds. See check. | Nothing |
unharden | Removes the TuxCare builds and the settings that init and harden wrote. See unharden. | The manifest, the lockfile, and the configuration files |
migrate | Changes the old npm aliases npm:@els-js/… to the normal package names. | The manifest |
auth | Signs the CLI in and out. See Sign in the CLI. | The keychain. auth login and auth logout also change the configuration files in your home directory: see The files that auth login and registry login write. |
doctor | Checks your environment: the package managers, the configuration, the proxy, and the connection to the portal. --bundle <path> writes a support archive, with the tokens removed. See Check your environment. | The archive that you name |
upgrade | Moves the CLI to the promoted release. See Upgrade the CLI. | The CLI |
version | Prints the version of the CLI. | Nothing |
securechain --helplists the commands.securechain sca --helplists the options of one command.- Each command runs in the current directory.
--dir pathselects another project root. harden,update,init,unharden, andfixtake--dry-run: they print the change and write nothing.
sca and sbom read the lockfiles of these ecosystems: npm, pnpm, Yarn, Bun, Deno, pip, uv, Poetry, PDM, Pipenv, conda, Maven, Gradle, Go, Cargo, Composer, Bundler, NuGet, Paket, Julia, Mix, Pub, SwiftPM, CocoaPods, Stack, and Cabal. harden and check work for JavaScript and Python projects, and in part for Deno. Maven and Gradle need a BOM file from TuxCare. See TuxCare builds.
Options of sca and compare #
| Option | Command | What it does |
|---|---|---|
--fail-on <severity> | sca | Exits with code 1 when an open finding is at this severity or higher: critical, high, medium, or low. Without it, sca only reports. |
--fail-on-exploited | sca | Exits with code 1 when an open finding is known exploited, at any severity. It combines with --fail-on: either gate fails the job. --fail-on-exploited=false turns the key fail_on_exploited off for one run. A finding that --baseline-portal skips, a finding that a TuxCare build fixes, a finding with no fix planned or a live-patched finding (see below), and a dev finding under --ignore-dev do not fail this gate. compare has no such option: run sca --fail-on-exploited beside compare --fail-on-new. CLI 0.1.80 or later. See the gate on known-exploited findings. |
--base <branch> | compare | The branch to compare with, for example main. Required. The base branch needs a scan of its own. |
--fail-on-new | compare | Exits with code 1 when the scan has an open finding that the latest scan of the base branch does not have. |
--min-severity <severity> | sca | Hides the findings below this severity from the printed report. JSON and SARIF output still hold them. |
--group-by <key> | sca | Groups the printed findings by ecosystem (the default), package, or severity. |
--output <format> | both | The format of the result. sca: human (the default), json, markdown, or sarif. compare: human or json. check also writes junit. The JSON format is stable: use it in scripts. |
--baseline-portal | sca | Skips the findings that your team ignores in the portal. |
--wait <duration> | both | How long to wait for the portal to match the scan. The default is 2m for sca and 5m for compare. |
--release <name> | sca | Records the scan as a release with this name. An empty name stops the run with exit code 2. See Record a release. |
--product-release <name> | sca | Also adds the release to this product release. Needs --release. |
--force-release | sca | Replaces a release of the same name that another commit holds. Needs --release. |
--on-portal-error warn | sca, check | Changes exit code 4 (the portal did not answer) to 0 with a warning. |
--dir <path> | all | The project root. The default is the current directory. |
--ecosystem <name> | all | Uses only this package manager, for example npm. You can give the option more than one time. In sca, sbom, and compare it also takes an ecosystem family, for example golang or cargo. From version 0.1.71, a name that the CLI does not know (for example go) stops the run with exit code 2, and the message lists the names. |
Findings with no fix planned, and live-patched findings #
Some findings need no step from you. The portal gives an OS package of a TuxCare build the status no_fix_planned when TuxCare stated that it will not fix the finding on that build. It gives a finding the status live_patched when a live patch that is loaded on the host closes it. sca and securechain image submit read both statuses (a CLI release after 0.1.84):
- The report lists the finding, and the
FIXED INcolumn shows the reason:TuxCare will not fix
, orlive-patched
.--output jsongives the reason instatus_reasonof the finding. - The totals line counts these findings apart, for example
2 security vulnerabilities found in 1 component; TuxCare will not fix 3 findings; 1 finding is live-patched
. Under--fail-on,vulnerabilities.gateof the JSON counts them inno_fix_plannedandlive_patched. - Such a finding never fails
--fail-onor--fail-on-exploited.
CLI 0.1.84 and earlier do not read these statuses: the run stops with exit code 4. Upgrade the CLI (see Upgrade the CLI).
Exit codes #
Code 1 is the result of a gate. Each other code that is not 0 means that the run did not finish.
| Code | Meaning | What to do |
|---|---|---|
| 0 | The run finished, and no finding reached the level that fails the job. | Nothing. |
| 1 | A finding failed the gate: a finding at the --fail-on level, a known-exploited finding under --fail-on-exploited, a new finding for compare --fail-on-new, a newer build for update --check-only, a problem that check found, or a finding that fix left. | Read the findings in the job log or in the portal. |
| 2 | The command cannot run as you wrote it: a wrong option, a configuration file that the CLI cannot read, no package manager that it knows, or a browser sign-in in a CI job. | Read the message. Check the options and the directory. |
| 3 | The token is missing, wrong, expired, or revoked, the workspace refused it, a limit stopped it, the --tenant pin does not match, or the workspace has no registry token. | See Common errors. |
| 4 | The portal did not answer in time, or its answer failed a check. A CLI that is too old also gets this code, and so does a CLI version that the portal blocks (CLI 0.1.86 or later): the message then gives the reason, the version to use, and the command that pins it. | Run the job again. Upgrade the CLI if the message tells you to. For a blocked version, do what the message says. |
| 5 | A tool on your side failed: the install command of your package manager, or a file that the CLI cannot write. | Read the output of the tool in the job log. |
| 6 | harden, update, unharden, or fix changed the project, but the installed packages are not the planned ones. The CLI put your files back. | Read the message: it names the package. Contact TuxCare if the error stays. |
| 7 | An error in the CLI. The CLI prints the path of a report file. | Send the report to TuxCare. |
The file .securechain.yaml #
securechain init writes this file into the project root. Commit it. It holds no secret. The CLI refuses a key that it does not know, with exit code 2, so a typo does not go unseen.
| Key | Meaning |
|---|---|
schema_version | The version of the file format. Set it to 1. The key is necessary: without it, the CLI stops with exit code 2. securechain init writes it. |
registry | The address of the registry, for example your own mirror. Without the key, the CLI uses the registry that the portal names. |
tenant | The name of your workspace. With this key, each command stops when the token belongs to another workspace. |
ecosystems | The package managers to use, when you do not want the CLI to find them, or the ecosystem families to scan, for example [golang] or [cargo]. The option --ecosystem does the same for one run. A family name (golang, cargo, pypi, and the others that the error message lists) makes sca, sbom, and compare scan only the families that the key names, as --ecosystem does. A list of package managers only (for example [pnpm]) chooses the package manager of its language, and the CLI still finds the other languages. A name that the CLI does not know stops the run with exit code 2. Family names in this key need version 0.1.71 or later. |
ignore | A list of paths to leave out, for example test fixtures that have lockfiles of their own. The CLI reads no dependency file under these paths and sends nothing from them. From version 0.1.71, a file under these paths also does not select a package manager: an unused setup.py under ignore does not make the CLI look for a Python environment. |
submit.remote_repo_url | The repository URL to file the scans under. Without it, the CLI reads the URL from the CI variables, else from the git remote origin. |
baseline.portal | true makes sca skip the findings that your team ignores in the portal, as --baseline-portal does. |
fail_on_exploited | true sets sca --fail-on-exploited for every run of the project. The option wins over the key. CLI 0.1.80 or later. |
dev_extras | A list of the project's extras that hold only development tools, for example ["test"]. A package that only these extras or a dependency group need is marked (dev), and sca --ignore-dev keeps its findings out of --fail-on. The key applies to uv and Poetry projects. |
reinstall | The install command of the project, as a list, when it is not the default one. For example npm: ["npm", "install", "--legacy-peer-deps"]. |
unharden | The original lines that init, harden, and update changed. unharden reads them. The CLI writes this key: do not change it. |
Access tokens #
A token lets a program use your workspace: the CLI, a CI job, a script, or an AI assistant. Open Access tokens in the workspace menu, type a Name that tells where the token is used, select the rights, set an expiry, and select Mint token.
Copy it at once and keep it in a secret store. The portal keeps only a hash of the token. If you lose a token, revoke it and make a new one.

- The name of the token.
- The scope. Only an admin sees this list.
- The rights: a preset, or your own selection of channels and permissions.
- Mint token makes the token and shows it one time.
- A token starts with
tuxr_and the name of your workspace. - The table shows the last four characters, the rights, the creation date, the last use, and the expiry of each token. Select Revoke to stop a token at once. A revoked token cannot come back.
- The Last CLI column shows the CLI version of the newest scan that the token sent.
older than
marks an old CLI. Use it to find a CI job that needs an upgrade. - The Browser sessions table lists your sign-ins. Select Sign out on a row to end that session.
Rights #
The rights of a token are two lists:
- Channels: how the token connects.
CLI
is the securechain CLI.API
is the REST API.MCP
is the MCP server for AI assistants. - Permissions: what the token can do.
submit
sends scans.read
reads repositories, scans, and findings.write
changes things: triage, the default branch, and the settings.poll
is for scan workers only: do not give it to a CI token.
Select a preset, or select Custom and tick each channel and permission:
| Preset | Channels | Permissions | Use it for |
|---|---|---|---|
| CI token (one repository) | CLI | submit, read | The CI job of one repository. An admin and a member see this preset, and the form starts with it. It sets the scope to one repository and the expiry to 90 days from today. A member needs the member role on that repository, and the expiry is 90 days or less. |
| CI upload (all my repositories) | CLI | submit, read | A CI job that builds more than one repository, or your own computer: send scans and read the findings. The token can read every repository that its scope can read, and the form warns about it. It sets the expiry to 90 days from today; you can clear it. |
| Upload only | CLI | submit | A job or a TuxCare Radar agent that sends scans. It reads only the findings of the scans that it sent. It can run securechain sca and securechain check. |
| Read only | API | read | A script or a dashboard that reads findings. |
| Read and write | API | read, write | A script that also triages findings or changes settings. |
| AI assistant | MCP | read | An AI assistant that reads findings. |
| AI assistant with triage | MCP | read, write | An AI assistant that can also triage findings. |
- A token never does more than the role of its user. A viewer can only read, so a token of a viewer cannot send scans. The page shows only the presets that your role can give.
- The CLI channel is always on. An admin must turn on the API and MCP channels for the workspace.
- You cannot change the rights of a token. Revoke it and make a new one.
Scope #
An admin selects a Scope. The scope limits what a token can see on every channel. Use the smallest scope that does the job:
| Scope | What the token can do | Use it for |
|---|---|---|
| a repository | Send scans to one repository and read that repository only. | The CI job of one repository. If the token leaks, only that repository is exposed. |
| a department | Send scans and read the repositories of one department. A scan of a new repository puts the repository in that department. | A CI server that builds many repositories of one team. |
| me, or a user | Act as that user, with the role and the departments of the user. The token stops when the user is disabled. | Your own computer, scripts, and AI assistant. |
| whole workspace | Act as an admin of the whole workspace. The token belongs to no person, so it keeps working when the person who made it leaves. | Automation that manages the workspace. Keep these few. |
A member or a viewer makes tokens for their own user, and does not see the Scope list. A member also makes the CI token of one repository with the CI token (one repository) preset. That token stops when the person who made it is disabled or loses the member role on the repository, and Access tokens marks it; it works again when that person gets the role back. It also stops when it expires or someone revokes it. The member sees it on Access tokens and can revoke it. A department token that an admin makes does not depend on a person. A repository or department token cannot read other repositories, and it cannot make, list, or revoke tokens.
Expiry #
Set a date in Expires, or leave the field empty for a token that does not expire. The token stops at the end of that day in the time zone of your browser.
- An expired token gets the same answer as a revoked token: 401
unknown or revoked token
. The table marks itexpired
. - You cannot change the expiry. To replace a token: make the new token, change the CI secret, run the pipeline, then revoke the old token.
- A token that expires cannot make a token that expires later, or a token with no expiry.
Allowed addresses #
A token can work from some networks only. Type them in Allowed from when you make the token, separated by commas: a network such as 10.0.0.0/8 or 2a01:4f8::/64, or one address such as 203.0.113.7. Leave the field empty to allow every address. To change the list of a token, select Addresses in its row.
- The list holds for every use of the token: the API, the MCP server, the CLI and the agent, and a sign-in with the token.
- A request from another address gets 403
this token does not allow requests from
and the address. The address is the one that the portal sees: behind NAT or a proxy, the address of the NAT or the proxy. - For example, give a CI token the network of your CI runners, and a dashboard token the address of its server.
- Only a person who signs in changes a list. A request with a token, or a browser signed in with a token, cannot change the list of a token or the list of the workspace: such a browser shows no Addresses button, and shows the list of the workspace read-only.
- A token with a list can make only a token whose networks are inside its own list.
API and MCP #
Programs can use your workspace in two more ways:
- The REST API at
/api/v1, for scripts, dashboards, and other tools. - The MCP server at
/mcp, for AI assistants such as Claude Code and Cursor. MCP is the Model Context Protocol.
Both are off in a new workspace. Each one needs a switch that an admin turns on, and a token with that channel in its rights.
Turn the API or MCP on #
- As an admin, open Settings › API and MCP access.
- Select the switch of API access or MCP access. It changes from
Off
toOn
, and the page showsSaved
. - Copy the API base URL or the MCP URL from the same section.
- On the Access tokens page, make a token with a preset for that channel.

- The switches. Each one shows its state.
- The base URL of the REST API.
- The URL of the MCP server.
Under the switches, Allowed addresses holds the networks from which a token can use the API and the MCP server, one per line. Leave it empty to allow every address. The section shows Your address, and warns when the list leaves it out. The list also holds for a sign-in with a token. It does not hold for a person who signs in with a sign-in provider, so you cannot lock yourself out of the page. It does not hold for the CLI or the agent. Each token can also have a list of its own.
- When you turn a switch off, every token stops on that channel at once. The other channels continue to work.
- The CLI and the browser work with both switches off.
- If the section has no switch for a channel, the channel is not available for your workspace. Contact TuxCare.
The REST API #
The base URL is https://name.sc.tuxcare.cloud/api/v1. Send the token in the Authorization header. The API does not accept a token in the URL.
curl -fsS \
-H "Authorization: Bearer $SECURECHAIN_API_TOKEN" \
"https://name.sc.tuxcare.cloud/api/v1/repos?limit=20"
- A
GETrequest needs the read permission. Any other method needs the write permission. - The OpenAPI document at
/api/v1/openapi.jsonlists each route, its permission, and the role that it needs. It needs no token. - The role and the scope of the token apply, the same as in the browser. The rate limit of each token also applies.
- The examples list hosts and vulnerabilities.
- Useful routes: the exports (
/api/v1/export/findings), the compliance report (/api/v1/repos/{id}/report), and the VEX file of a release (/api/v1/releases/{id}/vex).
Examples #
The examples use jq to read the JSON. Put the token in a variable first:
export SECURECHAIN_API_TOKEN='<token>'
B=https://name.sc.tuxcare.cloud/api/v1
H="Authorization: Bearer $SECURECHAIN_API_TOKEN"
The hosts, as the Hosts page lists them. Each id is the key of the host in the other routes:
curl -fsS -H "$H" "$B/hosts" | jq
Each host has its id, name, os (almalinux-9.6), support (els, esu, essential, or empty when the host has no TuxCare release file: the pages then show Community
, or no TuxCare licence
on RHEL), the booted kernel, live_patched_to (the kernel build that KernelCare's patches bring it to), addresses (the addresses of its network interfaces), submitted_from (the address that its last scan came from), last_scan, agent (tuxcare-radar/3.0.2), tags, and the open vulnerabilities by severity. The route takes filters: ?os=almalinux-9.6 (the hosts of one release; the Hosts page has no such list, and sorts by the OS column instead), ?tag=prod, ?q=web. ?q= also finds a host by an address: ?q=192.168.0.53.
# one line per host: name, operating system, kernel, last scan, critical and total
curl -fsS -H "$H" "$B/hosts" \
| jq -r '.[] | [.name, .os, .kernel, .last_scan, .vulnerabilities.critical, .vulnerabilities.total] | @tsv'
The vulnerabilities of one host, as its page lists them. Use the id from the list of hosts. The answer is the latest scan of the host:
curl -fsS -H "$H" "$B/repos/6/vulnerabilities" | jq
Each row has the advisory (a CVE id), its summary, the packages it is on, its severity, and the fix: the version that fixes it, or no fix yet
, TuxCare will not fix
, live-patched by KernelCare
. Add ?kernels=all to include the installed kernels that the host does not run.
# the critical CVEs of host 6 that have a fix, as CSV
curl -fsS -H "$H" "$B/repos/6/vulnerabilities" \
| jq -r '.vulnerabilities[] | select(.severity == "critical" and (.fix | test("^[0-9]")))
| [.advisory, (.packages | join(" ")), .fix] | @csv'
Every vulnerability of the workspace, with the hosts and other assets that have it, as the Vulnerabilities page lists them:
curl -fsS -H "$H" "$B/vulnerabilities?severity=critical&kind=host" | jq
Each row has the advisory, summary, severity, and the assets (id, name, kind). severity takes a comma list in any case: CRITICAL,HIGH. Other filters: exploited=1 (known exploited), fixable=1, tuxcare=1 (TuxCare has a fix), untriaged=1, reboot=1 (a reboot would close at least one of its findings, on a host that KernelCare does not patch), kind=host, q=openssl.
Files: add format=xlsx or format=csv to /repos/{id}/vulnerabilities or /vulnerabilities for the report as a file, with the filters of the request. /repos/{id}/vulnerabilities also takes the filters of the host's table: q, severity, fix (for example tuxcare, none), and triage.
curl -fsS -H "$H" -OJ "$B/repos/6/vulnerabilities?format=xlsx&severity=critical,high"
# one line per CVE with the names of its hosts
curl -fsS -H "$H" "$B/vulnerabilities?severity=critical&kind=host" \
| jq -r '.[] | [.advisory, .severity, ([.assets[].name] | join(","))] | @tsv'
The MCP server #
The MCP URL is https://name.sc.tuxcare.cloud/mcp. Use a token with the AI assistant preset, or AI assistant with triage if the assistant may triage findings. Each person uses a token of their own user.
Claude Code:
claude mcp add --transport http securechain https://name.sc.tuxcare.cloud/mcp \
--header "Authorization: Bearer <token>"
Cursor: add the server to ~/.cursor/mcp.json, or to .cursor/mcp.json in your project:
{
"mcpServers": {
"securechain": {
"url": "https://name.sc.tuxcare.cloud/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}
Do not commit a file that holds a token. The server gives the assistant these tools:
| Tool | What it does | Permission |
|---|---|---|
whoami | Tells the workspace, the scope, and the rights of the token. | none |
list_repos | Lists the repositories with the finding counts of the default branch. | read |
get_repo | Shows one repository: the tracked branch, the recent branches, the newest scan of each slot, and the finding counts. | read |
list_findings | Lists the findings of a branch. Filters: minimum severity, known exploited, triage state. | read |
get_finding | Shows one finding, as the finding page does. | read |
get_advisory | Shows an advisory and its other names. | read |
diff_ref | Shows the new and the fixed findings of a branch against an earlier scan or another branch. | read |
fix_plan | Shows the fix plan of a branch, as the Fix plan tab does. | read |
get_base_advice | Shows the base image of an image scan, how many open findings come from the base, and the base upgrades that remove findings. | read |
list_releases, get_release | List the releases of a repository, and show one release. | read |
triage_finding | Sets the triage state of a finding. It also needs the member or admin role. The audit log shows your email, then via MCP. | write |
- A slot is one project path and one set of ecosystems. A branch of a monorepo can have many slots.
get_repolists the scan id of each slot, and the other tools take a scan id to select a slot. - A list tool returns 50 rows by default and 100 at most. The assistant asks for the next rows when it needs them.
- When a tool fails, for example because a finding is outside the scope of the token, the assistant gets one sentence that tells why.
When the portal refuses a request #
| Answer | Cause | What to do |
|---|---|---|
403 this token cannot use the api channel(or cli, mcp) | The token does not have that channel in its rights. | Make a token with a preset for that channel. |
403 API access is off for this workspace(or MCP) | The switch of the channel is off. | Ask an admin to turn it on. |
403 this token cannot read(or submit, write) | The token does not have the permission, or the role of its user does not have it. | Make a token with the permission. A viewer can only read. |
403 this token does not allow requests froman address | The token has a list of allowed addresses, and the request came from another address. | Send the request from an allowed network, or change the list of the token. |
403 this workspace does not allow requests froman address | The workspace has a list of allowed addresses for the API and MCP, and the request came from another address. | Ask an admin to add the network under API and MCP access. |
404 no such route | The path is wrong, or the channel is not available for your workspace. | Check the path in the OpenAPI document. Contact TuxCare if the channel is not available. |
An AI assistant shows a 401, 403, or 404 as a connection error.
Next: Administration