Sprint 3500.0004.0004 (Documentation & Handoff) - T2 DONE Operations Runbooks Added: - score-replay-runbook.md: Deterministic replay procedures - proof-verification-runbook.md: DSSE/Merkle verification ops - airgap-operations-runbook.md: Offline kit management CLI Reference Docs: - reachability-cli-reference.md - score-proofs-cli-reference.md - unknowns-cli-reference.md Air-Gap Guides: - score-proofs-reachability-airgap-runbook.md Training Materials: - score-proofs-concept-guide.md UI API Clients: - proof.client.ts - reachability.client.ts - unknowns.client.ts All 5 operations runbooks now complete (reachability, unknowns-queue, score-replay, proof-verification, airgap-operations).
12 KiB
Score Proofs Concept Guide
Sprint: SPRINT_3500_0004_0004
Audience: Developers, Security Engineers, DevOps
Introduction
Score Proofs provide cryptographic evidence that vulnerability scores can be independently verified and reproduced. This guide explains the concepts, architecture, and use cases for Score Proofs in StellaOps.
What are Score Proofs?
The Problem
Traditional vulnerability scanners produce scores, but:
- Non-reproducible: Re-running a scan may yield different results
- Opaque: No visibility into how scores were computed
- Untraceable: No audit trail linking scores to inputs
- Time-sensitive: Advisory data changes constantly
The Solution
Score Proofs address these issues by:
- Content-addressing all inputs: Every piece of data is identified by its cryptographic hash
- Recording computation parameters: Algorithm versions, timestamps, configuration
- Creating verifiable attestations: DSSE-signed bundles that can be independently verified
- Enabling deterministic replay: Same inputs always produce same outputs
Core Concepts
1. Scan Manifest
A Scan Manifest is the immutable record of everything that went into a scan:
manifest:
scanId: "scan-12345"
digest: "sha256:abc123..." # Content hash of the manifest itself
timestamp: "2025-12-20T10:00:00Z"
inputs:
sbom:
digest: "sha256:def456..."
format: "cyclonedx-1.6"
advisoryFeeds:
- feedId: "nvd"
digest: "sha256:ghi789..."
asOf: "2025-12-20T00:00:00Z"
- feedId: "ghsa"
digest: "sha256:jkl012..."
asOf: "2025-12-20T00:00:00Z"
callGraph:
digest: "sha256:mno345..."
nodes: 12345
vexDocuments:
- digest: "sha256:pqr678..."
configuration:
scoringAlgorithm: "cvss-4.0"
reachabilityEnabled: true
unknownsHandling: "flag"
environment:
scannerVersion: "1.0.0"
feedVersions:
nvd: "2025.12.20"
ghsa: "2025.12.20"
Key Properties:
- Every input has a content hash (digest)
- Configuration is explicitly recorded
- Environment versions are captured
- The manifest itself has a digest
2. Proof Bundle
A Proof Bundle packages the manifest with cryptographic attestations:
proof-bundle/
├── manifest.json # The scan manifest
├── attestations/
│ ├── manifest.dsse # DSSE signature over manifest
│ ├── sbom.dsse # SBOM attestation
│ └── findings.dsse # Findings attestation
├── inputs/ # Optional: actual input data
│ ├── sbom.json
│ └── callgraph.ndjson
└── bundle.sig # Bundle signature
3. Deterministic Replay
Replay is the process of re-executing a scan using the exact inputs from a manifest:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Proof Bundle │────▶│ Replay Engine │────▶│ New Findings │
│ (manifest + │ │ (same algo) │ │ (must match) │
│ inputs) │ │ │ │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
Guarantees:
- Same inputs → Same outputs (byte-identical)
- Different inputs → Different outputs (with diff report)
- Missing inputs → Validation failure
4. Proof Ledger
The Proof Ledger is an append-only chain of proof records:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Proof 1 │────▶│ Proof 2 │────▶│ Proof 3 │
│ │ │ │ │ │
│ prevHash: ∅ │ │ prevHash: P1 │ │ prevHash: P2 │
│ manifest: M1 │ │ manifest: M2 │ │ manifest: M3 │
│ hash: P1 │ │ hash: P2 │ │ hash: P3 │
└──────────────┘ └──────────────┘ └──────────────┘
This creates an audit trail where:
- Each proof links to its predecessor
- Tampering breaks the chain
- History is verifiable
How It Works
Step 1: Scan Execution
During a scan, the system:
- Collects all inputs (SBOM, advisories, call graph, VEX)
- Computes digests for each input
- Records configuration and environment
- Executes the scoring algorithm
- Generates findings with provenance
Step 2: Manifest Creation
After scoring:
- All input digests are assembled into a manifest
- Findings are attached with their own digests
- The manifest is signed using DSSE
Step 3: Proof Registration
The proof is registered:
- Appended to the proof ledger (with chain link)
- Optionally anchored to Sigstore Rekor (transparency log)
- Stored in content-addressed storage
Step 4: Verification
To verify a proof:
- Retrieve the proof bundle
- Verify all signatures
- Check chain integrity (prev_hash)
- Optionally replay the computation
- Compare outputs
Use Cases
1. Audit Compliance
Scenario: An auditor asks "How did you arrive at this vulnerability score?"
With Score Proofs:
# Show the proof
stella proof inspect --scan-id $SCAN_ID
# Auditor can verify independently
stella proof verify --scan-id $SCAN_ID
The auditor sees exactly which advisories, SBOM version, and VEX documents were used.
2. Dispute Resolution
Scenario: A vendor disputes a finding, claiming it was fixed.
With Score Proofs:
# Replay with the original inputs
stella score replay --scan-id $SCAN_ID
# Compare with current data
stella score diff --scan-id $SCAN_ID --compare-latest
The diff shows what changed and why.
3. Regulatory Evidence
Scenario: A regulator requires proof that security scans were performed.
With Score Proofs:
# Export evidence bundle
stella proof export --scan-id $SCAN_ID --output evidence.zip
# Contains signed attestations, timestamps, and chain links
4. CI/CD Integration
Scenario: Ensure pipeline decisions are traceable.
With Score Proofs:
# In CI pipeline
- name: Scan with proofs
run: |
stella scan run --image $IMAGE --proof-mode full
stella proof export --scan-id $SCAN_ID --output proof.zip
- name: Upload evidence
uses: actions/upload-artifact@v3
with:
name: security-proof
path: proof.zip
Air-Gap Considerations
Score Proofs work offline with some preparation:
Offline Kit Contents
offline-kit/
├── feeds/ # Frozen advisory feeds
├── trust/ # Trust anchors (public keys)
├── time-anchor/ # Trusted timestamp
└── config/ # Offline configuration
Key Differences
| Feature | Online Mode | Offline Mode |
|---|---|---|
| Advisory feeds | Real-time | Frozen snapshot |
| Time source | NTP/Sigstore | Time anchor |
| Transparency | Rekor | Local ledger |
| Key rotation | Dynamic | Pre-provisioned |
Offline Workflow
# Prepare offline kit
stella airgap prepare --feeds nvd,ghsa --output offline-kit/
# Transfer to air-gapped system
# ... (physical media transfer)
# Run offline scan
stella scan run --offline --kit offline-kit/ --image $IMAGE
Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ Score Proofs System │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Scanner │──▶│ Manifest │──▶│ Signer │ │
│ │ Engine │ │ Generator │ │ (DSSE) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Input │ │ Proof │ │ Transparency│ │
│ │ Store │ │ Ledger │ │ Log │ │
│ │ (CAS) │ │ (Append) │ │ (Rekor) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ Replay Engine │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Bundle │──▶│ Replay │──▶│ Diff │ │
│ │ Loader │ │ Executor │ │ Engine │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Best Practices
1. Always Enable Proofs
# In scanner configuration
stella config set proof.mode full
stella config set proof.transparency enabled
2. Archive Proof Bundles
Store proof bundles alongside your build artifacts:
- Same retention period as releases
- Include in backup procedures
- Index for searchability
3. Verify Periodically
Don't just create proofs—verify them:
# Weekly verification job
stella proof verify --since "7 days ago" --output report.json
4. Plan for Offline Scenarios
Even if you operate online, prepare offline capability:
- Maintain offline kits
- Test offline workflows quarterly
- Document offline procedures
Troubleshooting
"Replay produces different results"
Possible causes:
- Missing input data (check bundle completeness)
- Algorithm version mismatch
- Non-deterministic configuration
Resolution:
stella proof inspect --scan-id $SCAN_ID --check-inputs
"Signature verification failed"
Possible causes:
- Key rotation (old key not trusted)
- Bundle tampering
- Corrupted download
Resolution:
stella proof verify --scan-id $SCAN_ID --verbose
# Check trust anchors
stella trust list
Related Documentation
Last Updated: 2025-12-20
Version: 1.0.0
Sprint: 3500.0004.0004