6.1 KiB
SBOM Schema Validation
This document describes the schema validation system for SBOM (Software Bill of Materials) fixtures in StellaOps.
Overview
StellaOps validates all SBOM fixtures against official JSON schemas to detect schema drift before runtime. This ensures:
- CycloneDX 1.6 fixtures are compliant with the official schema
- SPDX 3.0.1 fixtures meet specification requirements
- OpenVEX fixtures follow the 0.2.0 specification
- Invalid fixtures are detected early in the CI pipeline
Supported Formats
| Format | Version | Schema Location | Validator |
|---|---|---|---|
| CycloneDX | 1.6 | docs/schemas/cyclonedx-bom-1.6.schema.json |
sbom-utility |
| SPDX | 3.0.1 | docs/schemas/spdx-jsonld-3.0.1.schema.json |
pyspdxtools / check-jsonschema |
| OpenVEX | 0.2.0 | docs/schemas/openvex-0.2.0.schema.json |
ajv-cli |
CI Workflows
Schema Validation Workflow
File: .gitea/workflows/schema-validation.yml
Runs on:
- Pull requests touching
bench/golden-corpus/**,src/Scanner/**,docs/schemas/**, orscripts/validate-*.sh - Push to
mainbranch
Jobs:
- validate-cyclonedx - Validates all CycloneDX 1.6 fixtures
- validate-spdx - Validates all SPDX 3.0.1 fixtures
- validate-vex - Validates all OpenVEX 0.2.0 fixtures
- validate-negative - Verifies invalid fixtures are correctly rejected
- summary - Aggregates results
Determinism Gate Integration
File: .gitea/workflows/determinism-gate.yml
The determinism gate includes schema validation as a prerequisite step. If schema validation fails, determinism checks are blocked.
To skip schema validation (e.g., during debugging):
# Via workflow_dispatch
skip_schema_validation: true
Fixture Directories
Validation scans these directories for SBOM fixtures:
| Directory | Purpose |
|---|---|
bench/golden-corpus/ |
Golden reference fixtures for reproducibility testing |
tests/fixtures/ |
Test fixtures for unit and integration tests |
seed-data/ |
Initial seed data for development environments |
tests/fixtures/invalid/ |
Excluded - Contains intentionally invalid fixtures for negative testing |
Local Validation
Using the Validation Scripts
# Validate a single CycloneDX file
./scripts/validate-sbom.sh path/to/sbom.json
# Validate all CycloneDX files in a directory
./scripts/validate-sbom.sh --all path/to/directory
# Validate SPDX file
./scripts/validate-spdx.sh path/to/sbom.spdx.json
# Validate OpenVEX file
./scripts/validate-vex.sh path/to/vex.openvex.json
Using sbom-utility Directly
# Install sbom-utility
curl -sSfL "https://github.com/CycloneDX/sbom-utility/releases/download/v0.16.0/sbom-utility-v0.16.0-linux-amd64.tar.gz" | tar xz
sudo mv sbom-utility /usr/local/bin/
# Validate
sbom-utility validate --input-file sbom.json --schema docs/schemas/cyclonedx-bom-1.6.schema.json
Troubleshooting
Common Validation Errors
1. Invalid specVersion
Error: enum: must be equal to one of the allowed values
Cause: The specVersion field contains an invalid or unsupported version.
Solution:
// Invalid
"specVersion": "2.0"
// Valid
"specVersion": "1.6"
2. Missing Required Fields
Error: required: must have required property 'name'
Cause: A component is missing required fields.
Solution: Ensure all components have required fields:
{
"type": "library",
"name": "example-package",
"version": "1.0.0"
}
3. Invalid Component Type
Error: enum: type must be equal to one of the allowed values
Cause: The component type is not a valid CycloneDX type.
Solution: Use valid types: application, framework, library, container, operating-system, device, firmware, file, data
4. Invalid PURL Format
Error: format: must match format "purl"
Cause: The package URL (purl) is malformed.
Solution: Use correct purl format:
// Invalid
"purl": "npm:example@1.0.0"
// Valid
"purl": "pkg:npm/example@1.0.0"
CI Failure Recovery
- Identify the failing fixture: Check CI logs for the specific file
- Download the fixture:
cat path/to/failing-fixture.json - Run local validation:
./scripts/validate-sbom.sh path/to/failing-fixture.json - Fix the schema issues: Use the error messages to guide corrections
- Verify the fix: Re-run local validation
- Push and verify CI passes
Negative Test Failures
If negative tests fail with "UNEXPECTED PASS":
- The invalid fixture in
tests/fixtures/invalid/somehow passed validation - Review the fixture to ensure it contains actual schema violations
- Update the fixture to include more obvious violations
- Document the expected error in
tests/fixtures/invalid/README.md
Adding New Fixtures
Valid Fixtures
- Create fixture in appropriate directory (
bench/golden-corpus/,tests/fixtures/) - Ensure it contains the format marker:
- CycloneDX:
"bomFormat": "CycloneDX" - SPDX:
"spdxVersion"or"@context"with SPDX - OpenVEX:
"@context"with openvex
- CycloneDX:
- Run local validation before committing
- CI will automatically validate on PR
Invalid Fixtures (Negative Testing)
- Create fixture in
tests/fixtures/invalid/ - Add
$commentfield explaining the defect - Update
tests/fixtures/invalid/README.mdwith expected error - Ensure the fixture has the correct format marker
- CI will verify it fails validation
Schema Updates
When updating schema versions:
- Download new schema to
docs/schemas/ - Update
SBOM_UTILITY_VERSIONin workflows if needed - Run full validation to check for new violations
- Update documentation with new version
- Update
docs/reproducibility.mdwith schema version changes