# 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 | EOL/EOS detection, malicious component detection, KEV tracking        |

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

**Grade scale:**

| Grade | Score Range |
| ----- | ----------- |
| A     | 8.0 – 10.0  |
| B     | 6.0 – 7.9   |
| C     | 4.0 – 5.9   |
| D     | 2.0 – 3.9   |
| F     | 0.0 – 1.9   |

### 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/
```

### Compliance Validation

Validate against industry standards:

```bash
# NTIA Minimum Elements
sbomqs compliance --ntia sbom.json

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

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

# OpenChain Telco v1.0
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.

### 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
```

### 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 |
