audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories
This commit is contained in:
503
docs/dev/onboarding/concepts/reachability-concept-guide.md
Normal file
503
docs/dev/onboarding/concepts/reachability-concept-guide.md
Normal file
@@ -0,0 +1,503 @@
|
||||
# Reachability Analysis Concept Guide
|
||||
|
||||
**Sprint:** SPRINT_3500_0004_0004
|
||||
**Audience:** Developers, Security Engineers, DevOps
|
||||
|
||||
## Introduction
|
||||
|
||||
Reachability Analysis determines whether vulnerable code can actually be reached during program execution. This guide explains how StellaOps uses call graphs, BFS traversal, and confidence scoring to separate actionable vulnerabilities from noise.
|
||||
|
||||
---
|
||||
|
||||
## The Problem: Alert Fatigue
|
||||
|
||||
Traditional vulnerability scanners report every known CVE in your dependencies:
|
||||
|
||||
```
|
||||
❌ CVE-2024-1234 in lodash@4.17.20 (CRITICAL)
|
||||
❌ CVE-2024-5678 in express@4.18.0 (HIGH)
|
||||
❌ CVE-2024-9012 in moment@2.29.0 (MEDIUM)
|
||||
... 247 more findings
|
||||
```
|
||||
|
||||
**The reality:**
|
||||
- 80-90% of reported vulnerabilities are **unreachable**
|
||||
- Teams waste time investigating false positives
|
||||
- Real risks get lost in the noise
|
||||
- Security fatigue leads to ignored alerts
|
||||
|
||||
---
|
||||
|
||||
## The Solution: Reachability Analysis
|
||||
|
||||
StellaOps analyzes your application's **call graph** to determine if vulnerable functions are actually invoked:
|
||||
|
||||
```
|
||||
✅ CVE-2024-1234 in lodash@4.17.20 - UNREACHABLE (safe to ignore)
|
||||
⚠️ CVE-2024-5678 in express@4.18.0 - POSSIBLY_REACHABLE (review)
|
||||
🔴 CVE-2024-9012 in moment@2.29.0 - REACHABLE_STATIC (fix required)
|
||||
```
|
||||
|
||||
Result: Focus on the 10-20% that actually matter.
|
||||
|
||||
---
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### 1. Call Graph
|
||||
|
||||
A **Call Graph** represents function calls in your application:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Your Application │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ HTTP Endpoint │ ← Entrypoint │
|
||||
│ │ /api/orders │ │
|
||||
│ └───────┬────────┘ │
|
||||
│ │ calls │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ ┌────────────────┐ │
|
||||
│ │ OrderService │─────▶│ PaymentService │ │
|
||||
│ │ .processOrder()│ │ .charge() │ │
|
||||
│ └───────┬────────┘ └────────────────┘ │
|
||||
│ │ calls │
|
||||
│ ▼ │
|
||||
│ ┌────────────────┐ │
|
||||
│ │ lodash.merge() │ ← Vulnerable function │
|
||||
│ │ (CVE-2024-1234)│ │
|
||||
│ └────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Components:**
|
||||
- **Nodes**: Functions, methods, classes
|
||||
- **Edges**: Call relationships
|
||||
- **Entrypoints**: Where execution begins (HTTP routes, CLI commands, etc.)
|
||||
|
||||
### 2. Entrypoints
|
||||
|
||||
**Entrypoints** are where external input enters your application:
|
||||
|
||||
| Kind | Examples |
|
||||
|------|----------|
|
||||
| HTTP | `GET /api/orders`, `POST /users` |
|
||||
| gRPC | `OrderService.GetOrder` |
|
||||
| Message Queue | `orders.created` consumer |
|
||||
| CLI | `./app --process-file` |
|
||||
| Scheduled | Cron job, background worker |
|
||||
|
||||
### 3. Reachability Status
|
||||
|
||||
Each vulnerability gets one of these statuses:
|
||||
|
||||
| Status | Meaning | Action |
|
||||
|--------|---------|--------|
|
||||
| `UNREACHABLE` | No path from any entrypoint | Safe to ignore |
|
||||
| `POSSIBLY_REACHABLE` | Path exists via indirect/heuristic edges | Review |
|
||||
| `REACHABLE_STATIC` | Direct static path exists | Prioritize fix |
|
||||
| `REACHABLE_PROVEN` | Runtime trace confirms execution | Fix immediately |
|
||||
| `UNKNOWN` | Insufficient call graph data | Investigate |
|
||||
|
||||
### 4. Edge Types
|
||||
|
||||
Call graph edges have different confidence levels:
|
||||
|
||||
| Edge Type | Confidence | Description |
|
||||
|-----------|------------|-------------|
|
||||
| `direct_call` | High | Static function call |
|
||||
| `virtual_dispatch` | Medium | Interface/virtual method |
|
||||
| `reflection` | Low | Reflection-based call |
|
||||
| `dynamic` | Low | Dynamic dispatch |
|
||||
| `heuristic` | Very Low | Inferred relationship |
|
||||
|
||||
### 5. Confidence Score
|
||||
|
||||
**Confidence** quantifies how certain we are about reachability (0.0 to 1.0):
|
||||
|
||||
```
|
||||
Confidence = weighted_sum([
|
||||
staticPathExists × 0.50,
|
||||
allEdgesStatic × 0.20,
|
||||
noReflection × 0.10,
|
||||
runtimeConfirmed × 0.15,
|
||||
symbolResolved × 0.05
|
||||
])
|
||||
```
|
||||
|
||||
Example:
|
||||
- Static path exists: +0.50
|
||||
- All edges are direct calls: +0.20
|
||||
- No reflection: +0.10
|
||||
- Not runtime confirmed: +0.00
|
||||
- All symbols resolved: +0.05
|
||||
- **Total: 0.85**
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
### Step 1: Call Graph Generation
|
||||
|
||||
Your build system generates a call graph using one of these approaches:
|
||||
|
||||
**Build-time extraction** (most accurate):
|
||||
```bash
|
||||
# .NET (roslyn)
|
||||
dotnet build --generate-call-graph
|
||||
|
||||
# Java (gradle plugin)
|
||||
./gradlew generateCallGraph
|
||||
|
||||
# Node.js (static analysis)
|
||||
npx @stellaops/callgraph-generator .
|
||||
```
|
||||
|
||||
**Upload to StellaOps**:
|
||||
```bash
|
||||
stella scan graph upload --scan-id $SCAN_ID --file callgraph.json
|
||||
```
|
||||
|
||||
### Step 2: Entrypoint Detection
|
||||
|
||||
StellaOps identifies entrypoints automatically:
|
||||
|
||||
```json
|
||||
{
|
||||
"entrypoints": [
|
||||
{
|
||||
"kind": "http",
|
||||
"route": "GET /api/orders/{id}",
|
||||
"method": "MyApp.Controllers.OrdersController::Get",
|
||||
"framework": "aspnetcore"
|
||||
},
|
||||
{
|
||||
"kind": "grpc",
|
||||
"service": "OrderService",
|
||||
"method": "MyApp.Services.OrderGrpcService::GetOrder",
|
||||
"framework": "grpc-dotnet"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: BFS Traversal
|
||||
|
||||
For each vulnerability, BFS finds paths from entrypoints:
|
||||
|
||||
```
|
||||
Queue: [HTTP /api/orders → OrdersController::Get]
|
||||
|
||||
Step 1: Visit OrdersController::Get
|
||||
→ Neighbors: [OrderService::Process, Logger::Log]
|
||||
→ Add to queue: OrderService::Process, Logger::Log
|
||||
|
||||
Step 2: Visit OrderService::Process
|
||||
→ Neighbors: [Lodash::merge (VULNERABLE!)]
|
||||
→ PATH FOUND! Depth = 2
|
||||
|
||||
Result: REACHABLE_STATIC
|
||||
Path: /api/orders → OrdersController::Get → OrderService::Process → Lodash::merge
|
||||
```
|
||||
|
||||
### Step 4: Confidence Calculation
|
||||
|
||||
Based on the path quality:
|
||||
|
||||
```yaml
|
||||
path:
|
||||
- node: OrdersController::Get
|
||||
edge_type: entrypoint
|
||||
- node: OrderService::Process
|
||||
edge_type: direct_call # +0.50 static
|
||||
- node: Lodash::merge
|
||||
edge_type: direct_call # +0.20 all static
|
||||
|
||||
factors:
|
||||
staticPathExists: 0.50
|
||||
allEdgesStatic: 0.20
|
||||
noReflection: 0.10
|
||||
runtimeConfirmed: 0.00
|
||||
symbolResolved: 0.05
|
||||
|
||||
confidence: 0.85
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Understanding Results
|
||||
|
||||
### Explain Query
|
||||
|
||||
Get a detailed explanation for any finding:
|
||||
|
||||
```bash
|
||||
stella reachability explain \
|
||||
--scan-id $SCAN_ID \
|
||||
--cve CVE-2024-1234 \
|
||||
--purl "pkg:npm/lodash@4.17.20"
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Status: REACHABLE_STATIC
|
||||
Confidence: 0.85
|
||||
|
||||
Shortest Path (depth=2):
|
||||
[0] MyApp.Controllers.OrdersController::Get(Guid)
|
||||
Entrypoint: HTTP GET /api/orders/{id}
|
||||
[1] MyApp.Services.OrderService::Process(Order)
|
||||
Edge: static (direct_call)
|
||||
[2] Lodash.merge(Object, Object) [VULNERABLE]
|
||||
Edge: static (direct_call)
|
||||
|
||||
Why Reachable:
|
||||
- Static call path exists from HTTP entrypoint
|
||||
- All edges are statically proven (no heuristics)
|
||||
- Vulnerable function is directly invoked
|
||||
|
||||
Confidence Factors:
|
||||
staticPathExists: +0.50
|
||||
allEdgesStatic: +0.20
|
||||
noReflection: +0.10
|
||||
runtimeConfirmed: +0.00
|
||||
symbolResolved: +0.05
|
||||
```
|
||||
|
||||
### Interpreting Status
|
||||
|
||||
| Status | What it means | What to do |
|
||||
|--------|---------------|------------|
|
||||
| `UNREACHABLE` | No code path calls the vulnerable function | Safe to deprioritize; track for visibility |
|
||||
| `POSSIBLY_REACHABLE` | Path exists but involves heuristics | Review the path; add call graph data if missing |
|
||||
| `REACHABLE_STATIC` | Static analysis proves reachability | Prioritize remediation |
|
||||
| `REACHABLE_PROVEN` | Runtime data confirms execution | Fix immediately; exploitability confirmed |
|
||||
| `UNKNOWN` | Call graph incomplete | Improve call graph coverage |
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Generate Complete Call Graphs
|
||||
|
||||
Incomplete call graphs lead to `UNKNOWN` status:
|
||||
|
||||
```bash
|
||||
# Check call graph completeness
|
||||
stella scan graph summary --scan-id $SCAN_ID
|
||||
|
||||
# Output:
|
||||
# Nodes: 12,345 (expected: ~15,000 for project size)
|
||||
# Coverage: 82%
|
||||
# Orphan nodes: 234
|
||||
```
|
||||
|
||||
**Tips for better coverage:**
|
||||
- Include all modules in build
|
||||
- Enable whole-program analysis
|
||||
- Include test code (may reveal paths)
|
||||
|
||||
### 2. Review `POSSIBLY_REACHABLE` Findings
|
||||
|
||||
These often indicate:
|
||||
- Reflection use
|
||||
- Dynamic dispatch
|
||||
- Framework magic (DI, AOP)
|
||||
|
||||
```bash
|
||||
# Get details
|
||||
stella reachability explain \
|
||||
--scan-id $SCAN_ID \
|
||||
--cve CVE-2024-5678 \
|
||||
--all-paths
|
||||
```
|
||||
|
||||
### 3. Add Runtime Evidence
|
||||
|
||||
Runtime traces increase confidence:
|
||||
|
||||
```bash
|
||||
# Enable runtime instrumentation
|
||||
stella scan run \
|
||||
--image $IMAGE \
|
||||
--include-runtime \
|
||||
--runtime-profile production-traces.json
|
||||
```
|
||||
|
||||
### 4. Handle `UNKNOWN` Appropriately
|
||||
|
||||
Don't ignore unknowns—they represent gaps:
|
||||
|
||||
```bash
|
||||
# List unknowns
|
||||
stella reachability findings --scan-id $SCAN_ID --status UNKNOWN
|
||||
|
||||
# Common causes:
|
||||
# - External library without call graph
|
||||
# - Native code (FFI)
|
||||
# - Dynamic languages without type info
|
||||
```
|
||||
|
||||
### 5. Integrate with CI/CD
|
||||
|
||||
```yaml
|
||||
# Example GitHub Actions
|
||||
- name: Run reachability scan
|
||||
run: |
|
||||
stella scan run --image $IMAGE --reachability enabled
|
||||
|
||||
- name: Check for reachable vulnerabilities
|
||||
run: |
|
||||
# Fail if any HIGH+ CVE is reachable
|
||||
REACHABLE=$(stella reachability findings \
|
||||
--scan-id $SCAN_ID \
|
||||
--status REACHABLE_STATIC,REACHABLE_PROVEN \
|
||||
--output-format json | jq 'length')
|
||||
|
||||
if [ "$REACHABLE" -gt 0 ]; then
|
||||
echo "Found $REACHABLE reachable vulnerabilities!"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Call Graph Formats
|
||||
|
||||
### Supported Formats
|
||||
|
||||
| Format | Extension | Use Case |
|
||||
|--------|-----------|----------|
|
||||
| JSON | `.json` | Standard interchange |
|
||||
| NDJSON | `.ndjson` | Large graphs (streaming) |
|
||||
| DOT | `.dot` | Visualization |
|
||||
| Custom | `.cg` | StellaOps native |
|
||||
|
||||
### JSON Schema
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"language": "dotnet",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "sha256:abc123...",
|
||||
"symbol": "MyApp.Services.OrderService::Process",
|
||||
"kind": "method",
|
||||
"location": {
|
||||
"file": "Services/OrderService.cs",
|
||||
"line": 42
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "sha256:abc123...",
|
||||
"target": "sha256:def456...",
|
||||
"type": "direct_call",
|
||||
"location": {
|
||||
"file": "Services/OrderService.cs",
|
||||
"line": 55
|
||||
}
|
||||
}
|
||||
],
|
||||
"entrypoints": [
|
||||
{
|
||||
"nodeId": "sha256:ghi789...",
|
||||
"kind": "http",
|
||||
"route": "GET /api/orders/{id}"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Reachability Analysis System │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Call Graph │──▶│ Entrypoint │──▶│ Reachability│ │
|
||||
│ │ Parser │ │ Detector │ │ Engine │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Graph │ │ Framework │ │ Path │ │
|
||||
│ │ Store │ │ Adapters │ │ Cache │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
│ Symbol Resolution │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ CVE → │──▶│ Symbol │──▶│ Node │ │
|
||||
│ │ Function │ │ Matcher │ │ Lookup │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Too many UNKNOWN findings"
|
||||
|
||||
**Cause**: Incomplete call graph
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Check coverage
|
||||
stella scan graph summary --scan-id $SCAN_ID
|
||||
|
||||
# Regenerate with more options
|
||||
# For .NET:
|
||||
dotnet build --generate-call-graph --whole-program
|
||||
```
|
||||
|
||||
### "False UNREACHABLE"
|
||||
|
||||
**Cause**: Missing edge (reflection, dynamic dispatch)
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Check for known patterns
|
||||
stella scan graph validate --scan-id $SCAN_ID
|
||||
|
||||
# Add hints for reflection patterns
|
||||
stella scan run --reflection-hints reflection-config.json
|
||||
```
|
||||
|
||||
### "Computation timeout"
|
||||
|
||||
**Cause**: Large graph, deep paths
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Increase timeout
|
||||
stella reachability compute --scan-id $SCAN_ID --timeout 600s
|
||||
|
||||
# Or limit depth
|
||||
stella reachability compute --scan-id $SCAN_ID --max-depth 15
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Reachability CLI Reference](../cli/reachability-cli-reference.md)
|
||||
- [Reachability API Reference](../api/score-proofs-reachability-api-reference.md)
|
||||
- [Reachability Runbook](../operations/reachability-runbook.md)
|
||||
- [Score Proofs Concept Guide](./score-proofs-concept-guide.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-12-20
|
||||
**Version**: 1.0.0
|
||||
**Sprint**: 3500.0004.0004
|
||||
378
docs/dev/onboarding/concepts/score-proofs-concept-guide.md
Normal file
378
docs/dev/onboarding/concepts/score-proofs-concept-guide.md
Normal file
@@ -0,0 +1,378 @@
|
||||
# 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:
|
||||
|
||||
1. **Content-addressing all inputs**: Every piece of data is identified by its cryptographic hash
|
||||
2. **Recording computation parameters**: Algorithm versions, timestamps, configuration
|
||||
3. **Creating verifiable attestations**: DSSE-signed bundles that can be independently verified
|
||||
4. **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:
|
||||
|
||||
```yaml
|
||||
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:
|
||||
1. Collects all inputs (SBOM, advisories, call graph, VEX)
|
||||
2. Computes digests for each input
|
||||
3. Records configuration and environment
|
||||
4. Executes the scoring algorithm
|
||||
5. Generates findings with provenance
|
||||
|
||||
### Step 2: Manifest Creation
|
||||
|
||||
After scoring:
|
||||
1. All input digests are assembled into a manifest
|
||||
2. Findings are attached with their own digests
|
||||
3. The manifest is signed using DSSE
|
||||
|
||||
### Step 3: Proof Registration
|
||||
|
||||
The proof is registered:
|
||||
1. Appended to the proof ledger (with chain link)
|
||||
2. Optionally anchored to Sigstore Rekor (transparency log)
|
||||
3. Stored in content-addressed storage
|
||||
|
||||
### Step 4: Verification
|
||||
|
||||
To verify a proof:
|
||||
1. Retrieve the proof bundle
|
||||
2. Verify all signatures
|
||||
3. Check chain integrity (prev_hash)
|
||||
4. Optionally replay the computation
|
||||
5. Compare outputs
|
||||
|
||||
---
|
||||
|
||||
## Use Cases
|
||||
|
||||
### 1. Audit Compliance
|
||||
|
||||
**Scenario**: An auditor asks "How did you arrive at this vulnerability score?"
|
||||
|
||||
**With Score Proofs**:
|
||||
```bash
|
||||
# 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**:
|
||||
```bash
|
||||
# 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**:
|
||||
```bash
|
||||
# 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**:
|
||||
```yaml
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
```bash
|
||||
# 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:**
|
||||
1. Missing input data (check bundle completeness)
|
||||
2. Algorithm version mismatch
|
||||
3. Non-deterministic configuration
|
||||
|
||||
**Resolution:**
|
||||
```bash
|
||||
stella proof inspect --scan-id $SCAN_ID --check-inputs
|
||||
```
|
||||
|
||||
### "Signature verification failed"
|
||||
|
||||
**Possible causes:**
|
||||
1. Key rotation (old key not trusted)
|
||||
2. Bundle tampering
|
||||
3. Corrupted download
|
||||
|
||||
**Resolution:**
|
||||
```bash
|
||||
stella proof verify --scan-id $SCAN_ID --verbose
|
||||
# Check trust anchors
|
||||
stella trust list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Score Proofs CLI Reference](../cli/score-proofs-cli-reference.md)
|
||||
- [Score Proofs API Reference](../api/score-proofs-reachability-api-reference.md)
|
||||
- [Score Proofs Runbook](../operations/score-proofs-runbook.md)
|
||||
- [Air-Gap Runbook](../airgap/score-proofs-reachability-airgap-runbook.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-12-20
|
||||
**Version**: 1.0.0
|
||||
**Sprint**: 3500.0004.0004
|
||||
Reference in New Issue
Block a user