> For the complete documentation index, see [llms.txt](https://docs.interlynk.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.interlynk.io/productivity-tools/sbomqs.md).

# sbomqs

sbomqs evaluates the quality of Software Bills of Materials (SBOMs) and validates compliance against industry standards. It scores SBOMs on a 0–10 scale across multiple quality dimensions — identification, provenance, integrity, licensing, vulnerability readiness, and structural correctness — and provides actionable feedback for improvement.

**Repository:** [github.com/interlynk-io/sbomqs](https://github.com/interlynk-io/sbomqs)

***

## How Scoring Works

sbomqs evaluates SBOMs across 8 weighted categories, each containing multiple features:

| Category          | Weight        | What It Measures                                                          |
| ----------------- | ------------- | ------------------------------------------------------------------------- |
| Identification    | 10            | Component names, versions, unique identifiers                             |
| Provenance        | 12            | Creation timestamp, authors, tool info, supplier, namespace               |
| Integrity         | 15            | Checksums (SHA-256+), SBOM signatures                                     |
| Completeness      | 12            | Dependencies, primary component, source URIs, suppliers                   |
| Licensing         | 15            | License info quality, SPDX validity, deprecated/restrictive detection     |
| Vulnerability     | 10            | CPE/PURL identifiers for vulnerability lookup                             |
| Structural        | 8             | Spec compliance, version, file format, schema validation                  |
| Component Quality | Informational | PURL and CPE validation against package registries and the NVD dictionary |

Each feature is scored 0–10. Category scores are the average of their features. The overall score is the weighted average of all categories.

Component Quality is reported but excluded from the overall score. Its checks call the Interlynk API, so they run only with `--enable-component-analysis` and an API key:

```bash
sbomqs score --enable-component-analysis --api-key "your-api-key" sbom.json
```

The key can also come from the `INTERLYNK_SECURITY_TOKEN` environment variable.

**Grade scale:**

| Grade | Score Range |
| ----- | ----------- |
| A     | 9.0 – 10.0  |
| B     | 8.0 – 8.9   |
| C     | 7.0 – 7.9   |
| D     | 5.0 – 6.9   |
| F     | below 5.0   |

### Supported SBOM Formats

* **SPDX:** 2.2.1, 2.3, 3.0 (partial)
* **CycloneDX:** 1.4, 1.5, 1.6
* **File formats:** JSON, XML, Tag-Value
* Format and spec version are auto-detected.

***

## Installation

### Homebrew (macOS/Linux)

```bash
brew tap interlynk-io/interlynk
brew install sbomqs
```

### Go Install

```bash
go install github.com/interlynk-io/sbomqs@latest
```

### Pre-Built Binaries

Download from the [GitHub releases page](https://github.com/interlynk-io/sbomqs/releases) for Linux (amd64, arm64), macOS (amd64, arm64), and Windows (amd64).

### Linux Packages

```bash
# Debian/Ubuntu
sudo dpkg -i sbomqs_*_amd64.deb

# RedHat/CentOS
sudo rpm -i sbomqs_*_amd64.rpm
```

### Docker

```bash
docker run ghcr.io/interlynk-io/sbomqs:latest score sbom.json
```

Mount local files:

```bash
docker run -v $(pwd):/data ghcr.io/interlynk-io/sbomqs:latest score /data/sbom.json
```

### Build from Source

```bash
git clone https://github.com/interlynk-io/sbomqs.git
cd sbomqs
make build
```

### Verify Installation

```bash
sbomqs version
```

***

## Running a Scan

### Basic Score

```bash
sbomqs score sbom.json
```

### Output Formats

```bash
# Detailed table (default)
sbomqs score --detailed sbom.json

# Single-line summary
sbomqs score --basic sbom.json

# JSON for automation
sbomqs score --json sbom.json

# Color-coded table
sbomqs score --color sbom.json
```

**Basic output example:**

```
7.8 interlynk cyclonedx 1.6 json sbom.json
```

**JSON output structure:**

```json
{
  "run_id": "abc-123",
  "timestamp": "2025-02-20T10:30:00Z",
  "creation_info": { ... },
  "files": [
    {
      "sbom_quality_score": 7.8,
      "grade": "B",
      "num_components": 247,
      "spec": "cyclonedx",
      "spec_version": "1.6",
      "file_format": "json",
      "comprehensive": [ ... ],
      "profiles": { ... }
    }
  ]
}
```

### Filter by Category or Feature

```bash
# Score only specific categories
sbomqs score --category "integrity,licensing" sbom.json

# Score only specific features
sbomqs score --feature "comp_with_purl,comp_with_version" sbom.json
```

### Recursive Directory Scoring

```bash
sbomqs score --recursive ./sboms/
```

### Scoring Against a Compliance Profile

By default `score` uses the Interlynk scoring model. Pass `--profile` to score the SBOM against the feature set of a compliance standard instead, or against several at once:

```bash
# Score under one profile
sbomqs score --profile ntia sbom.json

# Score under several profiles in one run
sbomqs score --profile ntia,bsi,oct-v1.1,interlynk sbom.json
```

Accepted profiles: `interlynk`, `ntia` (aliases `cisa-2021`, `cisa2021`), `cisa` (aliases `cisa-2026`, `cisa2026`), `fsct`, `bsi` (an alias for the latest BSI profile), `bsi-v1.1`/`bsiv11`, `bsi-v2.0`/`bsiv20`, `bsi-v2.1`/`bsiv21`, and `oct-v1.1`/`octv11`/`oct`.

Profile results appear under `profiles` in the JSON output, each with its own score and grade.

{% hint style="info" %}
Feature keys differ per profile. `--feature comp_with_purl` applies to the default Interlynk model, while a profile run uses that profile's own keys. Run `sbomqs features --profile <profile>` to list them.
{% endhint %}

### Listing Supported Features

```bash
# All features across all profiles
sbomqs features

# Features for one profile
sbomqs features --profile bsiv21

# JSON output
sbomqs features --json
```

Use this to find the exact feature key to pass to `score --feature` or `list --feature`.

### Compliance Validation

Validate against industry standards:

```bash
# CISA Minimum Elements (2026)
sbomqs compliance --cisa sbom.json

# NTIA Minimum Elements (2021), also the default when no standard flag is given
sbomqs compliance --ntia sbom.json

# BSI TR-03183-2, latest version
sbomqs compliance --bsi sbom.json

# BSI TR-03183-2 v2.1.0
sbomqs compliance --bsi-v21 sbom.json

# BSI TR-03183-2 v2.0.0
sbomqs compliance --bsi-v2 sbom.json

# BSI TR-03183-2 v1.1
sbomqs compliance --bsi-v1 sbom.json

# OpenChain Telco SBOM v1.1
sbomqs compliance --oct sbom.json

# Framing Software Component Transparency v3
sbomqs compliance --fsct sbom.json
```

Compliance output shows pass/fail status for each requirement, score breakdowns, and recommendations.

#### Standard Flags

| Flag        | Standard                                          | Aliases                     |
| ----------- | ------------------------------------------------- | --------------------------- |
| `--cisa`    | CISA Minimum Elements (2026)                      | `--cisa-2026`, `--cisa2026` |
| `--ntia`    | NTIA Minimum Elements (July 12, 2021)             | `--cisa-2021`, `--cisa2021` |
| `--bsi`     | BSI TR-03183-2, latest version (currently v2.1.0) | —                           |
| `--bsi-v21` | BSI TR-03183-2 v2.1.0                             | `--bsi-v2.1`, `--bsiv21`    |
| `--bsi-v2`  | BSI TR-03183-2 v2.0.0                             | `--bsi-v2.0`, `--bsiv20`    |
| `--bsi-v1`  | BSI TR-03183-2 v1.1                               | `--bsi-v1.1`, `--bsiv11`    |
| `--oct`     | OpenChain Telco SBOM v1.1                         | `--oct-v1.1`, `--octv11`    |
| `--fsct`    | Framing Software Component Transparency v3        | —                           |

Running `compliance` with no standard flag produces the NTIA report.

{% hint style="warning" %}
`--bsi` tracks the latest BSI version rather than pinning one, and currently selects v2.1.0. Pin `--bsi-v21`, `--bsi-v2`, or `--bsi-v1` in CI if the report needs to stay on one version of the standard across sbomqs upgrades.
{% endhint %}

#### Verifying a Detached Signature

For SPDX SBOMs distributed with a detached signature, pass the signature and the public key alongside the standard flag:

```bash
sbomqs compliance --ntia \
  --signature sbom.json.sig \
  --public-key public.pem \
  sbom.json
```

### List Components by Feature

```bash
# List components missing PURLs
sbomqs list --feature comp_with_purl --missing sbom.json

# List components with their license values
sbomqs list --feature comp_valid_licenses --show sbom.json

# JSON output
sbomqs list --feature comp_with_version --missing --json sbom.json

# Feature keys from a compliance profile rather than the default model
sbomqs list --profile bsiv21 --feature comp_name --missing sbom.json
```

### Share Results

Generate a permanent shareable link on sbombenchmark.dev:

```bash
sbomqs share sbom.json
```

### Policy Enforcement

```bash
# Using a policy file
sbomqs policy --file policies.yaml sbom.json

# Inline policy
sbomqs policy --name "require-purl" --type required --rules "comp_with_purl" --action fail sbom.json
```

Policy types: `whitelist`, `blacklist`, `required`

Policy actions: `fail` (exit non-zero), `warn` (report only), `pass` (force pass)

***

## Exit Codes

| Code     | Meaning                                                     |
| -------- | ----------------------------------------------------------- |
| `0`      | Success                                                     |
| `1`      | Error (invalid input, configuration issue, parsing failure) |
| Non-zero | Policy violation with `--action fail`                       |

***

## Integration Patterns

### CI Quality Gate

Fail the build if SBOM quality drops below a threshold:

```bash
#!/bin/bash
THRESHOLD=7.0
SCORE=$(sbomqs score --json sbom.json | jq -r '.files[0].sbom_quality_score')

if (( $(echo "$SCORE < $THRESHOLD" | bc -l) )); then
  echo "SBOM quality score $SCORE is below threshold $THRESHOLD"
  exit 1
fi

echo "SBOM quality score: $SCORE (threshold: $THRESHOLD)"
```

### GitHub Actions

```yaml
name: SBOM Quality Gate
on: [push, pull_request]

jobs:
  sbom-quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Generate SBOM
        run: syft . -o cyclonedx-json > sbom.cdx.json

      - name: Install sbomqs
        run: |
          curl -sL https://github.com/interlynk-io/sbomqs/releases/latest/download/sbomqs-linux-amd64 -o sbomqs
          chmod +x sbomqs

      - name: Score SBOM
        run: |
          SCORE=$(./sbomqs score --json sbom.cdx.json | jq -r '.files[0].sbom_quality_score')
          echo "SBOM Quality Score: $SCORE"
          if (( $(echo "$SCORE < 7.0" | bc -l) )); then
            echo "::error::SBOM quality below threshold: $SCORE < 7.0"
            exit 1
          fi
```

### GitLab CI

```yaml
sbom-quality:
  stage: test
  image: golang:1.24
  script:
    - go install github.com/interlynk-io/sbomqs@latest
    - SCORE=$(sbomqs score --json sbom.cdx.json | jq -r '.files[0].sbom_quality_score')
    - |
      if [ $(echo "$SCORE < 7.0" | bc -l) -eq 1 ]; then
        echo "SBOM quality below threshold: $SCORE"
        exit 1
      fi
  artifacts:
    reports:
      dotenv: sbom-quality.env
```

### Pre-Release Validation

Score all SBOMs in a release directory:

```bash
sbomqs score --recursive --json ./release-sboms/ | \
  jq -r '.files[] | "\(.file_name): \(.sbom_quality_score) (\(.grade))"'
```

### Compliance Gate

Block releases that fail compliance standards:

```bash
sbomqs compliance --ntia --json sbom.json | \
  jq -e '.files[0].compliance_status == "pass"' || {
    echo "SBOM does not meet NTIA minimum elements"
    exit 1
  }
```

### Dependency-Track Integration

Score SBOMs directly from a Dependency-Track instance:

```bash
sbomqs dtrackScore \
  --url https://dtrack.example.com \
  --api-key "$DT_API_KEY" \
  --tag-project-with-score \
  --tag-project-with-grade \
  <project-uuid>
```

***

## Customization

### Configuration Files

Generate default configuration templates:

```bash
sbomqs generate features       # Individual feature weights
sbomqs generate comprehenssive # Category configuration
sbomqs generate profiles       # Profile definitions
```

### Custom Scoring Configuration

Use `--configpath` to apply a custom configuration:

```bash
sbomqs score --configpath ./custom-config.yaml sbom.json
```

Configuration structure allows you to:

* Enable or disable specific categories
* Adjust category weights
* Customize individual feature weights (0.0–1.0)
* Create organization-specific scoring profiles

### Compliance Profiles

Apply compliance profiles during scoring:

```bash
sbomqs score --profile ntia sbom.json
sbomqs score --profile bsi sbom.json
sbomqs score --profile bsi-v2.0 sbom.json
sbomqs score --profile oct sbom.json
sbomqs score --profile fsct sbom.json
sbomqs score --profile interlynk sbom.json
```

### Legacy Scoring Mode

Use the pre-v2.0 scoring categories (NTIA Minimum Elements, Structural, Semantic, Quality, Sharing):

```bash
sbomqs score --legacy sbom.json
```

***

## Best Practices

### When to Enforce Strict Scoring

| Context                     | Recommended Threshold | Standard               |
| --------------------------- | --------------------- | ---------------------- |
| Internal development builds | 5.0+ (Grade C)        | No specific standard   |
| Pre-release / staging       | 7.0+ (Grade B)        | Organization policy    |
| Production releases         | 8.0+ (Grade A)        | NTIA minimum elements  |
| Regulatory submissions      | 8.5+ (Grade A)        | BSI TR-03183-2 or FSCT |
| Supply chain sharing        | 7.5+ (Grade B)        | OpenChain Telco        |

### Using Alongside Vulnerability Scanning

1. **Score first** — validate the SBOM has sufficient quality for vulnerability scanning to be meaningful. An SBOM without PURLs or CPEs will produce incomplete vulnerability results.
2. **Scan second** — run vulnerability scanning on SBOMs that meet quality thresholds.
3. **Gate on both** — a release should pass both quality and vulnerability gates.

```bash
# Step 1: Quality gate
sbomqs score --json sbom.json | jq -e '.files[0].sbom_quality_score >= 7.0' || exit 1

# Step 2: Upload for vulnerability scanning
pylynk upload --prod 'my-app' --sbom sbom.json
```

### Governance Recommendations

* **Baseline scores:** Establish minimum quality scores per project tier (critical, standard, experimental).
* **Track trends:** Export JSON scores to a time-series database to monitor quality over time.
* **Automate compliance:** Run compliance checks in CI and block merges that introduce regressions.
* **Share results:** Use `sbomqs share` to create permanent links for audit trails.

***

## Common Misconfigurations

| Issue                                    | Symptom                            | Fix                                                          |
| ---------------------------------------- | ---------------------------------- | ------------------------------------------------------------ |
| Scoring SBOM without PURLs               | Low vulnerability readiness score  | Ensure SBOM generator includes PURLs for all components      |
| Using `--legacy` in new pipelines        | Inconsistent scoring with platform | Remove `--legacy` flag; use v2.0 categories                  |
| Threshold too low                        | Low-quality SBOMs pass the gate    | Raise threshold to 7.0+ for production                       |
| Threshold too high for early development | All builds fail quality gate       | Use 5.0 for development, increase for staging/production     |
| Not using `--json` in CI                 | Parsing table output is fragile    | Always use `--json` with `jq` for automation                 |
| Scoring the wrong file                   | Unexpected results                 | Verify the file is a valid SBOM, not a lock file or manifest |
