218 lines
6.0 KiB
Markdown
218 lines
6.0 KiB
Markdown
# SBOM Interoperability Testing
|
||
|
||
## Overview
|
||
|
||
StellaOps SBOM interoperability tests ensure compatibility with third-party security tools in the ecosystem. The tests validate that StellaOps-generated SBOMs can be consumed by popular tools like Grype, and that findings parity remains above 95%.
|
||
|
||
## Test Coverage
|
||
|
||
### SBOM Formats
|
||
|
||
| Format | Version | Status | Parity Target |
|
||
|--------|---------|--------|---------------|
|
||
| CycloneDX | 1.6 | ✅ Supported | 95%+ |
|
||
| SPDX | 3.0.1 | ✅ Supported | 95%+ |
|
||
|
||
### Third-Party Tools
|
||
|
||
| Tool | Purpose | Version | Status |
|
||
|------|---------|---------|--------|
|
||
| Syft | SBOM Generation | Latest | ✅ Compatible |
|
||
| Grype | Vulnerability Scanning | Latest | ✅ Compatible |
|
||
| cosign | Attestation | Latest | ✅ Compatible |
|
||
|
||
## Parity Expectations
|
||
|
||
### What is Parity?
|
||
|
||
Parity measures how closely StellaOps vulnerability findings match those from third-party tools like Grype when scanning the same SBOM.
|
||
|
||
**Formula:**
|
||
```
|
||
Parity % = (Matching Findings / Total Unique Findings) × 100
|
||
```
|
||
|
||
**Target:** ≥95% parity for both CycloneDX and SPDX formats
|
||
|
||
### Known Differences
|
||
|
||
The following differences are **acceptable** and expected:
|
||
|
||
#### 1. VEX Application
|
||
- **Difference:** StellaOps applies VEX documents, Grype may not
|
||
- **Impact:** StellaOps may show fewer vulnerabilities
|
||
- **Acceptable:** Yes - this is a feature, not a bug
|
||
|
||
#### 2. Feed Coverage
|
||
- **Difference:** Tool-specific vulnerability databases
|
||
- **Examples:**
|
||
- StellaOps may have distro-specific feeds Grype lacks
|
||
- Grype may have GitHub Advisory feeds StellaOps doesn't prioritize
|
||
- **Acceptable:** Within 5% tolerance
|
||
|
||
#### 3. Version Matching Semantics
|
||
- **Difference:** Interpretation of version ranges
|
||
- **Examples:**
|
||
- SemVer vs non-SemVer handling
|
||
- Epoch handling in RPM/Debian packages
|
||
- **Acceptable:** When using distro-native comparators
|
||
|
||
#### 4. Package Identification (PURL)
|
||
- **Difference:** PURL generation strategies
|
||
- **Examples:**
|
||
- `pkg:npm/package` vs `pkg:npm/package@version`
|
||
- Namespace handling
|
||
- **Acceptable:** When functionally equivalent
|
||
|
||
## Running Interop Tests
|
||
|
||
### Prerequisites
|
||
|
||
Install required tools:
|
||
|
||
```bash
|
||
# Install Syft
|
||
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
|
||
|
||
# Install Grype
|
||
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
|
||
|
||
# Install cosign
|
||
curl -sSfL https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o /usr/local/bin/cosign
|
||
chmod +x /usr/local/bin/cosign
|
||
```
|
||
|
||
### Local Execution
|
||
|
||
```bash
|
||
# Run all interop tests
|
||
dotnet test tests/interop/StellaOps.Interop.Tests
|
||
|
||
# Run CycloneDX tests only
|
||
dotnet test tests/interop/StellaOps.Interop.Tests --filter "Format=CycloneDX"
|
||
|
||
# Run SPDX tests only
|
||
dotnet test tests/interop/StellaOps.Interop.Tests --filter "Format=SPDX"
|
||
|
||
# Run parity tests
|
||
dotnet test tests/interop/StellaOps.Interop.Tests --filter "Category=Parity"
|
||
```
|
||
|
||
### CI Execution
|
||
|
||
Interop tests run automatically on:
|
||
- Pull requests affecting scanner or SBOM code
|
||
- Nightly schedule (6 AM UTC)
|
||
- Manual workflow dispatch
|
||
|
||
See `.gitea/workflows/interop-e2e.yml` for CI configuration.
|
||
|
||
## Test Images
|
||
|
||
The following container images are used for interop testing:
|
||
|
||
| Image | Purpose | Characteristics |
|
||
|-------|---------|-----------------|
|
||
| `alpine:3.18` | Distro packages | APK packages, minimal |
|
||
| `debian:12-slim` | Distro packages | DEB packages, medium |
|
||
| `ubuntu:22.04` | Distro packages | DEB packages, larger |
|
||
| `node:20-alpine` | Language packages | NPM packages |
|
||
| `python:3.12-slim` | Language packages | Pip packages |
|
||
| `golang:1.22-alpine` | Language packages | Go modules |
|
||
|
||
## Troubleshooting
|
||
|
||
### Parity Below Threshold
|
||
|
||
If parity drops below 95%:
|
||
|
||
1. **Check for feed updates**
|
||
- Grype may have newer vulnerability data
|
||
- Update StellaOps feeds
|
||
|
||
2. **Review differences**
|
||
- Run parity analysis: `dotnet test --filter "Category=Parity" --logger "console;verbosity=detailed"`
|
||
- Categorize differences using `FindingsParityAnalyzer`
|
||
|
||
3. **Validate with golden corpus**
|
||
- Compare against known-good results in `bench/golden-corpus/categories/interop/`
|
||
|
||
4. **Update acceptable differences**
|
||
- Document new acceptable differences in this README
|
||
- Adjust tolerance if justified
|
||
|
||
### Tool Installation Failures
|
||
|
||
If Syft/Grype/cosign fail to install:
|
||
|
||
```bash
|
||
# Check versions
|
||
syft --version
|
||
grype --version
|
||
cosign version
|
||
|
||
# Reinstall if needed
|
||
rm /usr/local/bin/{syft,grype,cosign}
|
||
# Re-run installation commands
|
||
```
|
||
|
||
### SBOM Validation Failures
|
||
|
||
If SBOMs fail schema validation:
|
||
|
||
1. Verify format version:
|
||
```bash
|
||
jq '.specVersion' sbom-cyclonedx.json # Should be "1.6"
|
||
jq '.spdxVersion' sbom-spdx.json # Should be "SPDX-3.0"
|
||
```
|
||
|
||
2. Validate against official schemas:
|
||
```bash
|
||
# CycloneDX
|
||
npm install -g @cyclonedx/cdx-cli
|
||
cdx-cli validate --input-file sbom-cyclonedx.json
|
||
|
||
# SPDX (TODO: Add SPDX validation tool)
|
||
```
|
||
|
||
## Continuous Improvement
|
||
|
||
### Adding New Test Cases
|
||
|
||
1. Add new image to test matrix in `*RoundTripTests.cs`
|
||
2. Update `TestImages` member data
|
||
3. Run locally to verify
|
||
4. Submit PR with updated tests
|
||
|
||
### Updating Parity Thresholds
|
||
|
||
Current threshold: **95%**
|
||
|
||
To adjust:
|
||
1. Document justification in sprint file
|
||
2. Update `tolerancePercent` parameter in test calls
|
||
3. Update this README
|
||
|
||
### Tool Version Pinning
|
||
|
||
Tools are currently installed from `latest`. To pin versions:
|
||
|
||
1. Update `.gitea/workflows/interop-e2e.yml`
|
||
2. Specify version in install commands
|
||
3. Document version compatibility in this README
|
||
|
||
## References
|
||
|
||
- [CycloneDX 1.6 Specification](https://cyclonedx.org/docs/1.6/)
|
||
- [SPDX 3.0.1 Specification](https://spdx.github.io/spdx-spec/v3.0/)
|
||
- [Syft Documentation](https://github.com/anchore/syft)
|
||
- [Grype Documentation](https://github.com/anchore/grype)
|
||
- [cosign Documentation](https://github.com/sigstore/cosign)
|
||
|
||
## Contacts
|
||
|
||
For questions about interop testing:
|
||
- **Sprint:** SPRINT_5100_0003_0001
|
||
- **Owner:** QA Team
|
||
- **Dependencies:** Sprint 5100.0001.0002 (Evidence Index)
|