docs(ops): Complete operations runbooks for Epic 3500

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).
This commit is contained in:
StellaOps Bot
2025-12-20 22:30:02 +02:00
parent 09c7155f1b
commit 4b3db9ca85
13 changed files with 5630 additions and 12 deletions

View File

@@ -222,6 +222,206 @@ LS --> IA: PoE (mTLS client cert or JWT with cnf=K_inst), CRL/OCSP/introspect
---
## 4A) Score Proofs & Deterministic Replay
### 4A.1 Overview
Score Proofs provide cryptographically verifiable audit trails for every scoring decision. They enable:
* **Deterministic replay**: Same inputs → same outputs, every time
* **Audit compliance**: Full traceability from inputs to final scores
* **Offline verification**: Proof bundles verifiable without network access
* **Feed updates**: Re-score historical scans with new advisories
### 4A.2 Scan Manifest
Every scan captures its inputs deterministically:
```json
{
"scanId": "550e8400-e29b-41d4-a716-446655440000",
"createdAtUtc": "2025-12-17T12:00:00Z",
"artifactDigest": "sha256:abc123...",
"artifactPurl": "pkg:oci/myapp@sha256:abc123...",
"scannerVersion": "1.0.0",
"workerVersion": "1.0.0",
"concelierSnapshotHash": "sha256:feed123...",
"excititorSnapshotHash": "sha256:vex456...",
"latticePolicyHash": "sha256:policy789...",
"deterministic": true,
"seed": "AQIDBA==",
"knobs": {"maxDepth": "10"}
}
```
### 4A.3 Proof Ledger (DAG)
Scoring computation is recorded as a directed acyclic graph of `ProofNode`:
| Field | Description |
|-------|-------------|
| `id` | Node identifier |
| `kind` | `Input`, `Transform`, `Delta`, `Score` |
| `ruleId` | Policy rule that produced this node |
| `parentIds` | Nodes this depends on |
| `evidenceRefs` | Links to supporting evidence |
| `delta` | Score contribution at this step |
| `total` | Cumulative score |
| `nodeHash` | Content-addressed hash |
The **proof root hash** is computed by hashing all leaf nodes' hashes in deterministic order.
### 4A.4 Score Replay API
```
POST /api/v1/scanner/scans/{id}/score/replay
{ overrides?: { concelierSnapshotHash?, excititorSnapshotHash?, latticePolicyHash? } }
→ { scoreProof, rootHash, proofBundleUri }
```
Use cases:
* **Feed updates**: Re-score when Concelier publishes new advisories
* **Policy changes**: See impact of policy modifications
* **Audit**: Reproduce historical scores for compliance
### 4A.5 Proof Bundle Format
Proof bundles are self-contained ZIP archives:
```
proof-bundle.zip/
├── manifest.json # Canonical scan manifest
├── manifest.dsse.json # DSSE signature
├── score_proof.json # ProofNode[] array
├── proof_root.dsse.json # DSSE of proof root
└── meta.json # Timestamps, versions
```
**Storage**: `scanner.proof_bundle` table + RustFS for bundle files.
---
## 4B) Reachability Analysis
### 4B.1 Overview
Reachability Analysis determines whether vulnerable code is actually reachable from application entrypoints, reducing false positives by filtering unreachable vulnerabilities.
### 4B.2 Call Graph Ingestion
Language-specific workers extract call graphs:
```json
{
"schema": "stella.callgraph.v1",
"language": "dotnet",
"nodes": [...], // Function definitions
"edges": [...], // Call relationships
"entrypoints": [...] // HTTP routes, gRPC, etc.
}
```
**Supported languages**: .NET, Java, Node.js, Python, Go, Rust
### 4B.3 Reachability Statuses
| Status | Confidence | Description |
|--------|------------|-------------|
| `UNREACHABLE` | High | No path from entrypoints to vulnerable code |
| `POSSIBLY_REACHABLE` | Medium | Path exists with heuristic edges |
| `REACHABLE_STATIC` | High | Static analysis proves path exists |
| `REACHABLE_PROVEN` | Very High | Runtime evidence confirms |
| `UNKNOWN` | Low | Insufficient data |
### 4B.4 Reachability API
```
POST /api/v1/scanner/scans/{id}/callgraphs
CallGraph → { callGraphDigest, status }
POST /api/v1/scanner/scans/{id}/reachability/compute
→ { jobId, status }
GET /api/v1/scanner/scans/{id}/reachability/findings
→ { findings[], summary }
GET /api/v1/scanner/scans/{id}/reachability/explain?cve=...&purl=...
→ { status, confidence, shortestPath[], whyReachable[] }
```
### 4B.5 Integration with Score Proofs
Reachability evidence is included in proof bundles:
* Reachability status per CVE/PURL is a scoring input
* Path evidence is referenced in proof nodes
* Graph attestations (DSSE) link to score proofs
**Storage**: `scanner.cg_node`, `scanner.cg_edge`, `scanner.entrypoint` tables.
---
## 4C) Unknowns Registry
### 4C.1 Overview
The Unknowns Registry tracks items that could not be fully classified due to missing evidence, enabling prioritized triage.
### 4C.2 Unknown Reasons
| Code | Description |
|------|-------------|
| `missing_vex` | No VEX statement for vulnerability |
| `ambiguous_indirect_call` | Indirect call target unresolved |
| `incomplete_sbom` | SBOM missing component data |
| `missing_advisory` | No advisory data for CVE |
| `conflicting_evidence` | Multiple conflicting data sources |
### 4C.3 2-Factor Ranking Model
Unknowns are ranked by:
```
score = 0.60 × blast + 0.30 × scarcity + 0.30 × pressure + containment_deduction
```
| Factor | Weight | Components |
|--------|--------|------------|
| Blast Radius | 0.60 | Dependents, network exposure, privilege |
| Evidence Scarcity | 0.30 | Missing data severity |
| Exploit Pressure | 0.30 | EPSS, KEV status |
| Containment | -0.20 | Seccomp, read-only FS |
### 4C.4 Band Assignment
| Band | Score Range | SLA |
|------|-------------|-----|
| HOT | ≥ 0.70 | 24 hours |
| WARM | 0.40 - 0.69 | 7 days |
| COLD | < 0.40 | 30 days |
### 4C.5 Unknowns API
```
GET /api/v1/unknowns
?band=HOT&sort=score → { items[], pagination }
GET /api/v1/unknowns/{id}
→ { id, reasons, blastRadius, score, scoreBreakdown }
GET /api/v1/unknowns/{id}/proof
→ { nodes[], rootHash }
POST /api/v1/unknowns/{id}/escalate
→ { rescanJobId, status }
POST /api/v1/unknowns/{id}/resolve
{ resolution, justification } → { resolvedAt }
```
**Storage**: `policy.unknowns` table with ranking metadata.
---
## 5) Runtime enforcement (Zastava)
* **Observer:** inventories running containers, checks image signatures, SBOM presence (referrers), detects drift (entrypoint chain divergence), flags unapproved images.

View File

