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.