- Implemented comprehensive unit tests for VexCandidateEmitter to validate candidate emission logic based on various scenarios including absent and present APIs, confidence thresholds, and rate limiting. - Added integration tests for SmartDiff PostgreSQL repositories, covering snapshot storage and retrieval, candidate storage, and material risk change handling. - Ensured tests validate correct behavior for storing, retrieving, and querying snapshots and candidates, including edge cases and expected outcomes.
30 KiB
Here’s a compact, practical blueprint to fuse Smart‑Diff with a Call‑Stack Reachability engine and emit DSSE‑signed diff attestations that carry a weighted impact index—so Stella Ops can prove not just “what changed,” but “how risky the change is in runtime‑reachable code.”
What this does (in plain words)
- Smart‑Diff: computes semantic diffs between two artifact states (SBOMs, lockfiles, symbols, call maps).
- Reachability: measures whether a changed function/package is actually on a path that executes in your services (based on call graph + entrypoints).
- Weighted Impact Index (WII): one number (0–100) that rises when the change lands on short, highly‑used, externally‑facing, or privileged call paths—and when known vulns become more “deterministic” (exploitably reachable).
- DSSE Attestation: a signed, portable JSON (in‑toto/DSSE) that binds the diff + WII to build/run evidence.
Signals that feed the Weighted Impact Index
Per‑delta features (each contributes a weight; defaults in brackets):
Δreach_len– change in shortest reachable path length to an entrypoint (−∞..+∞) [w=0.25]Δlib_depth– change in library call depth (indirection layers) [w=0.1]exposure– whether the touched symbol is public/external‑facing (API, RPC, HTTP route) [w=0.15]privilege– whether path crosses privileged sinks (deserialization, shell, fs/net, crypto) [w=0.15]hot_path– historical runtime evidence (pprof, APM, eBPF) showing frequent execution [w=0.15]cvss_v4– normalized CVSS v4.0 severity for affected CVEs (0–10 → 0–1) [w=0.1]epss_v4– exploit probability (0–1) [w=0.1]guard_coverage– presence of sanitizers/validations on the path (reduces score) [w=−0.1]
Determinism nudge
If reachability == true and (cvss_v4 > 0.7 || epss_v4 > 0.5), add a +5 bonus to reflect “evidence‑linked determinism.”
Final WII
WII = clamp01( Σ (w_i * feature_i_normalized) ) * 100
Minimal data you need in the engines
1) Smart‑Diff (inputs/outputs)
Inputs: SBOM(CycloneDX), symbol graph (per‑lang indexers), lockfiles, route maps.
Outputs: DiffUnit[] with:
{
"unitId": "pkg:npm/lodash@4.17.21#function:merge",
"change": "modified|added|removed",
"before": {"hash":"...", "attrs": {...}},
"after": {"hash":"...", "attrs": {...}}
}
2) Reachability Engine
Inputs: call graph (nodes: symbols; edges: calls), entrypoints (HTTP routes, jobs, message handlers), runtime heat (optional).
Queries: isReachable(symbol), shortestPathLen(symbol), libCallDepth(symbol), hasPrivilegedSink(path), hasGuards(path).
Putting it together (pipeline)
-
Collect: For image/artifact A→B, build call graph, import SBOMs, CVE map, EPSS/CVSS data, routes, runtime heat.
-
Diff: Run Smart‑Diff →
DiffUnit[]. -
Enrich per DiffUnit using Reachability:
reachable = isReachable(unit.symbol)Δreach_len = shortestPathLen_B - shortestPathLen_AΔlib_depth = libCallDepth_B - libCallDepth_Aexposure/privilege/hot_path/guard_coveragebooleans from path analysiscvss_v4/epss_v4from Feed (Concelier) + Excititor
-
Score: Compute
WIIper unit; also compute artifact‑level WII as:max(WII_unit)andp95(WII_unit)for “spike” vs “broad” impact.
-
Attest: Emit DSSE statement with diff + scores + evidence URIs (SBOM digest, call‑graph digest, logs).
-
Publish/Store: Rekor(v2) mirror (Proof‑Market Ledger), and PostgreSQL as system‑of‑record.
DSSE statement (example)
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [{"name":"ghcr.io/acme/payments:1.9.3","digest":{"sha256":"..."} }],
"predicateType": "https://stella-ops.org/attestations/smart-diff-wii@v1",
"predicate": {
"artifactBefore": {"digest":{"sha256":"..."}},
"artifactAfter": {"digest":{"sha256":"..."}},
"evidence": {
"sbomBefore":{"mediaType":"application/vnd.cdx+json","digest":{"sha256":"..." }},
"sbomAfter": {"mediaType":"application/vnd.cdx+json","digest":{"sha256":"..." }},
"callGraph": {"mediaType":"application/vnd.stella.callgraph+json","digest":{"sha256":"..."}},
"runtimeHeat": {"mediaType":"application/json","optional":true,"digest":{"sha256":"..."}}
},
"units": [{
"unitId":"pkg:nuget/Newtonsoft.Json@13.0.3#type:JsonSerializer",
"change":"modified",
"features":{
"reachable":true,
"deltaReachLen":-2,
"deltaLibDepth":-1,
"exposure":true,
"privilege":true,
"hotPath":true,
"guardCoverage":false,
"cvssV4":0.84,
"epssV4":0.61
},
"wii": 78.4,
"paths":[
{"entry":"HTTP POST /api/import","shortestLen":3,"privSinks":["fs.write"] }
]
}],
"aggregate": {"maxWii": 78.4, "p95Wii": 42.1}
},
"dsse": {"alg":"ed25519","keyid":"stella-authority:kid:abc123","sig":"..."}
}
.NET 10 integration (skeletal but end‑to‑end)
Contracts
public record DiffUnit(string UnitId, ChangeKind Change, Attr? Before, Attr? After);
public interface IReachabilityService {
bool IsReachable(SymbolId s);
int? ShortestPathLen(SymbolId s);
int LibCallDepth(SymbolId s);
bool PathHasPrivilegedSinks(SymbolId s);
bool PathHasGuards(SymbolId s);
bool IsHotPath(SymbolId s);
}
public sealed class WiiScorer {
public double Score(WiiFeatures f) {
double sum =
0.25 * NormalizeDelta(f.DeltaReachLen) +
0.10 * NormalizeDelta(f.DeltaLibDepth) +
0.15 * Bool(f.Exposure) +
0.15 * Bool(f.Privilege) +
0.15 * Bool(f.HotPath) +
0.10 * Clamp01(f.CvssV4) +
0.10 * Clamp01(f.EpssV4) -
0.10 * Bool(f.GuardCoverage);
if (f.Reachable && (f.CvssV4 > 0.7 || f.EpssV4 > 0.5)) sum += 0.05;
return Math.Round(Clamp01(sum) * 100, 1);
}
// helper normalizers (Δ capped to ±5 for stability)
static double NormalizeDelta(int? d) => Clamp01(((d ?? 0) + 5) / 10.0);
static double Bool(bool b) => b ? 1.0 : 0.0;
static double Clamp01(double x) => Math.Min(1, Math.Max(0, x));
}
Orchestrator (Scanner.WebService or Scheduled.Worker)
public async Task<SmartDiffAttestation> RunAsync(Artifact before, Artifact after) {
var diffs = await _smartDiff.ComputeAsync(before, after);
var scorer = new WiiScorer();
var units = new List<AttestedUnit>();
foreach (var d in diffs) {
var s = SymbolId.Parse(d.UnitId);
var feat = new WiiFeatures {
Reachable = _reach.IsReachable(s),
DeltaReachLen = SafeDelta(_reach.ShortestPathLen(s), _baseline.ShortestPathLen(s)),
DeltaLibDepth = _reach.LibCallDepth(s) - _baseline.LibCallDepth(s),
Exposure = _exposure.IsExternalFacing(s),
Privilege = _reach.PathHasPrivilegedSinks(s),
HotPath = _reach.IsHotPath(s),
GuardCoverage = _reach.PathHasGuards(s),
CvssV4 = _vuln.CvssV4For(s),
EpssV4 = _vuln.EpssV4For(s)
};
var wii = scorer.Score(feat);
units.Add(new AttestedUnit(d.UnitId, d.Change, feat, wii, _reach.PathPreview(s)));
}
var agg = new {
maxWii = units.Max(u => u.Wii),
p95Wii = Percentile(units.Select(u => u.Wii), 0.95)
};
var stmt = _attestor.BuildDsse(before, after, units, agg, _evidence.Hashes());
return await _attestor.SignAsync(stmt);
}
Where it lives in Stella Ops
- Concelier (feeds): CVE → CVSS v4.0 and EPSS v4 hydration.
- Excititor (VEX): accepts WII + reachability to mark Affected/Not Affected/Under Investigation with evidence.
- Scanner.WebService & Scanner.Workers: build call graphs, compute diffs, ask Concelier/Excititor for scores, produce attestations.
- Notify.WebService: triggers when
aggregate.maxWii >= thresholdor whenreachable && epss_v4 > X.
Developer checklist (DoD)
- Per‑language call‑graph adapters: .NET, Java, Node, Python (symbol → entrypoint reach; shortest path).
- Smart‑Diff emits
unitIdat function/method granularity (fall back to package). - Concelier endpoints to fetch CVSS v4 and EPSS v4 per
purl/symbol. - WiiScorer unit tests with frozen fixtures (golden files).
- DSSE attestation schema + JSON Schema validation.
- Rekor(v2) publish & local verification; offline bundle export.
- Policy gates: block deploy if
maxWii ≥ 70andreachable == true. - UI panel: show top 5 WII units, path preview, “why this score” explainer.
- CLI:
stella attest diff --before A --after B --emit dsse.json.
Why this strengthens the moat
- Turns reachability into a determinism signal, not just “found a CVE.”
- Binds evidence (graphs, SBOMs, metrics) into signed, portable proofs.
- Produces a single, comparable index that procurement/compliance and SREs can act on in seconds.
If you want, I can drop in a ready‑to‑run .NET 10 sample project (Scanner plug‑in + WiiScorer tests) and a JSON‑Schema for the DSSE predicate.
Below is a full, end‑to‑end implementation plan to ship “Smart‑Diff + Call‑Stack Reachability + Weighted Impact Index + DSSE‑signed diff attestations” into production inside Stella Ops (Scanner / Concelier / Excititor / Notify), with clear sequencing, deliverables, and the concrete engineering work breakdown.
1) Target outcomes and success criteria
Outcomes
-
For any artifact upgrade (A → B), produce a DSSE‑signed in‑toto Statement that includes:
- What changed (Smart‑Diff)
- What is runtime reachable (Call‑Stack Reachability)
- A per‑change Weighted Impact Index (WII) and artifact aggregates (max, p95)
- Evidence digests (SBOMs, call graph, runtime heat, vuln feeds) bound to the attestation
-
Policy gates can block or require approval based on:
maxWII,reachable == true,epss/cvss thresholds, “privileged path” flags, etc.
-
Operators can explain the score: top changes, entrypoints, shortest path, sinks, guards, heat.
Success criteria (Definition of Done)
- ✅ Deterministic diff attestations (same inputs → same statement bytes before signing)
- ✅ Signature verification succeeds offline using published key(s)
- ✅ Correct reachability on representative services (route hits match predicted reachable set)
- ✅ Low noise: “unreachable changes” do not page
- ✅ Scoring is configurable and versioned (weights tracked)
- ✅ Works in CI and/or cluster scanning pipeline
- ✅ Stored in ledger + queryable DB + searchable UI
2) System architecture and data flow
High-level data flow
Artifact A/B (OCI digest, build metadata)
├─ SBOM A/B (CycloneDX)
├─ Symbol Index A/B (function/type identifiers)
├─ Call Graph A/B (nodes=symbols, edges=calls, entrypoints)
├─ Runtime Heat (optional; APM/eBPF)
├─ Vuln Intelligence (CVSS v4, EPSS) from Concelier
│
└─ Smart-Diff (A vs B) -> DiffUnit[]
└─ Reachability enrich (A/B) -> features per unit
└─ WII scoring
└─ DSSE in-toto Statement (predicate)
└─ Sign (KMS/HSM/Key vault) -> DSSE envelope
├─ Publish to Ledger (Rekor-like)
├─ Store in Postgres + Object store
└─ Notify/Policy evaluation
Services / modules to implement or extend
- Scanner.Workers: build evidence (SBOM, call graph), compute diff, compute reachability features, compute WII
- Scanner.WebService: APIs to request attestations, query results, verify
- Concelier: CVE → package/symbol mapping, CVSS v4 + EPSS hydration
- Excititor: produce/ingest VEX decisions using WII + reachability evidence
- Notify: alerting rules and policy gates for CI/CD and runtime
3) Core data contracts (must come first)
3.1 Stable identifiers
You need stable IDs for everything so diffs and reachability join correctly:
-
Artifact ID: OCI digest (sha256) + image name + tag (tag is not trusted as primary)
-
Package ID: PURL (package-url standard)
-
Symbol ID: language-specific but normalized:
.NET:assembly::namespace.type::method(signature)orpdb mvid + token- Java:
class#method(desc) - Node:
module:path#exportName(best-effort) - Python:
module:function(best-effort)
Rule: Symbol IDs must remain stable across rebuilds where possible (prefer token-based or fully-qualified signature).
3.2 Predicate schema v1
Lock the predicate shape early:
artifactBefore,artifactAfterdigestsevidencedigests/URIs (sbom, callGraph, runtimeHeat, vulnSnapshot)units[](diff units with features, paths, wii)aggregate(max/p95 etc.)scoring(weights + version + normalizer caps)generatorinfo (scanner version, build id)
Deliverables:
- JSON Schema for predicate
smart-diff-wii@v1 - Protobuf (optional) for internal transport
- Golden-file fixtures for serialization determinism
4) Phase plan (sequenced deliverables, no guessy timelines)
Milestone M0 — Foundations (must be completed before “real scoring”)
Goal: You can sign/verify attestations and store evidence.
Work items
-
DSSE + in-toto Statement implementation
-
Choose signing primitive: Ed25519 or ECDSA P‑256
-
Implement:
- Statement builder (canonical JSON)
- DSSE envelope wrapper
- Signature verify endpoint + CLI
-
Add key rotation fields:
keyid,predicateType version,scanner build version
-
-
Evidence store
-
Object storage bucket layout:
/sbom/{artifactDigest}.cdx.json/callgraph/{artifactDigest}.cg.json/runtimeheat/{service}/{date}.json/vuln-snapshot/{date}.json
-
Every evidence object has digest recorded in DB
-
-
Database schema
artifacts(id, digest, name, createdAt, buildMetaJson)evidence(id, artifactDigest, kind, digest, uri, createdAt)attestations(id, subjectDigest, beforeDigest, afterDigest, predicateType, dsseDigest, createdAt, aggregateJson)attestation_units(attestationId, unitId, changeKind, reachable, wii, featuresJson, pathsJson)
-
Ledger integration
- Minimal: append-only table + hash chaining (if you want quickly)
- Full: publish to Rekor-like transparency log if already present in your ecosystem
DoD
stella verify dsse.jsonreturns OK- Stored attestations can be fetched by subject digest
- Evidence digests validate
Milestone M1 — Smart‑Diff v1 (package + file level)
Goal: Produce a signed attestation that captures “what changed” even before reachability.
Work items
-
SBOM ingestion & normalization
- Parse CycloneDX SBOM
- Normalize component identity to PURL
- Extract versions, hashes, scopes, dependencies edges
-
Diff engine (SBOM-level)
- Added/removed/updated packages
- Transitive dependency changes
- License changes (optional)
- Output
DiffUnit[]at package granularity first
-
Attestation emitter
-
Populate predicate with:
- units (packages)
- aggregate metrics: number of changed packages; “risk placeholders” (no reachability yet)
-
DoD
- For a dependency bump PR, the system emits DSSE attestation with package diffs
Milestone M2 — Call graph & reachability for .NET (first “real value”)
Goal: For .NET services, determine whether changed symbols/packages are reachable from entrypoints.
Work items
-
.NET call graph builder
-
Implement Roslyn-based static analysis for:
- method invocations
- virtual calls (best-effort: conservative edges)
- async/await (capture call relations)
-
Capture:
- nodes: methods/functions
- edges: caller → callee
- metadata: assembly, namespace, accessibility, source location (if available)
-
-
Entrypoint extractor (.NET)
-
ASP.NET Core minimal APIs:
MapGet/MapPost/...route mapping to delegate targets
-
MVC/WebAPI:
- controller action methods
-
gRPC endpoints
-
Background workers:
IHostedService, Hangfire jobs, Quartz jobs
-
Message handlers:
- MassTransit / Kafka consumers (pattern match + config hooks)
-
-
Reachability index
-
Store adjacency lists
-
For each entrypoint, compute:
- reachable set
- shortest path length to each reachable node (BFS on unweighted graph)
- path witness (store 1–3 representative paths for explainability)
-
Store:
distToNearestEntrypoint[node]nearestEntrypoint[node]- (optional)
countEntrypointsReaching[node]
-
-
Join Smart‑Diff with reachability
-
If you only have package diffs at this stage:
- Map package → symbol set using symbol index
- Mark unit reachable if any symbol reachable
-
If you already have symbol diffs:
- Directly query reachability per symbol
-
DoD
- For a PR that changes a controller path or core code, top diffs show reachable paths
- For a PR that only touches unreachable code (dead feature flags), system marks unreachable
Milestone M3 — Smart‑Diff v2 (symbol-level diffs)
Goal: Move from “package changed” to “what functions/types changed.”
Work items
-
Symbol indexer (.NET)
- Extract public/internal symbols
- Map symbol → file/module + hash of IL/body (or semantic hash)
- Record signature + accessibility + attributes
-
Symbol-level diff
-
Added/removed/modified methods/types
-
Semantic hashing to avoid noise from non-functional rebuild differences
-
Generate unit IDs like:
pkg:nuget/Newtonsoft.Json@13.0.3#method:Namespace.Type::Method(args)
-
-
Unit grouping
-
Group symbol deltas under:
- package delta
- assembly delta
- “API surface delta” (public symbol changes) for exposure
-
DoD
- Attestation units list individual changed symbols with reachable evidence
Milestone M4 — Feature extraction for WII
Goal: Compute the features that make WII meaningful and explainable.
Work items
-
Exposure classification
-
exposure=trueif symbol is:- directly an entrypoint method
- in the shortest path to an entrypoint
- part of public API surface changes
-
Store explanation: “reachable from HTTP POST /x”
-
-
Privilege sink detection
-
Maintain a versioned sink catalog:
- deserialization entrypoints
- process execution
- filesystem writes
- network dial / SSRF primitives
- crypto key handling
- dynamic code evaluation
-
Mark if any witness path crosses sinks
-
Store sink list in
paths[]
-
-
Guard coverage detection
-
Catalog of guard functions:
- input validation, sanitizers, authz checks, schema validators
-
Heuristic: on witness path, detect guard call before sink
-
guardCoverage=truereduces WII
-
-
Library depth
-
Compute “lib call depth” heuristics:
- number of frames from entrypoint to unit
- number of boundary crossings (app → lib → lib)
-
Use in scoring normalization
-
-
Runtime heat integration (optional but high impact)
-
Ingest APM sampling / pprof / eBPF:
(symbolId → invocationCount or CPU%)
-
Normalize to 0..1
hotPath -
Add mapping strategy:
- route names → controller action symbols
-
DoD
- Every unit has a features object with enough fields to justify its score
Milestone M5 — Vulnerability intelligence + determinism linkage
Goal: Use Concelier data to raise score when reachable changes align with exploitable vulns.
Work items
-
Vuln snapshot service (Concelier)
-
Provide API:
GET /vuln/by-purl?purl=...→ CVEs + CVSS v4 + EPSSGET /vuln/snapshot/{date}for reproducibility
-
-
Package ↔ symbol ↔ vuln mapping
- Map CVE affected package versions to
DiffUnitpackages - (Optional advanced) map to symbols if your feed provides function-level info
- Map CVE affected package versions to
-
Determinism rule
- If
reachable=trueAND (cvss>threshold OR epss>threshold) add bonus - Record “why” in unit explanation metadata
- If
DoD
- A dependency bump that introduces/removes a CVE changes WII accordingly
- Attestation includes vuln snapshot digest
Milestone M6 — WII scoring engine v1 + calibration
Goal: Produce a stable numeric index and calibrate thresholds.
Work items
-
Scoring engine
-
Implement WII as:
- weighted sum of normalized features
- clamp to 0..100
-
Make scoring config external + versioned:
- weights
- normalization caps (e.g., delta path len capped at ±5)
- determinism bonus amounts
-
Include
scoring.versionand config hash in predicate
-
-
Golden tests
- Fixture diffs with expected WII
- Regression tests for scoring changes (if weights change, version bumps)
-
Calibration workflow
-
Backtest on historical PRs/incidents:
- correlate WII with incidents / rollbacks / sev tickets
-
Produce recommended initial gate thresholds:
- block:
maxWII >= Xand reachable and privileged - warn:
p95WII >= Y
- block:
-
Store calibration report as an artifact (so you can justify policy)
-
DoD
- Score doesn’t oscillate due to minor code movement
- Thresholds are defensible and adjustable
Milestone M7 — Policy engine + CI/CD integration
Goal: Make it enforceable.
Work items
-
Policy evaluation component
-
Inputs:
- DSSE attestation
- verification result
- environment context (prod/stage)
-
Output:
- allow / warn / block + reason
-
-
CI integration
-
Pipeline step:
- build artifact
- generate evidence
- compute diff against deployed baseline
- emit + sign attestation
- run policy gate
-
Attach attestation to build metadata / OCI registry (as referrers if supported in your ecosystem)
-
-
Deployment integration
-
Admission controller / deploy-time check:
- verify signature
- enforce policy
-
DoD
- A deployment with
reachable && maxWII >= thresholdis blocked or requires approval
Milestone M8 — UI/UX and operator experience
Goal: People can understand and act quickly.
Work items
-
Diff attestation viewer
-
Show:
- aggregate WII (max/p95)
- top units by WII
- per unit: features + witness path(s)
- sinks/guards
- vuln evidence (CVSS/EPSS) with snapshot date
-
-
Explainability
-
“Why this score” breakdown:
- weights * feature values
- determinism bonus
-
Link to evidence objects (SBOM digest, call graph digest)
-
-
Notifications
-
Rules:
- page if
maxWII >= hardand reachable and privileged - slack/email if
maxWII >= warn
- page if
-
Include the top 3 units with paths
-
DoD
- Operators can make a decision within ~1–2 minutes reading the UI (no digging through logs)
Milestone M9 — Multi-language expansion + runtime reachability improvements
Goal: Expand coverage beyond .NET and reduce static-analysis blind spots.
Work items
-
Language adapters
- Java: bytecode analyzer (ASM/Soot-like approach), Spring entrypoints
- Node: TypeScript compiler graph, Express/Koa routes (heuristics)
- Python: AST + import graph; Django/FastAPI routes (heuristics)
-
Dynamic call handling
-
Reflection / DI / dynamic dispatch:
- conservative edges in static
- supplement with runtime traces to confirm
-
-
Distributed reachability
-
Cross-service edges inferred from:
- OpenTelemetry traces (service A → service B endpoint)
-
Build “service-level call graph” overlay:
- entrypoints + downstream calls
-
DoD
- Coverage reaches your top N services and languages
- False negatives reduced by runtime evidence
5) Detailed engineering work breakdown (by component)
A) Smart‑Diff engine
Deliverables
-
ISmartDiffinterface with pluggable diff sources:- SBOM diff
- lockfile diff
- symbol diff
- route diff (entrypoints changed)
Key implementation tasks
-
Normalization layer (PURL, symbol IDs)
-
Diff computation:
- add/remove/update
- semantic hash comparison
-
Output:
- stable
DiffUnitlist - deterministic ordering (sort by unitId)
- stable
Risk controls
- Deterministic hashing and ordering to keep DSSE stable
- “Noise filters” for rebuild-only diffs
B) Call graph builder
Deliverables
-
CallGraphobject:- nodes, edges
- node metadata
- entrypoints list
Key tasks
-
Static analysis per language
-
Entrypoint extraction (routes/jobs/consumers)
-
Graph serialization format:
- versioned
- compressed adjacency lists
Risk controls
- Expect incomplete graphs; never treat as perfect truth
- Maintain confidence score per edge if desired
C) Reachability service
Deliverables
-
IReachabilityServicewith:IsReachable(symbol)ShortestPathLen(symbol)PathPreview(symbol)(witness)LibCallDepth(symbol)PathHasPrivilegedSinks(symbol)PathHasGuards(symbol)
Key tasks
-
BFS from entrypoints
-
Store distances and witnesses
-
Cache per artifact digest
-
Incremental updates:
- recompute only impacted parts when call graph changes (optional optimization)
D) Feature extraction + WII scorer
Deliverables
WiiFeatures+WiiScorer- Versioned
ScoringConfig(weights/normalizers)
Key tasks
- Normalization functions (caps and monotonic transforms)
- Determinism bonus logic
- Aggregation (max, p95, counts by changeKind)
Risk controls
- Scoring changes require a version bump
- Golden tests + backtests
E) Attestation service
Deliverables
BuildStatement(...)SignDsse(...)VerifyDsse(...)
Key tasks
-
Canonical JSON serialization (avoid map-order randomness)
-
Key management:
- key IDs
- rotation and revocation list handling
-
Attach evidence digest set
Risk controls
- Sign only canonical bytes
- Record scanner version and config hash
F) Persistence + ledger
Deliverables
- DB migrations
- Object store client
- Ledger publish/verify integration
Key tasks
-
Store DSSE envelope bytes and computed digest
-
Index by:
- subject digest
- before/after
- maxWII
- reachable count
-
Retention policies
G) Policy + Notifications
Deliverables
- Policy rules (OPA/Rego or internal DSL)
- CI step and deploy-time verifier
- Notify workflows
Key tasks
- Verification must be mandatory before policy evaluation
- Provide human-readable reasons
6) Testing strategy (ship safely)
Unit tests
- Smart‑Diff normalization and diff correctness
- Reachability BFS correctness
- WII scoring determinism
- Predicate schema validation
- DSSE sign/verify roundtrip
Integration tests
- Build sample .NET service → generate call graph → diff two versions → attest
- Concelier mocked responses for CVSS/EPSS
End-to-end tests
- In CI: build → attest → store → verify → policy gate
- In deployment: admission check verifies signature and policy
Performance tests
- Large call graph (100k+ nodes) BFS time and memory
- Batch scoring of thousands of diff units
Security tests
- Tampered evidence digest detection
- Signature replay attempts (wrong subject digest)
- Key rotation tests
7) Rollout plan and operational guardrails
Rollout stages
-
Observe-only mode
- Generate attestations, no gates
- Tune scoring weights and thresholds
-
Warn mode
- Notify only for high WII or reachable vuln combos
-
Enforce mode
- Block only on clear high-risk conditions (reachable + privileged + high WII)
- Add “break glass” path with audit logging
Operational metrics
- Attestation generation success rate
- Verification failure rate
- Reachability coverage (% units with reachable computation)
- False positive/negative reports (human feedback)
- Policy gate blocks over time
Playbooks
-
What to do when:
- call graph generation fails
- Concelier feed unavailable
- signature verification fails
- scoring config mismatch
8) Concrete “first 10 commits” checklist
- Add predicate JSON schema + canonical JSON serializer
- Implement DSSE sign/verify library + CLI command
- Create DB schema + evidence storage plumbing
- Implement SBOM ingestion + SBOM diff ->
DiffUnit[] - Emit DSSE attestation for SBOM diffs only
- Implement .NET entrypoint extraction (minimal API + controllers)
- Implement .NET call graph builder (basic invocations)
- Implement reachability BFS + path witness extraction
- Add WII scoring with config + golden tests
- Add CI policy step (verify + evaluate thresholds) in warn-only mode
9) Deliverables bundle (what you should end up with)
-
Code
- Smart‑Diff engine + plugins
- Call graph builders (starting with .NET)
- Reachability service + caching
- WII scoring service + config
- Attestation builder + DSSE signer/verifier
- Policy evaluation step
- UI endpoints + viewer
-
Schemas and specs
smart-diff-wii@v1JSON schema- Evidence media types and versioning rules
- Scoring config format + versioning policy
-
Ops
- Playbooks and runbooks
- Metrics dashboards
- Key rotation procedure
- Backtest/calibration report
If you want the plan converted into a Jira-ready epic/story breakdown (with each story having acceptance criteria and dependencies), tell me whether you’re implementing only .NET first or multi-language from day one—and I’ll output the backlog in that format.