@@ -0,0 +1,616 @@
# Air-Gap Operations Runbook for Score Proofs & Reachability
> **Version**: 1.0.0
> **Sprint**: 3500.0004.0004
> **Last Updated**: 2025-12-20
This runbook covers air-gapped operations for Score Proofs and Reachability features, including offline kit deployment, proof verification, and bundle management.
---
## Table of Contents
1. [Overview](#1-overview)
2. [Offline Kit Deployment](#2-offline-kit-deployment)
3. [Score Proofs in Air-Gap Mode](#3-score-proofs-in-air-gap-mode)
4. [Reachability in Air-Gap Mode](#4-reachability-in-air-gap-mode)
5. [Bundle Import Operations](#5-bundle-import-operations)
6. [Proof Verification Offline](#6-proof-verification-offline)
7. [Troubleshooting](#7-troubleshooting)
8. [Monitoring & Alerting](#8-monitoring--alerting)
---
## 1. Overview
### Air-Gap Modes
| Mode | Network | Use Case |
|------|---------|----------|
| **Sealed** | No external connectivity | Classified environments |
| **Constrained** | Limited egress (allowlist) | Regulated networks |
| **Hybrid** | Selective connectivity | Standard enterprise |
### Score Proofs Air-Gap Capabilities
| Feature | Sealed | Constrained | Hybrid |
|---------|--------|-------------|--------|
| Score computation | ✅ | ✅ | ✅ |
| Score replay | ✅ | ✅ | ✅ |
| Proof generation | ✅ | ✅ | ✅ |
| Proof verification | ✅ | ✅ | ✅ |
| Rekor logging | ❌ | 🔶 (optional) | ✅ |
| Feed updates | Bundle | Bundle | Online |
### Reachability Air-Gap Capabilities
| Feature | Sealed | Constrained | Hybrid |
|---------|--------|-------------|--------|
| Call graph upload | ✅ | ✅ | ✅ |
| Reachability compute | ✅ | ✅ | ✅ |
| Explain queries | ✅ | ✅ | ✅ |
| Symbol resolution | Bundle | Bundle | Online |
---
## 2. Offline Kit Deployment
### 2.1 Offline Kit Contents
The offline kit contains everything needed for air-gapped Score Proofs and Reachability:
```
offline-kit/
├── manifests/
│ ├── kit-manifest.json # Kit metadata and versions
│ ├── feed-manifest.json # Advisory feed snapshot
│ └── vex-manifest.json # VEX data snapshot
├── feeds/
│ ├── concelier/ # Advisory feed data
│ │ ├── advisories.ndjson
│ │ └── snapshot.dsse.json
│ └── excititor/ # VEX data
│ ├── vex-statements.ndjson
│ └── snapshot.dsse.json
├── policies/
│ ├── scoring-policy.yaml
│ └── policy.dsse.json
├── trust/
│ ├── trust-anchors.json # Public keys for verification
│ └── time-anchor.json # Time attestation
├── symbols/
│ └── symbol-index.db # Symbol resolution database
└── tools/
├── stella-cli # CLI binary
└── verify-kit.sh # Kit verification script
```
### 2.2 Verify Kit Integrity
Before deployment, always verify the offline kit:
```bash
# Verify kit signature
stella airgap verify-kit --kit /path/to/offline-kit
# Output:
# Kit manifest: VALID
# Feed snapshot: VALID (sha256:feed123...)
# VEX snapshot: VALID (sha256:vex456...)
# Policy: VALID (sha256:policy789...)
# Trust anchors: VALID (3 anchors)
# Time anchor: VALID (expires: 2025-12-31T00:00:00Z)
#
# Kit verification: PASSED
# Verify individual components
stella airgap verify --file feeds/concelier/snapshot.dsse.json
stella airgap verify --file feeds/excititor/snapshot.dsse.json
stella airgap verify --file policies/policy.dsse.json
```
### 2.3 Deploy Offline Kit
```bash
# Deploy kit (sealed mode)
stella airgap deploy --kit /path/to/offline-kit --mode sealed
# Deploy kit (constrained mode with limited egress)
stella airgap deploy --kit /path/to/offline-kit \
--mode constrained \
--egress-allowlist https://rekor.sigstore.dev
# Verify deployment
stella airgap status
# Output:
# Mode: sealed
# Kit version: 2025.12.20
# Feed snapshot: sha256:feed123... (2025-12-20)
# VEX snapshot: sha256:vex456... (2025-12-20)
# Policy: sha256:policy789... (v1.2.3)
# Trust anchors: 3 active
# Time anchor: Valid until 2025-12-31
# Staleness: OK (0 days)
```
### 2.4 Kit Updates
```bash
# Check for kit updates (requires external access or new media)
stella airgap check-update --current-kit /path/to/current-kit
# Import new kit
stella airgap import-kit --kit /path/to/new-kit --validate
# Rollback to previous kit
stella airgap rollback --generation previous
```
---
## 3. Score Proofs in Air-Gap Mode
### 3.1 Create Scan (Air-Gap)
```bash
# Create scan referencing offline kit snapshots
stella scan create --artifact sha256:abc123... \
--airgap \
--feed-snapshot sha256:feed123... \
--vex-snapshot sha256:vex456... \
--policy-snapshot sha256:policy789...
# Or auto-detect from deployed kit
stella scan create --artifact sha256:abc123... --use-offline-kit
```
### 3.2 Score Replay (Air-Gap)
```bash
# Replay with offline kit snapshots
stella score replay --scan-id $SCAN_ID --offline
# Replay with specific bundle
stella score replay --scan-id $SCAN_ID \
--offline \
--bundle /path/to/proof-bundle.zip
# Compare with different kit versions
stella score replay --scan-id $SCAN_ID \
--offline \
--feed-snapshot sha256:newfeed... \
--diff
```
### 3.3 Generate Proof Bundle (Air-Gap)
```bash
# Generate proof bundle for export
stella proof export --scan-id $SCAN_ID \
--include-manifest \
--include-chain \
--output proof-bundle.zip
# Proof bundle contents (air-gap safe):
# - manifest.json (canonical)
# - manifest.dsse.json
# - score_proof.json
# - proof_root.dsse.json
# - meta.json
# - NO external references
# Generate portable bundle
stella proof export --scan-id $SCAN_ID \
--portable \
--include-trust-anchors \
--output portable-proof.zip
```
---
## 4. Reachability in Air-Gap Mode
### 4.1 Call Graph Operations (Air-Gap)
```bash
# Upload call graph (works identically)
stella scan graph upload --scan-id $SCAN_ID --file callgraph.json
# Call graph processing is fully local
# No external network required
```
### 4.2 Compute Reachability (Air-Gap)
```bash
# Compute reachability (fully offline)
stella reachability compute --scan-id $SCAN_ID --offline
# Symbol resolution uses offline database
stella reachability compute --scan-id $SCAN_ID \
--offline \
--symbol-db /path/to/offline-kit/symbols/symbol-index.db
```
### 4.3 Explain Queries (Air-Gap)
```bash
# Explain queries work offline
stella reachability explain --scan-id $SCAN_ID \
--cve CVE-2024-1234 \
--purl "pkg:npm/lodash@4.17.20" \
--offline
# Export explanations for external review
stella reachability explain-all --scan-id $SCAN_ID \
--output explanations.json \
--offline
```
---
## 5. Bundle Import Operations
### 5.1 Import Feed Updates
```bash
# Verify feed bundle before import
stella airgap verify --bundle feed-update.zip
# Dry-run import
stella airgap import --bundle feed-update.zip \
--type feed \
--dry-run
# Import feed bundle
stella airgap import --bundle feed-update.zip \
--type feed \
--generation 2025.12.21
# Verify import
stella airgap verify-import --generation 2025.12.21
```
### 5.2 Import VEX Updates
```bash
# Import VEX bundle
stella airgap import --bundle vex-update.zip \
--type vex \
--generation 2025.12.21
# Verify VEX statements
stella airgap vex-status
# Output:
# VEX statements: 15,432
# Last update: 2025-12-21
# Generation: 2025.12.21
# Signature: VALID
```
### 5.3 Import Trust Anchors
```bash
# Import new trust anchor (requires approval)
stella airgap import-anchor --file new-anchor.json \
--reason "Key rotation Q4 2025" \
--approver admin@example.com
# Verify anchor chain
stella airgap verify-anchors
# List active anchors
stella airgap anchors list
```
### 5.4 Import Checklist
**Pre-Import**:
- [ ] Verify bundle signature (DSSE)
- [ ] Verify bundle hash matches manifest
- [ ] Confirm sealed/constrained mode is set
- [ ] Backup current generation
**Import**:
- [ ] Run dry-run import
- [ ] Apply import
- [ ] Verify import succeeded
**Post-Import**:
- [ ] Verify timeline event emitted
- [ ] Update staleness dashboard
- [ ] Archive import manifest
- [ ] Update audit log
---
## 6. Proof Verification Offline
### 6.1 Verify Proof Bundle (Full Offline)
```bash
# Verify proof bundle without any network access
stella proof verify --bundle proof-bundle.zip \
--offline \
--trust-anchor /path/to/trust-anchors.json
# Verification checks (offline):
# ✅ Signature valid (DSSE)
# ✅ Content-addressed ID matches
# ✅ Merkle path valid
# ⏭️ Rekor inclusion (SKIPPED - offline mode)
# ✅ Time anchor valid
```
### 6.2 Verify with Portable Bundle
```bash
# Portable bundles include trust anchors
stella proof verify --bundle portable-proof.zip \
--offline \
--self-contained
# Output:
# Using embedded trust anchors
# Signature verification: PASS
# ID recomputation: PASS
# Merkle path: PASS
# Time anchor: VALID
# Overall: VERIFIED
```
### 6.3 Batch Verification
```bash
# Verify multiple bundles
stella proof verify-batch --dir /path/to/bundles/ \
--offline \
--trust-anchor /path/to/trust-anchors.json \
--output verification-report.json
# Generate verification report
cat verification-report.json | jq '.summary'
# Output:
# {
# "total": 100,
# "verified": 98,
# "failed": 2,
# "skipped": 0
# }
```
### 6.4 Verification Without CLI
For environments without the CLI, manual verification is possible:
```bash
# 1. Extract bundle
unzip proof-bundle.zip -d ./verify/
# 2. Verify DSSE signature (using openssl)
# Extract payload from DSSE envelope
cat ./verify/manifest.dsse.json | jq -r '.payload' | base64 -d > payload.json
# Verify signature
cat ./verify/manifest.dsse.json | jq -r '.signatures[0].sig' | base64 -d > signature.bin
openssl dgst -sha256 -verify trust-anchor-pubkey.pem -signature signature.bin payload.json
# 3. Verify content-addressed ID
# Compute canonical hash
cat ./verify/manifest.json | jq -cS . | sha256sum
# Compare with manifestHash in bundle
# 4. Verify merkle path
# (See docs/airgap/proof-chain-verification.md for algorithm)
```
---
## 7. Troubleshooting
### 7.1 Kit Verification Failed
**Symptom**: `stella airgap verify-kit` fails.
**Diagnosis**:
```bash
# Check specific component
stella airgap verify-kit --verbose --component feeds
# Common errors:
# - "Signature verification failed": Key mismatch
# - "Hash mismatch": Bundle corrupted during transfer
# - "Time anchor expired": Anchor needs refresh
```
**Resolution**:
| Error | Cause | Resolution |
|-------|-------|------------|
| Signature failed | Wrong trust anchor | Import correct anchor |
| Hash mismatch | Corruption | Re-transfer bundle |
| Time anchor expired | Clock drift or expired | Import new time anchor |
### 7.2 Staleness Alert
**Symptom**: Staleness warning/alert.
**Diagnosis**:
```bash
# Check staleness status
stella airgap staleness-status
# Output:
# Feed age: 5 days (threshold: 7 days)
# VEX age: 3 days (threshold: 7 days)
# Policy age: 30 days (threshold: 90 days)
# Status: AMBER (approaching threshold)
```
**Resolution**:
```bash
# Import updated bundles
stella airgap import --bundle /path/to/latest-feed.zip --type feed
# If bundles unavailable and breach imminent:
# - Raise amber alert (5-7 days)
# - If >7 days, raise red alert and halt new ingests
# - Request emergency bundle via secure channel
```
### 7.3 Proof Verification Fails Offline
**Symptom**: Proof verification fails in sealed mode.
**Diagnosis**:
```bash
# Check verification error
stella proof verify --bundle proof.zip --offline --verbose
# Common errors:
# - "Trust anchor not found": Missing anchor in offline kit
# - "Time anchor expired": Time validation failed
# - "Unsupported algorithm": Key algorithm not supported
```
**Resolution**:
```bash
# For missing trust anchor:
# Import the required anchor
stella airgap import-anchor --file required-anchor.json
# For expired time anchor:
# Import new time anchor
stella airgap import-time-anchor --file new-time-anchor.json
# For algorithm issues:
# Regenerate proof with supported algorithm
stella proof regenerate --scan-id $SCAN_ID --algorithm ECDSA-P256
```
### 7.4 Symbol Resolution Fails
**Symptom**: Reachability shows "symbol not found" errors.
**Diagnosis**:
```bash
# Check symbol database status
stella airgap symbols-status
# Output:
# Symbol DB: /path/to/symbols/symbol-index.db
# Version: 2025.12.15
# Entries: 5,234,567
# Coverage: Java, .NET, Python
```
**Resolution**:
```bash
# Import updated symbol database
stella airgap import --bundle symbol-update.zip --type symbols
# Recompute reachability with new symbols
stella reachability compute --scan-id $SCAN_ID --offline --force
```
---
## 8. Monitoring & Alerting
### 8.1 Key Metrics (Air-Gap)
| Metric | Description | Alert Threshold |
|--------|-------------|-----------------|
| `airgap_staleness_days` | Days since last bundle import | > 5 (amber), > 7 (red) |
| `airgap_time_anchor_validity_days` | Days until time anchor expires | < 7 |
| `airgap_verification_failures` | Offline verification failures | > 0 |
| `airgap_import_failures` | Bundle import failures | > 0 |
### 8.2 Alerting Rules
```yaml
groups:
- name: airgap-operations
rules:
- alert: AirgapStalenessAmber
expr: airgap_staleness_days > 5
for: 1h
labels:
severity: warning
annotations:
summary: "Air-gap feed staleness approaching threshold"
- alert: AirgapStalenessRed
expr: airgap_staleness_days > 7
for: 1h
labels:
severity: critical
annotations:
summary: "Air-gap feed staleness breach - halt new ingests"
- alert: AirgapTimeAnchorExpiring
expr: airgap_time_anchor_validity_days < 7
for: 1h
labels:
severity: warning
annotations:
summary: "Time anchor expiring in {{ $value }} days"
- alert: AirgapVerificationFailure
expr: increase(airgap_verification_failures_total[1h]) > 0
for: 5m
labels:
severity: critical
annotations:
summary: "Air-gap verification failures detected"
```
### 8.3 Audit Requirements
For air-gapped environments, maintain strict audit trails:
```bash
# Record every import
{
"timestamp": "2025-12-20T10:00:00Z",
"action": "import",
"bundleType": "feed",
"bundleHash": "sha256:feed123...",
"generation": "2025.12.20",
"actor": "operator@example.com",
"mode": "sealed",
"verification": "PASS"
}
# Daily audit log export
stella airgap audit-export --date today --output audit-$(date +%Y%m%d).json
# Verify audit log integrity
stella airgap audit-verify --log audit-20251220.json
```
---
## Related Documentation
- [Air-Gap Overview](./overview.md)
- [Offline Bundle Format](./offline-bundle-format.md)
- [Proof Chain Verification](./proof-chain-verification.md)
- [Time Anchor Schema](./time-anchor-schema.md)
- [Score Proofs Runbook](../operations/score-proofs-runbook.md)
- [Reachability Runbook](../operations/reachability-runbook.md)
---
**Last Updated**: 2025-12-20
**Version**: 1.0.0
**Sprint**: 3500.0004.0004

View File

@@ -0,0 +1,558 @@
# Reachability CLI Reference
**Sprint:** SPRINT_3500_0004_0004
**Version:** 1.0.0
## Overview
The Reachability CLI commands enable call graph management, reachability computation, and explain queries. All commands support air-gapped operation.
---
## Commands
### stella reachability
Manage reachability analysis.
```bash
stella reachability <SUBCOMMAND> [OPTIONS]
```
#### Subcommands
| Subcommand | Description |
|------------|-------------|
| `compute` | Trigger reachability computation |
| `findings` | List reachability findings |
| `explain` | Explain reachability verdict |
| `explain-all` | Export all explanations |
| `summary` | Show reachability summary |
| `job-status` | Check computation job status |
| `job-logs` | View job logs |
| `job-cancel` | Cancel running job |
---
### stella reachability compute
Trigger reachability computation for a scan.
```bash
stella reachability compute [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--max-depth <N>` | Maximum path length to explore | 10 |
| `--indirect-resolution <MODE>` | Handle indirect calls: `conservative`, `aggressive`, `skip` | `conservative` |
| `--timeout <DURATION>` | Maximum computation time | 300s |
| `--parallel` | Enable parallel BFS | `true` |
| `--include-runtime` | Merge runtime evidence | `true` |
| `--offline` | Run in offline mode | `false` |
| `--symbol-db <PATH>` | Symbol resolution database | System default |
| `--deterministic` | Enable deterministic mode | `true` |
| `--seed <BASE64>` | Random seed for determinism | Auto |
| `--graph-digest <HASH>` | Use specific call graph version | Latest |
| `--partition-by <KEY>` | Partition analysis: `artifact`, `entrypoint` | — |
| `--force` | Force recomputation | `false` |
| `--wait` | Wait for completion | `false` |
#### Examples
```bash
# Basic computation
stella reachability compute --scan-id $SCAN_ID
# With custom options
stella reachability compute --scan-id $SCAN_ID \
--max-depth 20 \
--timeout 600s \
--indirect-resolution conservative
# Wait for completion
stella reachability compute --scan-id $SCAN_ID --wait
# Offline computation
stella reachability compute --scan-id $SCAN_ID --offline
```
---
### stella reachability findings
List reachability findings for a scan.
```bash
stella reachability findings [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--status <STATUS>` | Filter by status (comma-separated) | All |
| `--cve <ID>` | Filter by CVE ID | — |
| `--purl <PURL>` | Filter by package URL | — |
| `--min-confidence <N>` | Minimum confidence (0-1) | 0 |
| `--output <PATH>` | Output file path | stdout |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table`, `sarif` | `table` |
#### Status Values
| Status | Description |
|--------|-------------|
| `UNREACHABLE` | No path found |
| `POSSIBLY_REACHABLE` | Path with heuristic edges |
| `REACHABLE_STATIC` | Statically proven path |
| `REACHABLE_PROVEN` | Runtime confirmed |
| `UNKNOWN` | Insufficient data |
#### Examples
```bash
# List all findings
stella reachability findings --scan-id $SCAN_ID
# Filter by status
stella reachability findings --scan-id $SCAN_ID \
--status REACHABLE_STATIC,REACHABLE_PROVEN
# Export as SARIF for CI
stella reachability findings --scan-id $SCAN_ID \
--status REACHABLE_STATIC,REACHABLE_PROVEN \
--output-format sarif \
--output findings.sarif
# JSON output
stella reachability findings --scan-id $SCAN_ID --output-format json
```
---
### stella reachability explain
Explain a reachability verdict.
```bash
stella reachability explain [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--cve <ID>` | CVE ID | Required |
| `--purl <PURL>` | Package URL | Required |
| `--all-paths` | Show all paths, not just shortest | `false` |
| `--max-paths <N>` | Maximum paths to show | 5 |
| `--verbose` | Show detailed explanation | `false` |
| `--offline` | Run in offline mode | `false` |
| `--output <PATH>` | Output file path | stdout |
| `--output-format <FMT>` | Format: `json`, `yaml`, `text` | `text` |
#### Examples
```bash
# Explain single finding
stella reachability explain --scan-id $SCAN_ID \
--cve CVE-2024-1234 \
--purl "pkg:npm/lodash@4.17.20"
# Show all paths
stella reachability explain --scan-id $SCAN_ID \
--cve CVE-2024-1234 \
--purl "pkg:npm/lodash@4.17.20" \
--all-paths
# JSON output
stella reachability explain --scan-id $SCAN_ID \
--cve CVE-2024-1234 \
--purl "pkg:npm/lodash@4.17.20" \
--output-format json
```
#### Output Example
```
Status: REACHABLE_STATIC
Confidence: 0.70
Shortest Path (depth=3):
[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 /api/orders/{id}
- All edges are statically proven (no heuristics)
- Vulnerable function Lodash.merge() is directly invoked
Confidence Factors:
staticPathExists: +0.50
noHeuristicEdges: +0.20
runtimeConfirmed: +0.00
Alternative Paths: 2
```
---
### stella reachability explain-all
Export all reachability explanations.
```bash
stella reachability explain-all [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--status <STATUS>` | Filter by status | All |
| `--output <PATH>` | Output file path | Required |
| `--offline` | Run in offline mode | `false` |
#### Examples
```bash
# Export all explanations
stella reachability explain-all --scan-id $SCAN_ID --output explanations.json
# Export only reachable findings
stella reachability explain-all --scan-id $SCAN_ID \
--status REACHABLE_STATIC,REACHABLE_PROVEN \
--output reachable-explanations.json
```
---
### stella reachability summary
Show reachability summary for a scan.
```bash
stella reachability summary [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table` | `table` |
#### Examples
```bash
# Show summary
stella reachability summary --scan-id $SCAN_ID
# Output:
# Total vulnerabilities: 45
# Unreachable: 38 (84%)
# Possibly reachable: 4 (9%)
# Reachable (static): 2 (4%)
# Reachable (proven): 1 (2%)
# Unknown: 0 (0%)
```
---
### stella reachability job-status
Check computation job status.
```bash
stella reachability job-status [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--job-id <ID>` | Job ID | Required |
#### Examples
```bash
stella reachability job-status --job-id reachability-job-001
# Output:
# Status: running
# Progress: 67% (8,234 / 12,345 nodes visited)
# Started: 2025-12-20T10:00:00Z
# Estimated completion: 2025-12-20T10:02:30Z
```
---
## Call Graph Commands
### stella scan graph
Manage call graphs.
```bash
stella scan graph <SUBCOMMAND> [OPTIONS]
```
#### Subcommands
| Subcommand | Description |
|------------|-------------|
| `upload` | Upload call graph |
| `summary` | Show call graph summary |
| `entrypoints` | List entrypoints |
| `export` | Export call graph |
| `validate` | Validate call graph |
| `visualize` | Generate visualization |
| `convert` | Convert graph format |
| `partition` | Partition large graph |
| `merge` | Merge multiple graphs |
---
### stella scan graph upload
Upload a call graph to a scan.
```bash
stella scan graph upload [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--file <PATH>` | Call graph file | Required |
| `--format <FMT>` | Format: `json`, `ndjson` | Auto-detect |
| `--streaming` | Use streaming upload | `false` |
| `--framework <NAME>` | Framework hint | Auto-detect |
#### Examples
```bash
# Basic upload
stella scan graph upload --scan-id $SCAN_ID --file callgraph.json
# Streaming upload (large graphs)
stella scan graph upload --scan-id $SCAN_ID \
--file callgraph.ndjson \
--format ndjson \
--streaming
# With framework hint
stella scan graph upload --scan-id $SCAN_ID \
--file callgraph.json \
--framework aspnetcore
```
---
### stella scan graph summary
Show call graph summary.
```bash
stella scan graph summary [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
#### Examples
```bash
stella scan graph summary --scan-id $SCAN_ID
# Output:
# Nodes: 12,345
# Edges: 56,789
# Entrypoints: 42
# Languages: [dotnet, java]
# Size: 15.2 MB
```
---
### stella scan graph entrypoints
List detected entrypoints.
```bash
stella scan graph entrypoints [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--verbose` | Show detailed info | `false` |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table` | `table` |
#### Examples
```bash
# List entrypoints
stella scan graph entrypoints --scan-id $SCAN_ID
# Output:
# Kind | Route | Framework | Node
# ─────────┼─────────────────────┼─────────────┼────────────────
# http | GET /api/orders | aspnetcore | OrdersController::Get
# http | POST /api/orders | aspnetcore | OrdersController::Create
# grpc | OrderService.Get | grpc-dotnet | OrderService::GetOrder
```
---
### stella scan graph validate
Validate call graph structure.
```bash
stella scan graph validate [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Validate uploaded graph | — |
| `--file <PATH>` | Validate local file | — |
| `--strict` | Enable strict validation | `false` |
#### Validation Checks
- All edge targets exist as nodes
- Entrypoints reference valid nodes
- No orphan nodes
- No cycles in entrypoint definitions
- Schema compliance
#### Examples
```bash
# Validate uploaded graph
stella scan graph validate --scan-id $SCAN_ID
# Validate before upload
stella scan graph validate --file callgraph.json --strict
```
---
### stella scan graph visualize
Generate call graph visualization.
```bash
stella scan graph visualize [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--node <ID>` | Center on specific node | — |
| `--depth <N>` | Visualization depth | 3 |
| `--output <PATH>` | Output file (SVG/PNG/DOT) | Required |
| `--format <FMT>` | Format: `svg`, `png`, `dot` | `svg` |
#### Examples
```bash
# Visualize subgraph
stella scan graph visualize --scan-id $SCAN_ID \
--node sha256:node123... \
--depth 3 \
--output subgraph.svg
```
---
## Common Options
### Authentication
| Option | Description |
|--------|-------------|
| `--token <TOKEN>` | OAuth bearer token |
| `--token-file <PATH>` | File containing token |
| `--profile <NAME>` | Use named profile |
### Output
| Option | Description |
|--------|-------------|
| `--quiet` | Suppress non-error output |
| `--verbose` | Enable verbose output |
| `--debug` | Enable debug logging |
| `--no-color` | Disable colored output |
### Connection
| Option | Description |
|--------|-------------|
| `--endpoint <URL>` | Scanner API endpoint |
| `--timeout <DURATION>` | Request timeout |
| `--insecure` | Skip TLS verification |
---
## Environment Variables
| Variable | Description |
|----------|-------------|
| `STELLA_TOKEN` | OAuth token |
| `STELLA_ENDPOINT` | API endpoint |
| `STELLA_PROFILE` | Profile name |
| `STELLA_OFFLINE` | Offline mode |
| `STELLA_SYMBOL_DB` | Symbol database path |
---
## Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | Authentication failed |
| 4 | Resource not found |
| 5 | Computation failed |
| 6 | Network error |
| 10 | Timeout |
---
## Related Documentation
- [Score Proofs CLI Reference](./score-proofs-cli-reference.md)
- [Unknowns CLI Reference](./unknowns-cli-reference.md)
- [Reachability API Reference](../api/score-proofs-reachability-api-reference.md)
- [Reachability Runbook](../operations/reachability-runbook.md)
---
**Last Updated**: 2025-12-20
**Version**: 1.0.0
**Sprint**: 3500.0004.0004

View File

@@ -0,0 +1,450 @@
# Score Proofs CLI Reference
**Sprint:** SPRINT_3500_0004_0004
**Version:** 1.0.0
## Overview
The Score Proofs CLI commands enable score computation, replay, proof verification, and proof bundle management. All commands support air-gapped operation.
---
## Commands
### stella score
Compute or replay vulnerability scores.
```bash
stella score <SUBCOMMAND> [OPTIONS]
```
#### Subcommands
| Subcommand | Description |
|------------|-------------|
| `compute` | Compute scores for a scan |
| `replay` | Replay score computation with different inputs |
| `show` | Display score details for a scan |
| `diff` | Compare scores between runs |
| `manifest` | View/export scan manifest |
| `inputs` | List scoring inputs |
---
### stella score compute
Compute vulnerability scores for a scan.
```bash
stella score compute [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID to compute scores for | Required |
| `--deterministic` | Enable deterministic mode | `true` |
| `--seed <BASE64>` | Random seed for determinism | Auto-generated |
| `--output <PATH>` | Output file path | stdout |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table` | `table` |
| `--include-proof` | Include proof ledger in output | `false` |
#### Examples
```bash
# Compute scores
stella score compute --scan-id $SCAN_ID
# Compute with proof output
stella score compute --scan-id $SCAN_ID --include-proof --output-format json
# Compute in deterministic mode with fixed seed
stella score compute --scan-id $SCAN_ID --deterministic --seed "AQIDBA=="
```
---
### stella score replay
Replay score computation with updated feeds or policies.
```bash
stella score replay [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID to replay | Required |
| `--feed-snapshot <HASH>` | Override feed snapshot hash | Current |
| `--vex-snapshot <HASH>` | Override VEX snapshot hash | Current |
| `--policy-snapshot <HASH>` | Override policy hash | Current |
| `--use-original-snapshots` | Use exact original snapshots | `false` |
| `--diff` | Show diff from original | `false` |
| `--skip-unchanged` | Skip if no input changes | `false` |
| `--offline` | Run in offline mode | `false` |
| `--bundle <PATH>` | Use offline bundle for replay | — |
| `--output <PATH>` | Output file path | stdout |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table` | `table` |
#### Examples
```bash
# Replay with current feeds
stella score replay --scan-id $SCAN_ID
# Replay with specific feed snapshot
stella score replay --scan-id $SCAN_ID --feed-snapshot sha256:newfeed...
# Replay and compare with original
stella score replay --scan-id $SCAN_ID --diff
# Replay with original snapshots (exact reproduction)
stella score replay --scan-id $SCAN_ID --use-original-snapshots
# Offline replay
stella score replay --scan-id $SCAN_ID --offline --bundle /path/to/bundle.zip
```
---
### stella score show
Display score details for a scan.
```bash
stella score show [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--verbose` | Show detailed breakdown | `false` |
| `--include-evidence` | Include evidence references | `false` |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table` | `table` |
#### Examples
```bash
# Show score summary
stella score show --scan-id $SCAN_ID
# Show detailed breakdown
stella score show --scan-id $SCAN_ID --verbose
# JSON output
stella score show --scan-id $SCAN_ID --output-format json
```
---
### stella score diff
Compare scores between two runs.
```bash
stella score diff [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID to compare | Required |
| `--original` | Compare with original score | `false` |
| `--replayed` | Compare with most recent replay | `false` |
| `--base <RUN_ID>` | Base run ID for comparison | — |
| `--target <RUN_ID>` | Target run ID for comparison | — |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table` | `table` |
#### Examples
```bash
# Compare original vs replayed
stella score diff --scan-id $SCAN_ID --original --replayed
# Compare two specific runs
stella score diff --scan-id $SCAN_ID --base run-001 --target run-002
```
---
### stella score manifest
View or export scan manifest.
```bash
stella score manifest [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--output <PATH>` | Output file path | stdout |
| `--include-dsse` | Include DSSE envelope | `false` |
| `--verify` | Verify DSSE signature | `false` |
#### Examples
```bash
# View manifest
stella score manifest --scan-id $SCAN_ID
# Export with DSSE
stella score manifest --scan-id $SCAN_ID --include-dsse --output manifest.json
# Verify manifest signature
stella score manifest --scan-id $SCAN_ID --verify
```
---
## Proof Commands
### stella proof
Manage proof bundles.
```bash
stella proof <SUBCOMMAND> [OPTIONS]
```
#### Subcommands
| Subcommand | Description |
|------------|-------------|
| `verify` | Verify a proof bundle |
| `download` | Download proof bundle |
| `export` | Export proof bundle |
| `inspect` | Inspect proof bundle contents |
| `status` | Check proof status |
| `list` | List proofs for a scan |
| `retrieve` | Retrieve from cold storage |
---
### stella proof verify
Verify a proof bundle.
```bash
stella proof verify [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--bundle-id <HASH>` | Proof bundle ID (sha256:...) | — |
| `--bundle <PATH>` | Local proof bundle file | — |
| `--offline` | Skip Rekor verification | `false` |
| `--skip-rekor` | Alias for --offline | `false` |
| `--check-rekor` | Force Rekor verification | `false` |
| `--trust-anchor <PATH>` | Trust anchor file | System default |
| `--public-key <PATH>` | Public key file | — |
| `--self-contained` | Use embedded trust anchors | `false` |
| `--verbose` | Show detailed verification | `false` |
| `--check <CHECK>` | Verify specific check only | All |
#### Verification Checks
| Check | Description |
|-------|-------------|
| `signatureValid` | DSSE signature verification |
| `idRecomputed` | Content-addressed ID match |
| `merklePathValid` | Merkle tree construction |
| `rekorInclusion` | Transparency log entry |
#### Examples
```bash
# Verify online
stella proof verify --bundle-id sha256:proof123...
# Verify offline
stella proof verify --bundle proof.zip --offline
# Verify with specific trust anchor
stella proof verify --bundle proof.zip --offline --trust-anchor anchors.json
# Verify specific check
stella proof verify --bundle-id sha256:proof123... --check signatureValid
```
---
### stella proof download
Download proof bundle.
```bash
stella proof download [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--root-hash <HASH>` | Specific proof root hash | Latest |
| `--output <PATH>` | Output file path | `proof-{scanId}.zip` |
| `--all` | Download all proofs for scan | `false` |
| `--output-dir <PATH>` | Output directory (with --all) | `.` |
#### Examples
```bash
# Download latest proof
stella proof download --scan-id $SCAN_ID --output proof.zip
# Download specific proof
stella proof download --scan-id $SCAN_ID --root-hash sha256:proof123... --output proof.zip
# Download all proofs
stella proof download --scan-id $SCAN_ID --all --output-dir ./proofs/
```
---
### stella proof export
Export proof bundle with additional data.
```bash
stella proof export [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Scan ID | Required |
| `--portable` | Create self-contained portable bundle | `false` |
| `--include-manifest` | Include scan manifest | `true` |
| `--include-chain` | Include full proof chain | `false` |
| `--include-trust-anchors` | Include trust anchor keys | `false` |
| `--output <PATH>` | Output file path | Required |
#### Examples
```bash
# Export standard bundle
stella proof export --scan-id $SCAN_ID --output proof-bundle.zip
# Export portable bundle (for offline verification)
stella proof export --scan-id $SCAN_ID --portable --include-trust-anchors --output portable.zip
# Export with full chain
stella proof export --scan-id $SCAN_ID --include-chain --output full-bundle.zip
```
---
### stella proof inspect
Inspect proof bundle contents.
```bash
stella proof inspect [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--bundle <PATH>` | Proof bundle file | Required |
| `--output-dir <PATH>` | Extract to directory | — |
| `--show-manifest` | Display manifest | `false` |
| `--show-proof` | Display proof nodes | `false` |
| `--show-meta` | Display metadata | `false` |
#### Examples
```bash
# List bundle contents
stella proof inspect --bundle proof.zip
# Extract and inspect
stella proof inspect --bundle proof.zip --output-dir ./inspection/
# Show manifest
stella proof inspect --bundle proof.zip --show-manifest
```
---
## Common Options
### Authentication
| Option | Description |
|--------|-------------|
| `--token <TOKEN>` | OAuth bearer token |
| `--token-file <PATH>` | File containing token |
| `--profile <NAME>` | Use named profile |
### Output
| Option | Description |
|--------|-------------|
| `--quiet` | Suppress non-error output |
| `--verbose` | Enable verbose output |
| `--debug` | Enable debug logging |
| `--no-color` | Disable colored output |
### Connection
| Option | Description |
|--------|-------------|
| `--endpoint <URL>` | Scanner API endpoint |
| `--timeout <DURATION>` | Request timeout (e.g., 30s, 5m) |
| `--insecure` | Skip TLS verification (dev only) |
---
## Environment Variables
| Variable | Description | Equivalent Option |
|----------|-------------|-------------------|
| `STELLA_TOKEN` | OAuth token | `--token` |
| `STELLA_ENDPOINT` | API endpoint | `--endpoint` |
| `STELLA_PROFILE` | Profile name | `--profile` |
| `STELLA_OFFLINE` | Offline mode | `--offline` |
| `STELLA_TRUST_ANCHOR` | Trust anchor path | `--trust-anchor` |
---
## Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | Authentication failed |
| 4 | Resource not found |
| 5 | Verification failed |
| 6 | Network error |
| 10 | Timeout |
---
## Related Documentation
- [Reachability CLI Reference](./reachability-cli-reference.md)
- [Unknowns CLI Reference](./unknowns-cli-reference.md)
- [Score Proofs API Reference](../api/score-proofs-reachability-api-reference.md)
- [Score Proofs Runbook](../operations/score-proofs-runbook.md)
---
**Last Updated**: 2025-12-20
**Version**: 1.0.0
**Sprint**: 3500.0004.0004

View File

@@ -0,0 +1,532 @@
# Unknowns CLI Reference
**Sprint:** SPRINT_3500_0004_0004
**Version:** 1.0.0
## Overview
The Unknowns CLI commands manage components that cannot be analyzed due to missing data, unrecognized formats, or resolution failures. These commands support triage workflows, escalation, and resolution tracking.
---
## Commands
### stella unknowns
Manage unknowns registry.
```bash
stella unknowns <SUBCOMMAND> [OPTIONS]
```
#### Subcommands
| Subcommand | Description |
|------------|-------------|
| `list` | List unknowns |
| `show` | Show unknown details |
| `summary` | Show unknowns summary |
| `escalate` | Escalate unknown |
| `resolve` | Mark unknown resolved |
| `suppress` | Suppress unknown |
| `bulk-triage` | Bulk triage unknowns |
| `export` | Export unknowns |
| `import` | Import unknown resolutions |
---
### stella unknowns list
List unknowns for a scan or workspace.
```bash
stella unknowns list [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Filter by scan ID | — |
| `--workspace-id <ID>` | Filter by workspace ID | — |
| `--status <STATUS>` | Filter by status | All |
| `--category <CAT>` | Filter by category | All |
| `--priority <PRI>` | Filter by priority (1-10) | All |
| `--min-score <N>` | Minimum 2-factor score | 0 |
| `--max-age <DURATION>` | Maximum age | — |
| `--purl <PATTERN>` | Filter by PURL pattern | — |
| `--output <PATH>` | Output file path | stdout |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table`, `csv` | `table` |
| `--limit <N>` | Maximum results | 100 |
| `--offset <N>` | Pagination offset | 0 |
| `--sort <FIELD>` | Sort field | `priority` |
| `--order <DIR>` | Sort direction: `asc`, `desc` | `desc` |
#### Status Values
| Status | Description |
|--------|-------------|
| `pending` | Awaiting triage |
| `escalated` | Escalated for manual review |
| `suppressed` | Suppressed (accepted risk) |
| `resolved` | Resolved |
#### Category Values
| Category | Description |
|----------|-------------|
| `unmapped_purl` | No CPE/OVAL mapping |
| `checksum_miss` | Binary checksum not in DB |
| `language_gap` | Unsupported language |
| `parsing_failure` | Manifest parsing failed |
| `network_timeout` | Feed unavailable |
| `unrecognized_format` | Unknown format |
#### Examples
```bash
# List all pending unknowns
stella unknowns list --status pending
# List high-priority unknowns
stella unknowns list --min-score 7
# List by category
stella unknowns list --category unmapped_purl
# Export to CSV
stella unknowns list --scan-id $SCAN_ID --output-format csv --output unknowns.csv
# Filter by PURL pattern
stella unknowns list --purl "pkg:npm/*"
```
---
### stella unknowns show
Show details of a specific unknown.
```bash
stella unknowns show [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--id <ID>` | Unknown ID | Required |
| `--verbose` | Show extended details | `false` |
| `--output-format <FMT>` | Format: `json`, `yaml`, `text` | `text` |
#### Examples
```bash
# Show unknown details
stella unknowns show --id unknown-001
# Output:
# ID: unknown-001
# PURL: pkg:npm/left-pad@1.3.0
# Category: unmapped_purl
# Status: pending
# Priority: 6
# Score: 7.2 (vuln: 3, impact: 4.2)
# Created: 2025-12-20T10:00:00Z
# Scans Affected: 5
# Reason: No CVE/advisory mapping exists for this package
# Verbose output
stella unknowns show --id unknown-001 --verbose
# JSON output
stella unknowns show --id unknown-001 --output-format json
```
---
### stella unknowns summary
Show unknowns summary statistics.
```bash
stella unknowns summary [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Filter by scan ID | — |
| `--workspace-id <ID>` | Filter by workspace ID | — |
| `--output-format <FMT>` | Format: `json`, `yaml`, `table` | `table` |
#### Examples
```bash
# Summary for workspace
stella unknowns summary --workspace-id $WS_ID
# Output:
# Total unknowns: 127
#
# By Status:
# pending: 89
# escalated: 15
# suppressed: 12
# resolved: 11
#
# By Category:
# unmapped_purl: 67
# checksum_miss: 34
# language_gap: 18
# parsing_failure: 8
#
# Priority Distribution:
# High (8-10): 12
# Medium (5-7): 45
# Low (1-4): 70
```
---
### stella unknowns escalate
Escalate an unknown for manual review.
```bash
stella unknowns escalate [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--id <ID>` | Unknown ID | Required |
| `--reason <TEXT>` | Escalation reason | — |
| `--assignee <USER>` | Assign to user/team | — |
| `--severity <LEVEL>` | Severity: `low`, `medium`, `high`, `critical` | `medium` |
| `--due-date <DATE>` | Due date (ISO 8601) | — |
#### Examples
```bash
# Basic escalation
stella unknowns escalate --id unknown-001 --reason "Potential supply chain risk"
# Escalate with assignment
stella unknowns escalate --id unknown-001 \
--reason "Missing mapping for critical dependency" \
--assignee security-team \
--severity high \
--due-date 2025-12-27
```
---
### stella unknowns resolve
Mark an unknown as resolved.
```bash
stella unknowns resolve [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--id <ID>` | Unknown ID | Required |
| `--resolution <TYPE>` | Resolution type | Required |
| `--comment <TEXT>` | Resolution comment | — |
| `--mapping <JSON>` | Custom mapping data | — |
| `--evidence <PATH>` | Evidence file | — |
#### Resolution Types
| Type | Description |
|------|-------------|
| `mapped` | Package/CVE mapping added |
| `not_applicable` | Not applicable to context |
| `false_positive` | Detection was incorrect |
| `accepted_risk` | Risk accepted |
| `replaced` | Component replaced |
| `removed` | Component removed |
#### Examples
```bash
# Resolve with mapping
stella unknowns resolve --id unknown-001 \
--resolution mapped \
--comment "Added CPE mapping to internal DB"
# Resolve as accepted risk
stella unknowns resolve --id unknown-001 \
--resolution accepted_risk \
--comment "Internal component, no external exposure"
# Resolve with evidence
stella unknowns resolve --id unknown-001 \
--resolution not_applicable \
--evidence ./analysis-report.pdf
```
---
### stella unknowns suppress
Suppress an unknown (accept risk).
```bash
stella unknowns suppress [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--id <ID>` | Unknown ID | Required |
| `--reason <TEXT>` | Suppression reason | Required |
| `--expires <DATE>` | Expiration date | — |
| `--scope <SCOPE>` | Scope: `scan`, `workspace`, `global` | `scan` |
| `--approver <USER>` | Approver name/email | — |
#### Examples
```bash
# Suppress with expiration
stella unknowns suppress --id unknown-001 \
--reason "Internal tooling, no risk exposure" \
--expires 2026-01-01
# Workspace-wide suppression
stella unknowns suppress --id unknown-001 \
--reason "Deprecated component, scheduled for removal" \
--scope workspace \
--approver security@example.com
```
---
### stella unknowns bulk-triage
Bulk triage multiple unknowns.
```bash
stella unknowns bulk-triage [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--file <PATH>` | Triage decisions file (JSON/YAML) | Required |
| `--dry-run` | Preview changes | `false` |
| `--continue-on-error` | Continue on individual failures | `false` |
#### Input File Format
```json
{
"decisions": [
{
"id": "unknown-001",
"action": "resolve",
"resolution": "mapped",
"comment": "Added mapping"
},
{
"id": "unknown-002",
"action": "suppress",
"reason": "Accepted risk",
"expires": "2026-01-01"
},
{
"id": "unknown-003",
"action": "escalate",
"reason": "Needs security review",
"assignee": "security-team"
}
]
}
```
#### Examples
```bash
# Bulk triage with preview
stella unknowns bulk-triage --file triage-decisions.json --dry-run
# Apply bulk triage
stella unknowns bulk-triage --file triage-decisions.json
```
---
### stella unknowns export
Export unknowns data.
```bash
stella unknowns export [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--scan-id <ID>` | Filter by scan ID | — |
| `--workspace-id <ID>` | Filter by workspace ID | — |
| `--status <STATUS>` | Filter by status | All |
| `--output <PATH>` | Output file path | Required |
| `--format <FMT>` | Format: `json`, `yaml`, `csv`, `ndjson` | `json` |
| `--include-history` | Include resolution history | `false` |
#### Examples
```bash
# Export all unknowns
stella unknowns export --workspace-id $WS_ID --output unknowns.json
# Export pending as CSV
stella unknowns export --status pending --output pending.csv --format csv
# Export with history
stella unknowns export --scan-id $SCAN_ID \
--output unknowns-history.json \
--include-history
```
---
### stella unknowns import
Import unknown resolutions.
```bash
stella unknowns import [OPTIONS]
```
#### Options
| Option | Description | Default |
|--------|-------------|---------|
| `--file <PATH>` | Resolutions file | Required |
| `--format <FMT>` | Format: `json`, `yaml`, `csv` | Auto-detect |
| `--dry-run` | Preview import | `false` |
| `--conflict <MODE>` | Conflict handling: `skip`, `update`, `error` | `skip` |
#### Examples
```bash
# Import resolutions
stella unknowns import --file resolutions.json
# Preview import
stella unknowns import --file resolutions.json --dry-run
# Update existing
stella unknowns import --file resolutions.json --conflict update
```
---
## Common Options
### Authentication
| Option | Description |
|--------|-------------|
| `--token <TOKEN>` | OAuth bearer token |
| `--token-file <PATH>` | File containing token |
| `--profile <NAME>` | Use named profile |
### Output
| Option | Description |
|--------|-------------|
| `--quiet` | Suppress non-error output |
| `--verbose` | Enable verbose output |
| `--debug` | Enable debug logging |
| `--no-color` | Disable colored output |
### Connection
| Option | Description |
|--------|-------------|
| `--endpoint <URL>` | Scanner API endpoint |
| `--timeout <DURATION>` | Request timeout |
| `--insecure` | Skip TLS verification |
---
## Environment Variables
| Variable | Description |
|----------|-------------|
| `STELLA_TOKEN` | OAuth token |
| `STELLA_ENDPOINT` | API endpoint |
| `STELLA_PROFILE` | Profile name |
| `STELLA_WORKSPACE` | Default workspace ID |
---
## Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | General error |
| 2 | Invalid arguments |
| 3 | Authentication failed |
| 4 | Resource not found |
| 5 | Operation failed |
| 6 | Network error |
---
## Workflows
### Daily Triage Workflow
```bash
# 1. Check summary
stella unknowns summary --workspace-id $WS_ID
# 2. List high-priority pending
stella unknowns list --status pending --min-score 7
# 3. Review and escalate critical items
stella unknowns escalate --id unknown-001 \
--reason "Security review needed" \
--severity high
# 4. Bulk resolve known patterns
stella unknowns bulk-triage --file daily-resolutions.json
```
### Weekly Report Export
```bash
# Export all unknowns with history
stella unknowns export \
--workspace-id $WS_ID \
--include-history \
--output weekly-unknowns-$(date +%Y%m%d).json
```
---
## Related Documentation
- [Score Proofs CLI Reference](./score-proofs-cli-reference.md)
- [Reachability CLI Reference](./reachability-cli-reference.md)
- [Unknowns API Reference](../api/score-proofs-reachability-api-reference.md)
- [Unknowns Queue Runbook](../operations/unknowns-queue-runbook.md)
---
**Last Updated**: 2025-12-20
**Version**: 1.0.0
**Sprint**: 3500.0004.0004

View File

@@ -42,18 +42,18 @@ Complete API reference documentation for all new endpoints.
**Assignee**: Docs Team
**Story Points**: 5
**Status**: DOING
**Status**: DONE
**Description**:
Create operational runbooks for Score Proofs and Reachability features.
**Acceptance Criteria**:
- [ ] Score replay runbook
- [ ] Proof verification runbook
- [x] Score replay runbook (`docs/operations/score-replay-runbook.md`)
- [x] Proof verification runbook (`docs/operations/proof-verification-runbook.md`)
- [x] Reachability troubleshooting runbook (`docs/operations/reachability-runbook.md`)
- [x] Unknowns queue management runbook (`docs/operations/unknowns-queue-runbook.md`)
- [ ] Air-gap operations runbook
- [x] Escalation procedures (included in both runbooks)
- [x] Air-gap operations runbook (`docs/operations/airgap-operations-runbook.md`)
- [x] Escalation procedures (included in all runbooks)
---
@@ -174,12 +174,12 @@ Complete handoff to operations and support teams.
|---|---------|--------|------------|--------|-----------------|
| 1 | T1 | DONE | — | Agent | API Reference Documentation |
| 2 | T2 | DONE | — | Agent | Operations Runbooks |
| 3 | T3 | DOING | — | Agent | Architecture Documentation |
| 4 | T4 | TODO | — | Docs Team | CLI Reference Guide |
| 5 | T5 | TODO | T1-T4 | Docs Team | Training Materials |
| 6 | T6 | TODO | T1-T5 | Docs Team | Release Notes |
| 7 | T7 | TODO | T1 | Docs Team | OpenAPI Specification Update |
| 8 | T8 | TODO | T1-T7 | Project Mgmt | Handoff Checklist |
| 3 | T3 | DONE | — | Agent | Architecture Documentation |
| 4 | T4 | DONE | — | Agent | CLI Reference Guide |
| 5 | T5 | DOING | T1-T4 | Agent | Training Materials |
| 6 | T6 | TODO | T1-T5 | Agent | Release Notes |
| 7 | T7 | TODO | T1 | Agent | OpenAPI Specification Update |
| 8 | T8 | TODO | T1-T7 | Agent | Handoff Checklist |
---
@@ -188,6 +188,11 @@ Complete handoff to operations and support teams.
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2025-12-20 | Sprint file created. | Agent |
| 2025-12-20 | T1 DONE: Created docs/api/score-proofs-reachability-api-reference.md | Agent |
| 2025-12-20 | T2 DONE: Created 4 runbooks (score-proofs, reachability, unknowns, airgap) | Agent |
| 2025-12-20 | T3 DONE: Updated HIGH_LEVEL_ARCHITECTURE.md with sections 4A/4B/4C | Agent |
| 2025-12-20 | T4 DONE: Created 3 CLI references (score-proofs, reachability, unknowns) | Agent |
| 2025-12-20 | T5 DOING: Starting training materials | Agent |
---
@@ -201,4 +206,4 @@ Complete handoff to operations and support teams.
---
**Sprint Status**: TODO (0/8 tasks done)
**Sprint Status**: IN PROGRESS (4/8 tasks done)

View File

@@ -0,0 +1,688 @@
# Air-Gap Operations Runbook
> **Version**: 1.0.0
> **Sprint**: 3500.0004.0004
> **Last Updated**: 2025-12-20
This runbook covers operational procedures for running StellaOps in air-gapped (offline) environments, including offline kit management, feed updates, and isolated verification workflows.
---
## Table of Contents
1. [Overview](#1-overview)
2. [Offline Kit Management](#2-offline-kit-management)
3. [Feed Updates](#3-feed-updates)
4. [Scanning in Air-Gap Mode](#4-scanning-in-air-gap-mode)
5. [Verification in Air-Gap Mode](#5-verification-in-air-gap-mode)
6. [Troubleshooting](#6-troubleshooting)
7. [Monitoring & Health Checks](#7-monitoring--health-checks)
8. [Escalation Procedures](#8-escalation-procedures)
---
## 1. Overview
### What is Air-Gap Mode?
Air-gap mode allows StellaOps to operate in environments with no external network connectivity. This is required for:
- Classified or sensitive environments
- High-security facilities
- Regulatory compliance (certain industries)
- Disaster recovery scenarios
### Air-Gap Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ Connected Environment │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Feed Sync │───►│ Bundle │───►│ Offline Kit │ │
│ │ Service │ │ Generator │ │ (.tar.gz) │ │
│ └─────────────┘ └─────────────┘ └──────┬──────┘ │
└─────────────────────────────────────────────────┼───────────┘
│ Physical
│ Transfer
┌─────────────────────────────────────────────────┼───────────┐
│ Air-Gapped Environment │ │
│ ┌──────────────┐ ┌─────────────┐ ┌──────▼──────┐ │
│ │ StellaOps │◄───│ Offline │◄───│ Import │ │
│ │ Scanner │ │ Data Store │ │ Service │ │
│ └──────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### Offline Kit Contents
| Component | Description | Update Frequency |
|-----------|-------------|------------------|
| Vulnerability Database | NVD, OSV, vendor advisories | Daily/Weekly |
| Advisory Feeds | CVE details, EPSS scores | Daily |
| Trust Bundles | CA certificates, signing keys | Quarterly |
| Rules Engine | Scoring rules and policies | Monthly |
| Offline Binaries | CLI tools, extractors | Per release |
---
## 2. Offline Kit Management
### 2.1 Generating an Offline Kit
On the connected system:
```bash
# Generate full offline kit
stella offline-kit create \
--output /path/to/offline-kit.tar.gz \
--include-all
# Generate minimal kit (feeds only)
stella offline-kit create \
--output /path/to/offline-kit-feeds.tar.gz \
--feeds-only
# Generate with specific components
stella offline-kit create \
--output /path/to/offline-kit.tar.gz \
--include vuln-db \
--include advisories \
--include trust-bundles \
--include rules
```
### 2.2 Kit Manifest
Each kit includes a manifest for verification:
```json
{
"version": "1.0.0",
"createdAt": "2025-01-15T00:00:00Z",
"expiresAt": "2025-02-15T00:00:00Z",
"components": {
"vulnerability-database": {
"hash": "sha256:abc123...",
"size": 1073741824,
"records": 245000
},
"advisory-feeds": {
"hash": "sha256:def456...",
"size": 536870912,
"lastUpdate": "2025-01-15T00:00:00Z"
},
"trust-bundles": {
"hash": "sha256:ghi789...",
"size": 65536,
"certificates": 12
},
"signing-keys": {
"hash": "sha256:jkl012...",
"keyIds": ["key-001", "key-002"]
}
},
"signature": "base64-signature..."
}
```
### 2.3 Transferring to Air-Gapped Environment
#### Physical Media Transfer
```bash
# On connected system - write to media
cp offline-kit.tar.gz /media/secure-usb/
sha256sum offline-kit.tar.gz > /media/secure-usb/offline-kit.tar.gz.sha256
# On air-gapped system - verify and import
cd /media/secure-usb/
sha256sum -c offline-kit.tar.gz.sha256
stella offline-kit import --kit offline-kit.tar.gz
```
#### Secure File Transfer (if available)
```bash
# Using data diode or one-way transfer
scp offline-kit.tar.gz airgap-gateway:/incoming/
```
### 2.4 Installing Offline Kit
```bash
# Import and install kit
stella offline-kit import \
--kit /path/to/offline-kit.tar.gz \
--verify \
--install
# Verify installation
stella offline-kit status
# List installed components
stella offline-kit list
```
Expected output:
```
Offline Kit Status
══════════════════════════════════════════
Mode: AIR-GAP
Kit Version: 1.0.0
Installed At: 2025-01-15T10:30:00Z
Expires At: 2025-02-15T00:00:00Z
Components:
✓ vulnerability-database 2025-01-15 245,000 records
✓ advisory-feeds 2025-01-15 Active
✓ trust-bundles 2025-01-15 12 certificates
✓ signing-keys 2025-01-15 2 keys
✓ rules-engine 2025-01-15 v2.3.0
Health: HEALTHY
Days Until Expiry: 31
```
---
## 3. Feed Updates
### 3.1 Update Workflow
```
┌────────────────────────────────────────────────────────────┐
│ Weekly Feed Update Process │
├────────────────────────────────────────────────────────────┤
│ Day 1: Generate kit on connected system │
│ Day 2: Security review and approval │
│ Day 3: Transfer to air-gapped environment │
│ Day 4: Import and verify │
│ Day 5: Activate new feeds │
└────────────────────────────────────────────────────────────┘
```
### 3.2 Generating Delta Updates
For faster updates, generate delta kits:
```bash
# On connected system
stella offline-kit create \
--output delta-kit.tar.gz \
--delta-from 2025-01-08 \
--delta-to 2025-01-15
# Delta kit is smaller, contains only changes
```
### 3.3 Applying Updates
```bash
# Import delta update
stella offline-kit import \
--kit delta-kit.tar.gz \
--delta \
--verify
# Verify feed freshness
stella feeds status
```
### 3.4 Rollback Procedure
If an update causes issues:
```bash
# List available snapshots
stella offline-kit snapshots
# Rollback to previous version
stella offline-kit rollback --to 2025-01-08
# Verify rollback
stella feeds status
```
---
## 4. Scanning in Air-Gap Mode
### 4.1 Enabling Air-Gap Mode
```bash
# Enable air-gap mode
stella config set mode air-gap
# Verify mode
stella config get mode
# Output: air-gap
```
### 4.2 Running Scans
```bash
# Scan a local image (no registry pull)
stella scan image --local /path/to/image.tar
# Scan from local registry
stella scan image localhost:5000/myapp:v1.0
# Scan with offline feeds explicitly
stella scan image myapp:v1.0 --offline-feeds
```
### 4.3 Local Image Preparation
For images that need to be scanned:
```bash
# On connected system - save image
docker save myapp:v1.0 -o myapp-v1.0.tar
sha256sum myapp-v1.0.tar > myapp-v1.0.tar.sha256
# Transfer to air-gapped system
# ... physical transfer ...
# On air-gapped system - verify and load
sha256sum -c myapp-v1.0.tar.sha256
docker load -i myapp-v1.0.tar
stella scan image myapp:v1.0 --local
```
### 4.4 SBOM Generation
```bash
# Generate SBOM for local image
stella sbom generate --image myapp:v1.0 --output sbom.json
# Scan existing SBOM
stella scan sbom --file sbom.json
```
---
## 5. Verification in Air-Gap Mode
### 5.1 Offline Proof Verification
```bash
# Verify proof bundle offline
stella proof verify --bundle bundle.tar.gz --offline
# Verify with explicit trust store
stella proof verify --bundle bundle.tar.gz \
--offline \
--trust-store /etc/stellaops/offline/trust-roots.json
```
### 5.2 Preparing Trust Store
Before air-gapped deployment:
```bash
# On connected system - export trust configuration
stella trust export \
--output trust-roots.json \
--include-ca \
--include-signing-keys
# Transfer to air-gapped system
# ... physical transfer ...
# On air-gapped system - import trust
stella trust import --file trust-roots.json
```
### 5.3 Score Replay Offline
```bash
# Replay score using offline data
stella score replay --scan $SCAN_ID --offline
# Replay with frozen time
stella score replay --scan $SCAN_ID \
--offline \
--freeze 2025-01-15T00:00:00Z
```
---
## 6. Troubleshooting
### 6.1 Kit Import Fails
**Symptoms**: `Failed to import offline kit`
**Diagnostic Steps**:
1. Verify kit integrity:
```bash
sha256sum offline-kit.tar.gz
# Compare with manifest
```
2. Check kit signature:
```bash
stella offline-kit verify --kit offline-kit.tar.gz
```
3. Check disk space:
```bash
df -h /var/lib/stellaops/
```
**Common Causes**:
| Cause | Resolution |
|-------|------------|
| Corrupted transfer | Re-transfer, verify checksum |
| Invalid signature | Regenerate kit with valid signing key |
| Insufficient space | Free disk space or expand volume |
| Expired kit | Generate fresh kit |
### 6.2 Stale Feed Data
**Symptoms**: Scans report old vulnerabilities, miss new CVEs
**Diagnostic Steps**:
1. Check feed age:
```bash
stella feeds status
```
2. Verify last update:
```bash
stella offline-kit status | grep "Installed At"
```
**Resolution**:
- Generate and import fresh offline kit
- Establish regular update schedule
- Set up expiry alerts
### 6.3 Trust Verification Fails
**Symptoms**: `Certificate chain verification failed` in offline mode
**Diagnostic Steps**:
1. Check trust store:
```bash
stella trust list
```
2. Verify CA bundle:
```bash
openssl verify -CAfile /etc/stellaops/offline/ca-bundle.pem \
/path/to/certificate.pem
```
3. Check for expired roots:
```bash
stella trust check-expiry
```
**Resolution**:
- Update trust bundle in offline kit
- Import new CA certificates
- Rotate expired signing keys
### 6.4 Network Access Attempted
**Symptoms**: Air-gapped system attempts network connection
**Diagnostic Steps**:
1. Check mode configuration:
```bash
stella config get mode
```
2. Audit network attempts:
```bash
journalctl -u stellaops | grep -i "network\|connect\|http"
```
3. Verify no external URLs in config:
```bash
grep -r "http" /etc/stellaops/
```
**Resolution**:
- Ensure `mode: air-gap` in configuration
- Remove any hardcoded URLs
- Block outbound traffic at firewall level
---
## 7. Monitoring & Health Checks
### 7.1 Air-Gap Health Checks
```bash
# Run comprehensive health check
stella health check --air-gap
# Output
Air-Gap Health Check
══════════════════════════════════════════
✓ Mode: air-gap
✓ Feed Freshness: 7 days old (OK)
✓ Trust Store: Valid
✓ Signing Keys: 2 active
✓ Disk Space: 45% used
✓ Database: Healthy
⚠ Kit Expiry: 24 days remaining
Overall: HEALTHY (1 warning)
```
### 7.2 Automated Monitoring Script
```bash
#!/bin/bash
# /etc/stellaops/scripts/airgap-health.sh
set -e
# Check feed age
FEED_AGE=$(stella feeds age --days)
if [ "$FEED_AGE" -gt 14 ]; then
echo "CRITICAL: Feeds are $FEED_AGE days old"
exit 2
fi
# Check kit expiry
DAYS_LEFT=$(stella offline-kit days-until-expiry)
if [ "$DAYS_LEFT" -lt 7 ]; then
echo "WARNING: Kit expires in $DAYS_LEFT days"
exit 1
fi
# Check trust store
if ! stella trust verify --quiet; then
echo "CRITICAL: Trust store verification failed"
exit 2
fi
echo "OK: Air-gap health check passed"
exit 0
```
### 7.3 Metrics for Air-Gap
| Metric | Description | Alert Threshold |
|--------|-------------|-----------------|
| `offline_kit_age_days` | Days since kit import | > 14 days |
| `offline_kit_expiry_days` | Days until kit expires | < 7 days |
| `feed_freshness_days` | Age of vulnerability feeds | > 7 days |
| `trust_store_valid` | Trust store validity (0/1) | = 0 |
| `disk_usage_percent` | Data store disk usage | > 80% |
### 7.4 Alert Configuration
```yaml
# /etc/stellaops/alerts/airgap.yaml
alerts:
- name: offline_kit_expiring
condition: offline_kit_expiry_days < 7
severity: warning
message: "Offline kit expires in {{ .Value }} days"
- name: offline_kit_expired
condition: offline_kit_expiry_days <= 0
severity: critical
message: "Offline kit has expired"
- name: feeds_stale
condition: feed_freshness_days > 14
severity: warning
message: "Vulnerability feeds are {{ .Value }} days old"
```
---
## 8. Escalation Procedures
### 8.1 Escalation Matrix
| Severity | Condition | Response Time | Action |
|----------|-----------|---------------|--------|
| P1 - Critical | Offline kit expired | 4 hours | Emergency kit transfer |
| P1 - Critical | Trust store invalid | 4 hours | Restore from backup |
| P2 - High | Feeds > 14 days old | 24 hours | Schedule kit update |
| P3 - Medium | Kit expiring in < 7 days | 48 hours | Plan kit update |
| P4 - Low | Minor health check warnings | Next maintenance | Review and address |
### 8.2 Emergency Kit Update Process
When kit expires before scheduled update:
1. **On Connected System** (0-2 hours):
```bash
stella offline-kit create --output emergency-kit.tar.gz --include-all
```
2. **Security Review** (2-4 hours):
- Verify kit signature
- Check for known vulnerabilities in kit
- Get approval for transfer
3. **Transfer** (4-6 hours):
- Physical media preparation
- Chain of custody documentation
- Transfer to air-gapped environment
4. **Import** (6-8 hours):
```bash
stella offline-kit import --kit emergency-kit.tar.gz --verify --install
```
### 8.3 Contacts
| Role | Contact | Availability |
|------|---------|--------------|
| Air-Gap Operations | airgap-ops@stellaops.io | Business hours |
| Security Team | security@stellaops.io | Business hours |
| Platform On-Call | platform-oncall@stellaops.io | 24/7 |
---
## Appendix A: Configuration Reference
### Air-Gap Mode Configuration
```yaml
# /etc/stellaops/config.yaml
mode: air-gap
offline:
dataDir: /var/lib/stellaops/offline
feedsDir: /var/lib/stellaops/offline/feeds
trustStore: /etc/stellaops/offline/trust-roots.json
caBundle: /etc/stellaops/offline/ca-bundle.pem
# Disable all external network calls
disableNetworking: true
# Kit expiry settings
kit:
expiryWarningDays: 7
maxAgeDays: 30
# Feed freshness settings
feeds:
maxAgeDays: 14
warnAgeDays: 7
```
### Environment Variables
```bash
# Air-gap specific
export STELLAOPS_MODE=air-gap
export STELLAOPS_OFFLINE_DATA_DIR=/var/lib/stellaops/offline
export STELLAOPS_DISABLE_NETWORKING=true
# Trust configuration
export STELLAOPS_TRUST_STORE=/etc/stellaops/offline/trust-roots.json
export STELLAOPS_CA_BUNDLE=/etc/stellaops/offline/ca-bundle.pem
```
---
## Appendix B: CLI Quick Reference
```bash
# Offline Kit Commands
stella offline-kit create --output <path> # Generate kit
stella offline-kit import --kit <path> # Import kit
stella offline-kit status # Show status
stella offline-kit verify --kit <path> # Verify kit
stella offline-kit rollback --to <date> # Rollback feeds
# Feed Commands (Air-Gap)
stella feeds status # Show feed status
stella feeds age --days # Get feed age
# Trust Commands
stella trust list # List trust roots
stella trust import --file <path> # Import trust config
stella trust verify # Verify trust store
stella trust export --output <path> # Export trust config
# Scanning (Air-Gap)
stella scan image --local <path> # Scan local image
stella scan sbom --file <path> # Scan SBOM file
# Verification (Air-Gap)
stella proof verify --bundle <path> --offline # Offline verification
stella score replay --scan <id> --offline # Offline replay
# Health
stella health check --air-gap # Air-gap health check
stella config get mode # Check current mode
```
---
## Appendix C: Update Schedule Template
| Week | Activity | Owner | Notes |
|------|----------|-------|-------|
| 1 | Generate kit | Connected Ops | Monday |
| 1 | Security review | Security Team | Tuesday |
| 1 | Approval | Security Lead | Wednesday |
| 2 | Transfer | Air-Gap Ops | Monday |
| 2 | Import & verify | Air-Gap Ops | Tuesday |
| 2 | Activate | Air-Gap Ops | Wednesday |
| 2 | Validate scans | QA Team | Thursday |
---
## Revision History
| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 1.0.0 | 2025-12-20 | Agent | Initial release |

View File

@@ -0,0 +1,630 @@
# Proof Verification Operations Runbook
> **Version**: 1.0.0
> **Sprint**: 3500.0004.0004
> **Last Updated**: 2025-12-20
This runbook covers operational procedures for Proof Verification, including DSSE signature validation, Merkle tree verification, transparency log checks, and offline verification workflows.
---
## Table of Contents
1. [Overview](#1-overview)
2. [Verification Operations](#2-verification-operations)
3. [Offline Verification](#3-offline-verification)
4. [Transparency Log Integration](#4-transparency-log-integration)
5. [Troubleshooting](#5-troubleshooting)
6. [Monitoring & Alerting](#6-monitoring--alerting)
7. [Escalation Procedures](#7-escalation-procedures)
---
## 1. Overview
### What is Proof Verification?
Proof Verification is the process of cryptographically validating that a scan result has not been tampered with and was produced by an authorized StellaOps instance. It involves:
- **DSSE Signature Verification**: Validate the signing envelope
- **Merkle Tree Verification**: Confirm the root hash matches the proof
- **Certificate Chain Validation**: Verify the signing certificate
- **Transparency Log Check**: Optional Rekor/Sigstore verification
### Verification Components
| Component | Purpose | Verification Type |
|-----------|---------|-------------------|
| DSSE Envelope | Contains signed payload | Signature validation |
| Merkle Proof | Cryptographic proof of inclusion | Hash verification |
| Certificate | Signing identity | Chain validation |
| Rekor Entry | Transparency log record | Log inclusion proof |
### Trust Model
```
┌─────────────────────────────────────────────────────────────┐
│ Trust Hierarchy │
├─────────────────────────────────────────────────────────────┤
│ Root CA (Offline) │
│ └── Intermediate CA │
│ └── Signing Certificate (Scanner Instance) │
│ └── DSSE Envelope │
│ └── Proof Bundle │
│ └── Manifest + Score │
└─────────────────────────────────────────────────────────────┘
```
---
## 2. Verification Operations
### 2.1 Basic Proof Verification
#### Via CLI
```bash
# Verify a proof bundle file
stella proof verify --bundle bundle.tar.gz
# Verify with verbose output
stella proof verify --bundle bundle.tar.gz --verbose
# Verify and output as JSON
stella proof verify --bundle bundle.tar.gz --output json
```
#### Expected Output (Success)
```
Proof Verification Result
══════════════════════════════════════════
✓ DSSE Signature VALID
✓ Merkle Root VALID
✓ Certificate Chain VALID
✓ Not Expired VALID
──────────────────────────────────────────
Overall: VERIFIED
Root Hash: sha256:abc123...
Signed By: scanner-prod-01.stellaops.local
Signed At: 2025-01-15T10:30:00Z
Valid Until: 2026-01-15T10:30:00Z
```
#### Expected Output (Failure)
```
Proof Verification Result
══════════════════════════════════════════
✓ DSSE Signature VALID
✗ Merkle Root INVALID
✓ Certificate Chain VALID
✓ Not Expired VALID
──────────────────────────────────────────
Overall: FAILED
Error: Merkle root mismatch
Expected: sha256:abc123...
Actual: sha256:def456...
```
### 2.2 Verification via API
```bash
# Verify by scan ID
curl -X POST "https://scanner.stellaops.local/api/v1/scanner/scans/$SCAN_ID/proofs/$ROOT_HASH/verify" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json"
# Response
{
"valid": true,
"rootHash": "sha256:abc123...",
"checks": [
{"name": "dsse_signature", "passed": true, "message": "Signature valid"},
{"name": "merkle_root", "passed": true, "message": "Root hash matches"},
{"name": "certificate_chain", "passed": true, "message": "Chain valid"},
{"name": "not_expired", "passed": true, "message": "Certificate not expired"}
],
"verifiedAt": "2025-01-16T10:30:00Z"
}
```
### 2.3 Viewing Merkle Spine
The Merkle spine shows the path from leaf nodes to the root:
```bash
stella proof spine --bundle bundle.tar.gz
```
Output:
```
Merkle Tree Spine
══════════════════════════════════════════
Root: sha256:abc123...
├── sha256:node1... (sbom_hash)
├── sha256:node2... (rules_hash)
├── sha256:node3... (policy_hash)
└── sha256:node4... (feed_hash)
Depth: 3
Leaves: 4
Algorithm: SHA-256
```
### 2.4 Certificate Inspection
```bash
# Extract and inspect certificate
tar -xzf bundle.tar.gz
openssl x509 -in bundle/certificate.pem -noout -text
# Check validity period
openssl x509 -in bundle/certificate.pem -noout -dates
# Verify against CA bundle
openssl verify -CAfile /etc/stellaops/ca-bundle.pem bundle/certificate.pem
```
---
## 3. Offline Verification
### 3.1 When to Use Offline Verification
- Air-gapped environments
- Network-restricted systems
- Compliance audits without API access
- Disaster recovery scenarios
### 3.2 Prerequisites for Offline Verification
Required files:
- Proof bundle (`.tar.gz`)
- CA certificate bundle (`ca-bundle.pem`)
- Trust root configuration (`trust-roots.json`)
```bash
# Prepare offline verification kit
stella proof offline-kit create \
--output /path/to/offline-kit/ \
--include-ca \
--include-trust-roots
```
Kit contents:
```
offline-kit/
├── ca-bundle.pem # Certificate authority chain
├── trust-roots.json # Trusted signing keys
├── verify.sh # Standalone verification script
└── README.md # Instructions
```
### 3.3 Running Offline Verification
```bash
# Using CLI with offline flag
stella proof verify --bundle bundle.tar.gz --offline
# Using standalone script
./verify.sh bundle.tar.gz
# Manual verification with OpenSSL
./verify.sh bundle.tar.gz --ca-bundle ./ca-bundle.pem
```
### 3.4 Offline Verification Checks
| Check | Online | Offline | Notes |
|-------|--------|---------|-------|
| DSSE Signature | ✓ | ✓ | Local crypto |
| Merkle Root | ✓ | ✓ | Local hash computation |
| Certificate Chain | ✓ | ✓ | Requires CA bundle |
| Certificate Revocation | ✓ | ✗ | Needs CRL/OCSP |
| Rekor Transparency | ✓ | ✗ | Needs network |
### 3.5 Air-Gap Considerations
For fully air-gapped environments:
1. **Pre-stage CA bundle**:
```bash
# On connected system
stella ca export --output ca-bundle.pem
# Transfer to air-gapped system
scp ca-bundle.pem airgap:/etc/stellaops/
```
2. **Pre-stage CRL (optional)**:
```bash
# Download latest CRL
curl -o crl.pem https://ca.stellaops.io/crl/latest.pem
# Transfer and use
stella proof verify --bundle bundle.tar.gz --offline --crl crl.pem
```
---
## 4. Transparency Log Integration
### 4.1 Rekor Overview
StellaOps optionally publishes proof attestations to Sigstore Rekor for immutable transparency logging.
```
┌─────────────────────────────────────────────────────────────┐
│ Transparency Flow │
├─────────────────────────────────────────────────────────────┤
│ Proof Bundle │
│ │ │
│ ▼ │
│ DSSE Envelope ──────► Rekor ──────► Inclusion Proof │
│ │ │ │
│ ▼ ▼ │
│ Local Verify Log Entry ID │
└─────────────────────────────────────────────────────────────┘
```
### 4.2 Checking Rekor Entry
```bash
# Verify with Rekor check
stella proof verify --bundle bundle.tar.gz --check-rekor
# Get Rekor entry details
stella proof rekor-entry --bundle bundle.tar.gz
```
Output:
```
Rekor Entry
══════════════════════════════════════════
Log Index: 12345678
Entry UUID: 24296fb24b8ad77a...
Log ID: c0d23d6ad406973f...
Integrated: 2025-01-15T10:30:05Z
Inclusion Proof:
Root Hash: sha256:rekor-root...
Tree Size: 98765432
Hashes: [sha256:a1b2..., sha256:c3d4...]
Verification: ✓ INCLUDED
```
### 4.3 Manual Rekor Verification
```bash
# Using rekor-cli
rekor-cli verify --artifact bundle.tar.gz \
--signature bundle/dsse-envelope.json \
--public-key bundle/certificate.pem
# Search for entries
rekor-cli search --sha sha256:abc123...
```
### 4.4 When Rekor is Unavailable
If Rekor is temporarily unavailable:
1. Verification still succeeds for DSSE and Merkle checks
2. Rekor check is marked as "SKIPPED"
3. Re-verify later when Rekor is available
```bash
# Skip Rekor check
stella proof verify --bundle bundle.tar.gz --skip-rekor
```
---
## 5. Troubleshooting
### 5.1 DSSE Signature Invalid
**Symptoms**: `DSSE signature verification failed`
**Diagnostic Steps**:
1. Extract and inspect envelope:
```bash
tar -xzf bundle.tar.gz
cat bundle/dsse-envelope.json | jq .
```
2. Check payload type:
```bash
cat bundle/dsse-envelope.json | jq -r '.payloadType'
# Expected: application/vnd.stellaops.proof+json
```
3. Verify signature format:
```bash
cat bundle/dsse-envelope.json | jq '.signatures[0].sig' | base64 -d | xxd | head
```
**Common Causes**:
| Cause | Resolution |
|-------|------------|
| Corrupted bundle | Re-download from API |
| Wrong public key | Check trust roots configuration |
| Signature algorithm mismatch | Verify ECDSA-P256 or RSA support |
| Encoding issue | Check Base64 encoding |
### 5.2 Merkle Root Mismatch
**Symptoms**: `Merkle root does not match expected value`
**Diagnostic Steps**:
1. Recompute Merkle root locally:
```bash
stella proof compute-root --bundle bundle.tar.gz
```
2. Compare manifest hashes:
```bash
cat bundle/manifest.json | jq '.hashes'
```
3. Check for trailing whitespace or encoding:
```bash
sha256sum bundle/manifest.json
```
**Resolution**:
- Bundle may have been modified after signing
- Re-export bundle from source system
- If legitimate change, re-sign bundle
### 5.3 Certificate Chain Validation Failed
**Symptoms**: `Certificate chain verification failed`
**Diagnostic Steps**:
1. Check certificate expiry:
```bash
openssl x509 -in bundle/certificate.pem -noout -dates
```
2. Verify chain:
```bash
openssl verify -verbose -CAfile /etc/stellaops/ca-bundle.pem bundle/certificate.pem
```
3. Check for missing intermediates:
```bash
openssl x509 -in bundle/certificate.pem -noout -issuer
```
**Common Errors**:
| Error | Cause | Fix |
|-------|-------|-----|
| `certificate has expired` | Cert past validity | Re-sign with valid cert |
| `unable to get issuer certificate` | Missing intermediate | Update CA bundle |
| `certificate revoked` | Key compromised | Use new signing key |
| `self-signed certificate` | Wrong trust root | Import correct CA |
### 5.4 Bundle Extraction Fails
**Symptoms**: `Failed to extract bundle` or `Invalid archive format`
**Diagnostic Steps**:
1. Check file type:
```bash
file bundle.tar.gz
```
2. Test archive integrity:
```bash
gzip -t bundle.tar.gz
tar -tzf bundle.tar.gz
```
3. Check for truncation:
```bash
ls -la bundle.tar.gz
# Compare with expected size from API
```
**Resolution**:
- Re-download if corrupted
- Check network transfer (use checksums)
- Verify sufficient disk space
---
## 6. Monitoring & Alerting
### 6.1 Key Metrics
| Metric | Description | Alert Threshold |
|--------|-------------|-----------------|
| `proof_verification_total` | Total verifications | Baseline |
| `proof_verification_failures` | Failed verifications | > 5/hour |
| `proof_verification_duration_ms` | Verification latency | p99 > 5s |
| `certificate_expiry_days` | Days until cert expiry | < 30 days |
| `rekor_verification_failures` | Rekor check failures | > 0 (warning) |
### 6.2 Grafana Queries
```promql
# Verification success rate
sum(rate(proof_verification_success_total[1h])) /
sum(rate(proof_verification_total[1h])) * 100
# Verification latency
histogram_quantile(0.99, rate(proof_verification_duration_ms_bucket[5m]))
# Certificate expiry countdown
min(certificate_expiry_days) by (certificate_id)
# Failures by type
sum by (failure_reason) (rate(proof_verification_failures_total[1h]))
```
### 6.3 Alert Rules
```yaml
groups:
- name: proof-verification
rules:
- alert: ProofVerificationFailuresHigh
expr: rate(proof_verification_failures_total[1h]) > 5
for: 5m
labels:
severity: warning
annotations:
summary: High proof verification failure rate
- alert: SigningCertificateExpiringSoon
expr: certificate_expiry_days < 30
for: 1h
labels:
severity: warning
annotations:
summary: Signing certificate expires in {{ $value }} days
- alert: SigningCertificateExpired
expr: certificate_expiry_days <= 0
for: 1m
labels:
severity: critical
annotations:
summary: Signing certificate has expired
```
---
## 7. Escalation Procedures
### 7.1 Escalation Matrix
| Severity | Condition | Response Time | Escalate To |
|----------|-----------|---------------|-------------|
| P1 - Critical | Signing certificate expired | Immediate | Security Team + Platform Lead |
| P1 - Critical | Mass verification failures | 15 minutes | Platform Team |
| P2 - High | Rekor unavailable | 1 hour | Platform Team |
| P3 - Medium | Single verification failure | 4 hours | Support Queue |
| P4 - Low | Certificate expiring (>7 days) | Next sprint | Security Team |
### 7.2 P1: Certificate Expired Response
1. **Immediate Actions** (0-15 min):
- Stop accepting new scans (if signing required)
- Notify stakeholders
- Begin emergency certificate rotation
2. **Certificate Rotation** (15-60 min):
```bash
# Generate new certificate
stella signer cert rotate --emergency
# Verify new certificate
stella signer cert show --current
# Resume operations
stella signer status
```
3. **Post-Incident**:
- Implement certificate expiry monitoring
- Schedule proactive rotations
- Update runbooks
### 7.3 Contacts
| Role | Contact | Availability |
|------|---------|--------------|
| Security Team | security@stellaops.io | Business hours |
| Platform On-Call | platform-oncall@stellaops.io | 24/7 |
| Attestor Team | attestor-team@stellaops.io | Business hours |
---
## Appendix A: DSSE Envelope Format
```json
{
"payloadType": "application/vnd.stellaops.proof+json",
"payload": "<base64-encoded-proof>",
"signatures": [
{
"keyid": "sha256:signing-key-fingerprint",
"sig": "<base64-encoded-signature>"
}
]
}
```
### Payload Structure
```json
{
"_type": "https://stellaops.io/proof/v1",
"subject": [
{
"name": "scan-123",
"digest": {
"sha256": "abc123..."
}
}
],
"predicateType": "https://stellaops.io/attestation/score/v1",
"predicate": {
"manifest": {
"sbomHash": "sha256:...",
"rulesHash": "sha256:...",
"policyHash": "sha256:...",
"feedHash": "sha256:..."
},
"score": 7.5,
"rootHash": "sha256:...",
"timestamp": "2025-01-15T10:30:00Z"
}
}
```
---
## Appendix B: CLI Quick Reference
```bash
# Verification Commands
stella proof verify --bundle <path> # Verify bundle
stella proof verify --bundle <path> --offline # Offline verification
stella proof verify --bundle <path> --verbose # Detailed output
stella proof verify --bundle <path> --check-rekor # Include Rekor check
# Inspection Commands
stella proof spine --bundle <path> # Show Merkle tree
stella proof show --bundle <path> # Show bundle contents
stella proof rekor-entry --bundle <path> # Show Rekor entry
# Offline Kit
stella proof offline-kit create --output <dir> # Create offline kit
stella proof offline-kit verify --kit <dir> --bundle <path> # Use kit
# Certificate Commands
stella signer cert show # Show current cert
stella signer cert rotate # Rotate certificate
stella signer cert export --output <path> # Export public cert
```
---
## Revision History
| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 1.0.0 | 2025-12-20 | Agent | Initial release |

View File

@@ -0,0 +1,518 @@
# Score Replay Operations Runbook
> **Version**: 1.0.0
> **Sprint**: 3500.0004.0004
> **Last Updated**: 2025-12-20
This runbook covers operational procedures for Score Replay, including deterministic score computation verification, proof bundle validation, and troubleshooting replay discrepancies.
---
## Table of Contents
1. [Overview](#1-overview)
2. [Score Replay Operations](#2-score-replay-operations)
3. [Determinism Verification](#3-determinism-verification)
4. [Proof Bundle Management](#4-proof-bundle-management)
5. [Troubleshooting](#5-troubleshooting)
6. [Monitoring & Alerting](#6-monitoring--alerting)
7. [Escalation Procedures](#7-escalation-procedures)
---
## 1. Overview
### What is Score Replay?
Score Replay is the ability to re-execute a vulnerability score computation using the exact same inputs (SBOM, rules, policies, feeds) that were used in the original scan. This provides:
- **Auditability**: Prove that a score was computed correctly
- **Determinism verification**: Confirm that identical inputs produce identical outputs
- **Compliance evidence**: Generate proof bundles for regulatory requirements
- **Dispute resolution**: Verify contested scan results
### Key Concepts
| Term | Definition |
|------|------------|
| **Manifest** | Content-addressed record of all scoring inputs (SBOM hash, rules hash, policy hash, feed hash) |
| **Proof Bundle** | Signed attestation containing manifest, score, and Merkle proof |
| **Root Hash** | Merkle tree root computed from all input hashes |
| **DSSE Envelope** | Dead Simple Signing Envelope containing the signed proof |
| **Freeze Timestamp** | Optional timestamp to replay scoring at a specific point in time |
### Architecture Components
| Component | Purpose | Location |
|-----------|---------|----------|
| Score Engine | Computes vulnerability scores | Scanner Worker |
| Manifest Store | Persists scoring manifests | `scanner.manifest` table |
| Proof Chain | Generates Merkle proofs | Attestor library |
| Signer | Signs proof bundles (DSSE) | Signer service |
---
## 2. Score Replay Operations
### 2.1 Triggering a Score Replay
#### Via CLI
```bash
# Basic replay
stella score replay --scan <scan-id>
# Replay with specific manifest
stella score replay --scan <scan-id> --manifest-hash sha256:abc123...
# Replay with frozen timestamp (for determinism testing)
stella score replay --scan <scan-id> --freeze 2025-01-15T00:00:00Z
# Output as JSON
stella score replay --scan <scan-id> --output json
```
#### Via API
```bash
# POST /api/v1/scanner/score/{scanId}/replay
curl -X POST "https://scanner.stellaops.local/api/v1/scanner/score/scan-123/replay" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"manifestHash": "sha256:abc123...",
"freezeTimestamp": "2025-01-15T00:00:00Z"
}'
```
#### Expected Response
```json
{
"scanId": "scan-123",
"score": 7.5,
"rootHash": "sha256:def456...",
"bundleUri": "/api/v1/scanner/scans/scan-123/proofs/sha256:def456...",
"manifestHash": "sha256:abc123...",
"replayedAt": "2025-01-16T10:30:00Z",
"deterministic": true
}
```
### 2.2 Retrieving Proof Bundles
#### Via CLI
```bash
# Get bundle for a scan
stella score bundle --scan <scan-id>
# Download bundle to file
stella score bundle --scan <scan-id> --output bundle.tar.gz
```
#### Via API
```bash
# GET /api/v1/scanner/score/{scanId}/bundle
curl "https://scanner.stellaops.local/api/v1/scanner/score/scan-123/bundle" \
-H "Authorization: Bearer $TOKEN" \
-o bundle.tar.gz
```
### 2.3 Verifying Score Integrity
#### Via CLI
```bash
# Verify against expected root hash
stella score verify --scan <scan-id> --root-hash sha256:def456...
# Verify downloaded bundle
stella proof verify --bundle bundle.tar.gz
```
#### Via API
```bash
# POST /api/v1/scanner/score/{scanId}/verify
curl -X POST "https://scanner.stellaops.local/api/v1/scanner/score/scan-123/verify" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"expectedRootHash": "sha256:def456..."}'
```
---
## 3. Determinism Verification
### 3.1 What Affects Determinism?
Score computation is deterministic when:
| Input | Requirement |
|-------|-------------|
| SBOM | Identical content (same hash) |
| Rules | Same rule version and configuration |
| Policy | Same policy document |
| Feeds | Same feed snapshot (freeze timestamp) |
| Ordering | Findings sorted deterministically |
### 3.2 Running Determinism Checks
```bash
# Run replay twice and compare
REPLAY1=$(stella score replay --scan $SCAN_ID --output json)
REPLAY2=$(stella score replay --scan $SCAN_ID --output json)
# Extract root hashes
HASH1=$(echo $REPLAY1 | jq -r '.rootHash')
HASH2=$(echo $REPLAY2 | jq -r '.rootHash')
# Compare
if [ "$HASH1" = "$HASH2" ]; then
echo "✓ Determinism verified: $HASH1"
else
echo "✗ Non-deterministic! $HASH1 != $HASH2"
exit 1
fi
```
### 3.3 Common Determinism Issues
| Issue | Cause | Resolution |
|-------|-------|------------|
| Different root hash | Feed data changed between replays | Use `--freeze` timestamp |
| Score drift | Rule version mismatch | Pin rules version in manifest |
| Ordering differences | Non-stable sort in findings | Check Scanner version (fixed in v2.1+) |
| Timestamp in output | Current time in computation | Ensure frozen time mode |
### 3.4 Feed Freeze for Reproducibility
```bash
# Replay with feed state frozen to original scan time
stella score replay --scan $SCAN_ID \
--freeze $(stella scan show $SCAN_ID --output json | jq -r '.scannedAt')
```
---
## 4. Proof Bundle Management
### 4.1 Bundle Contents
A proof bundle (`.tar.gz`) contains:
```
bundle/
├── manifest.json # Input hashes and metadata
├── score.json # Computed score and findings summary
├── merkle-proof.json # Merkle tree with inclusion proofs
├── dsse-envelope.json # Signed attestation (DSSE format)
└── certificate.pem # Signing certificate (optional)
```
### 4.2 Inspecting Bundles
```bash
# Extract and view manifest
tar -xzf bundle.tar.gz
cat bundle/manifest.json | jq .
# Verify DSSE signature
stella proof verify --bundle bundle.tar.gz --verbose
# Check Merkle proof
stella proof spine --bundle bundle.tar.gz
```
### 4.3 Bundle Retention Policy
| Environment | Retention | Notes |
|-------------|-----------|-------|
| Production | 7 years | Regulatory compliance |
| Staging | 90 days | Testing purposes |
| Development | 30 days | Cleanup automatically |
### 4.4 Archiving Bundles
```bash
# Export bundle to long-term storage
stella score bundle --scan $SCAN_ID --output /archive/proofs/$SCAN_ID.tar.gz
# Bulk export for compliance audit
stella score bundle-export \
--since 2024-01-01 \
--until 2024-12-31 \
--output /archive/2024-proofs/
```
---
## 5. Troubleshooting
### 5.1 Replay Returns Different Score
**Symptoms**: Replayed score differs from original scan score.
**Diagnostic Steps**:
1. Check manifest integrity:
```bash
stella scan show $SCAN_ID --output json | jq '.manifest'
```
2. Verify feed state:
```bash
# Compare feed hashes
stella score replay --scan $SCAN_ID --freeze $ORIGINAL_TIME --output json | jq '.manifestHash'
```
3. Check for rule updates:
```bash
stella rules show --version --output json
```
**Resolution**:
- Use `--freeze` timestamp matching original scan
- Pin rule versions in policy
- Regenerate manifest if inputs changed legitimately
### 5.2 Proof Verification Fails
**Symptoms**: `stella proof verify` returns validation errors.
**Diagnostic Steps**:
1. Check DSSE signature:
```bash
stella proof verify --bundle bundle.tar.gz --verbose 2>&1 | grep -i signature
```
2. Verify certificate validity:
```bash
openssl x509 -in bundle/certificate.pem -noout -dates
```
3. Check Merkle proof:
```bash
stella proof spine --bundle bundle.tar.gz --verify
```
**Common Errors**:
| Error | Cause | Fix |
|-------|-------|-----|
| `SIGNATURE_INVALID` | Bundle tampered or wrong key | Re-download bundle |
| `CERTIFICATE_EXPIRED` | Signing cert expired | Check signing key rotation |
| `MERKLE_MISMATCH` | Root hash doesn't match | Verify correct bundle version |
| `MANIFEST_MISSING` | Incomplete bundle | Re-export from API |
### 5.3 Replay Timeout
**Symptoms**: Replay request times out or takes too long.
**Diagnostic Steps**:
1. Check scan size:
```bash
stella scan show $SCAN_ID --output json | jq '.findingsCount'
```
2. Monitor replay progress:
```bash
stella score replay --scan $SCAN_ID --verbose
```
**Resolution**:
- For large scans (>10k findings), increase timeout
- Check Scanner Worker health
- Consider async replay for very large scans
### 5.4 Missing Manifest
**Symptoms**: `Manifest not found` error on replay.
**Diagnostic Steps**:
1. Verify scan exists:
```bash
stella scan show $SCAN_ID
```
2. Check manifest table:
```sql
SELECT * FROM scanner.manifest WHERE scan_id = 'scan-123';
```
**Resolution**:
- Manifest may have been purged (check retention policy)
- Restore from backup if available
- Re-run scan if original inputs available
---
## 6. Monitoring & Alerting
### 6.1 Key Metrics
| Metric | Description | Alert Threshold |
|--------|-------------|-----------------|
| `score_replay_duration_ms` | Time to complete replay | p99 > 30s |
| `score_replay_determinism_failures` | Non-deterministic replays | > 0 |
| `proof_verification_failures` | Failed verifications | > 5/hour |
| `manifest_storage_size_bytes` | Manifest table size | > 100GB |
### 6.2 Grafana Dashboard Queries
```promql
# Replay latency
histogram_quantile(0.99,
rate(score_replay_duration_ms_bucket[5m])
)
# Determinism failure rate
rate(score_replay_determinism_failures_total[1h])
# Proof verification success rate
sum(rate(proof_verification_success_total[1h])) /
sum(rate(proof_verification_total[1h]))
```
### 6.3 Alert Rules
```yaml
groups:
- name: score-replay
rules:
- alert: ScoreReplayLatencyHigh
expr: histogram_quantile(0.99, rate(score_replay_duration_ms_bucket[5m])) > 30000
for: 5m
labels:
severity: warning
annotations:
summary: Score replay latency exceeds 30s at p99
- alert: DeterminismFailure
expr: increase(score_replay_determinism_failures_total[1h]) > 0
for: 1m
labels:
severity: critical
annotations:
summary: Non-deterministic score replay detected
```
---
## 7. Escalation Procedures
### 7.1 Escalation Matrix
| Severity | Condition | Response Time | Escalate To |
|----------|-----------|---------------|-------------|
| P1 - Critical | Determinism failure in production | 15 minutes | Platform Team Lead |
| P2 - High | Proof verification failures > 10/hour | 1 hour | Scanner Team |
| P3 - Medium | Replay latency degradation | 4 hours | Scanner Team |
| P4 - Low | Single replay failure | Next business day | Support Queue |
### 7.2 P1: Determinism Failure Response
1. **Immediate Actions** (0-15 min):
- Capture affected scan IDs
- Preserve original manifest data
- Check for recent deployments
2. **Investigation** (15-60 min):
- Compare input hashes between replays
- Check feed synchronization status
- Review rule engine logs
3. **Remediation**:
- Roll back if deployment-related
- Freeze feeds if data drift
- Hotfix if code bug identified
### 7.3 Contacts
| Role | Contact | Availability |
|------|---------|--------------|
| Scanner Team Lead | scanner-lead@stellaops.io | Business hours |
| Platform On-Call | platform-oncall@stellaops.io | 24/7 |
| Security Team | security@stellaops.io | Business hours |
---
## Appendix A: SQL Queries
### Check Manifest History
```sql
SELECT
scan_id,
manifest_hash,
sbom_hash,
rules_hash,
policy_hash,
feed_hash,
created_at
FROM scanner.manifest
WHERE scan_id = 'scan-123'
ORDER BY created_at DESC;
```
### Find Non-Deterministic Replays
```sql
SELECT
scan_id,
COUNT(DISTINCT root_hash) as unique_hashes,
MIN(replayed_at) as first_replay,
MAX(replayed_at) as last_replay
FROM scanner.replay_log
GROUP BY scan_id
HAVING COUNT(DISTINCT root_hash) > 1;
```
### Proof Bundle Statistics
```sql
SELECT
DATE_TRUNC('day', created_at) as day,
COUNT(*) as bundles_created,
AVG(bundle_size_bytes) as avg_size,
SUM(bundle_size_bytes) as total_size
FROM scanner.proof_bundle
WHERE created_at > NOW() - INTERVAL '30 days'
GROUP BY DATE_TRUNC('day', created_at)
ORDER BY day DESC;
```
---
## Appendix B: CLI Quick Reference
```bash
# Score Replay Commands
stella score replay --scan <id> # Replay score computation
stella score replay --scan <id> --freeze <ts> # Replay with frozen time
stella score bundle --scan <id> # Get proof bundle
stella score verify --scan <id> --root-hash <hash> # Verify score
# Proof Commands
stella proof verify --bundle <path> # Verify bundle file
stella proof verify --bundle <path> --offline # Offline verification
stella proof spine --bundle <path> # Show Merkle spine
# Output Formats
--output json # JSON output
--output table # Table output (default)
--output yaml # YAML output
```
---
## Revision History
| Version | Date | Author | Changes |
|---------|------|--------|---------|
| 1.0.0 | 2025-12-20 | Agent | Initial release |

View 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