Signal Contract Mapping: Advisory ↔ StellaOps
This document is the durable cross-walk between the reference advisory’s wire-level Signal contracts (10 / 12 / 14 / 16 / 18) and their concrete StellaOps implementations. It is written for architects and integrators who need to confirm that StellaOps fulfils each advisory signal, and to find the StellaOps entity, contract, or endpoint that does so.
Altitude note. This is an architectural mapping, not an API reference. It records which StellaOps construct fulfils each advisory signal and why the mapping holds — it deliberately does not restate every DTO field, enum member, or endpoint signature. For exact shapes, follow the
src/pointers; the code is the source of truth and this doc is reconciled against it in passes.
Overview
This document maps the reference advisory’s Signal-based message contracts (10/12/14/16/18) onto the StellaOps implementation. StellaOps uses domain-specific entity names instead of generic “Signal-X” labels; the table below is the durable cross-walk, and each section explains the equivalence.
Key Insight: StellaOps implements the same architectural patterns as the advisory but names entities after business concepts (Triage, Risk, Evidence, Decision) rather than wire-level signal numbers. This buys type safety, relational integrity, and domain clarity while preserving conceptual alignment.
Quick Reference Table
| Advisory Signal | StellaOps equivalent | Owning module(s) | Key types |
|---|---|---|---|
| Signal-10 (SBOM Intake) | CallgraphIngestRequest, ISbomIngestionService | Scanner, Signals | CallgraphIngestRequest, ISbomIngestionService |
| Signal-12 (Evidence/Attestation) | in-toto Statement + DSSE | Attestor, Signer | InTotoStatement, DsseEnvelope, PredicateTypes |
| Signal-14 (Triage Fact) | TriageFinding + satellite entities | Scanner.Triage | TriageFinding, TriageReachabilityResult, TriageRiskResult, TriageEffectiveVex |
| Signal-16 (Diff Delta) | TriageSnapshot, MaterialRiskChange, DriftCause | Scanner.SmartDiff, ReachabilityDrift | MaterialRiskChangeDetector, ReachabilityDriftDetector, TriageSnapshot |
| Signal-18 (Decision) | TriageDecision + DSSE signatures | Scanner.Triage | TriageDecision, TriageEvidenceArtifact |
Signal-10: SBOM Intake
Advisory Specification
The advisory’s Signal-10 carries a CycloneDX 1.7 BOM, a subject (image + digest), a source, a scanProfile, and createdAt. Purpose: initial SBOM ingestion with subject identification.
StellaOps Implementation
- Contract:
CallgraphIngestRequest— a record keyed onTenantId+ArtifactDigest(the subject), carrying the encoded BOM content, language/component/version, optional schema version, and a free-formMetadatamap (wheresource/scanProfilelive). Source:src/Signals/StellaOps.Signals/Models/CallgraphIngestRequest.cs - Service:
ISbomIngestionService— exposesIngestCycloneDxAsyncandIngestSpdxAsync(tenant, stream,SbomIngestionOptions, cancellation token). Source:src/Scanner/StellaOps.Scanner.WebService/Services/ISbomIngestionService.cs
Data flow:
[Scanner] → SbomIngestionService → [CycloneDxComposer/SpdxComposer]
↓
PostgreSQL (scanner.sboms)
↓
Event: "sbom.ingested"
↓
[Downstream processors]
API surface (shape only — see route registrations for exact paths/verbs):
- SBOM ingest endpoint under
/api/scanner/sboms/… - Call-graph + SBOM ingest endpoint under
/api/signals/callgraph/…Sources:src/Scanner/StellaOps.Scanner.WebService/Endpoints/SbomEndpoints.cs,src/Signals/StellaOps.Signals/Services/CallgraphIngestionService.cs,src/Scanner/__Libraries/StellaOps.Scanner.Emit/Composition/CycloneDxComposer.cs
Equivalence: BOM content (CycloneDX 1.7), subject digest (ArtifactDigest, SHA-256), source/profile (Metadata + SbomIngestionOptions), and ingestion timestamp are all represented.
Signal-12: Evidence/Attestation (in-toto Statement)
Advisory Specification
Signal-12 is a DSSE-wrapped in-toto statement: subject.digest, statement type, predicateType, predicate, materials, tool, runId, and start/finish timestamps. Purpose: signed evidence envelopes.
StellaOps Implementation
- Statement:
InTotoStatement— abstract base fixing_typetohttps://in-toto.io/Statement/v1, a requiredSubjectlist, and an abstractPredicateType; concrete predicates derive from it. Source:src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/Statements/InTotoStatement.cs - Envelope:
DsseEnvelope— the standard DSSE shape (payload= base64url canonical JSON,payloadType=application/vnd.in-toto+json,signatureslist). Source:src/Attestor/StellaOps.Attestor.Envelope/DsseEnvelope.cs - Predicate registry:
PredicateTypes— a static catalog of predicate-type URI constants (SLSA provenance plus StellaOps-custom predicates: SBOM, VEX, evidence, path/reachability witness, reachability-drift, policy-decision, and more). Treat the file as authoritative for the exact set and string values — do not hardcode a count here. Source:src/Attestor/StellaOps.Signer/StellaOps.Signer.Core/PredicateTypes.csNote: the Signer module now lives under
src/Attestor/per the module-consolidation map (Signer/Provenance → Attestor). - Signing:
CryptoDsseSigner. Source:src/Attestor/StellaOps.Signer/StellaOps.Signer.Infrastructure/Signing/CryptoDsseSigner.cs
Data flow:
[Component] → ProofChainSigner → [Build in-toto Statement]
↓
Canonical JSON serialization
↓
DSSE PAE construction
↓
CryptoDsseSigner (KMS/Keyless)
↓
DsseEnvelope (signed)
↓
PostgreSQL (attestor.envelopes)
↓
Optional: Rekor transparency log
Sample attestations: src/Attestor/StellaOps.Attestor.Types/samples/ (build-provenance.v1.json, vex-attestation.v1.json, scan-results.v1.json).
Equivalence: subject digests, in-toto statement type, predicate type + body, tool/run/timestamp metadata (carried inside the predicate), and full DSSE wrapping are all present.
Signal-14: Triage Fact
Advisory Specification
Signal-14 is the per-CVE triage fact: subject (purl), cve, stable findingId, location, reachability (status + call-stack ref), epss, cvss (version/vector/score), vexStatus, notes, and evidenceRefs.
StellaOps Implementation
The advisory’s single flat fact is normalised into a core entity plus four satellite entities (1:1 or 1:N), giving relational integrity and independent recompute/caching per component. All live under src/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/.
TriageFinding— core entity. StableFindingId({cve}@{purl}@{scanId}), tenant/asset/purl/cve/rule identity, first/last-seen timestamps, and navigation to the satellites below. Source:…/Entities/TriageFinding.csTriageReachabilityResult(1:1) — reachability verdict + confidence, static/runtime proof refs, an inputs hash for diffing, and lattice score/state. Source:…/Entities/TriageReachabilityResult.csTriageRiskResult(1:1) — combined risk score, CVSS (base/vector/version), EPSS (score/percentile/model-date), policy verdict + lane, inputs hash, and a structured lattice explanation (the advisory’snotes). Source:…/Entities/TriageRiskResult.csTriageEffectiveVex(1:1) — effective VEX status + justification, provenance pointer, and DSSE envelope hash (the advisory’sevidenceRefs). Source:…/Entities/TriageEffectiveVex.csTriageEvidenceArtifact(1:N) — content hash (SHA-256), signature ref, CAS URI, media type/size, created-at. Source:…/Entities/TriageEvidenceArtifact.cs
Database schema (table shape): scanner.triage_findings (core), with scanner.triage_reachability_results, scanner.triage_risk_results, scanner.triage_effective_vex (each 1:1) and scanner.triage_evidence_artifacts (1:N).
Equivalence: every advisory field maps onto a column or satellite entity — subject (AssetId+Purl), CveId, stable FindingId, location/evidence (TriageEvidenceArtifact), reachability, EPSS, CVSS, VEX status, notes (lattice explanation), and evidence refs.
Signal-16: Diff Delta
Advisory Specification
Signal-16 is the minimal delta between two SBOM snapshots: subject, fromVersion/toVersion, a changed set (packages/files/symbols/vulns), and explainableReasons (reason code + params + evidence refs).
StellaOps Implementation
TriageSnapshot— persists a from/to comparison: asset, from/to version + scan ids, from/to inputs hashes, a precomputedDiffJson(the advisory’schanged), and a trigger marker. Source:src/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageSnapshot.csMaterialRiskChangeDetector— compares twoRiskStateSnapshots and emits detected changes. The detection rules are the load-bearing design: R1 reachability flip, R2 VEX-status flip, R3 affected-range boundary cross, R4 intelligence/policy flip. Source:src/Scanner/__Libraries/StellaOps.Scanner.SmartDiff/Detection/MaterialRiskChangeDetector.csRiskStateSnapshot— the deterministic input to detection (reachable / VEX status / in-affected-range / KEV / EPSS / policy decision / lattice state) with a SHA-256ComputeHash()for change detection. Source:src/Scanner/__Libraries/StellaOps.Scanner.SmartDiff/Detection/RiskStateSnapshot.csReachabilityDriftDetector—DetectAsync(baseScanId, headScanId, …); explains why reachability changed between two scans. Source:src/Scanner/__Libraries/StellaOps.Scanner.ReachabilityDrift/Services/ReachabilityDriftDetector.csDriftCauseExplainer/DriftCause— the explainable-reason mechanism.DriftCause.Kindis the reason code (DriftCauseKind: guard removed/added, new public route, visibility escalated, dependency upgraded, symbol removed, unknown) and carries the changed symbol/file/line + a code-change id (the advisory’sevidenceRefs). See the enum in source for the exact member set and reason-code strings. Source:src/Scanner/__Libraries/StellaOps.Scanner.ReachabilityDrift/Services/DriftCauseExplainer.cs
API surface (shape only): smart-diff exposes per-scan change and SARIF 2.1.0 views plus a per-image VEX-candidate view under /smart-diff/…. See route registrations for exact paths.
Database schema (table shape): scanner.triage_snapshots, scanner.risk_state_snapshots, scanner.material_risk_changes, scanner.call_graph_snapshots.
Equivalence: subject, from/to version, changed packages (DiffJson), changed symbols (drift detection), changed vulns (material risk changes), explainable reasons (DriftCause.Kind), and evidence refs are all represented.
Signal-18: Decision
Advisory Specification
Signal-18 is a policy decision: subject, decisionId, severity, priority, rationale[], actions[], and dsseSignatures[].
StellaOps Implementation
The decision splits across two entities: the act of deciding (TriageDecision) and the scoring that severity/priority/actions derive from (TriageRiskResult).
TriageDecision— the human/policy decision record:DecisionId, link toTriageFinding(subject), decision kind (mute/acknowledge/exception), reason + reason code (rationale), actor, policy ref, lifetime (effective/expires/TTL), reversibility (revoked/revoked-at/revoked-by), and signature refs (DsseEnvelopeHash/SignatureRef= the advisory’sdsseSignatures). Source:src/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageDecision.csTriageRiskResultsupplies the derived decision attributes:RiskScore→ priority,Lane→ severity,Verdict(Ship/Block/Exception) → actions, lattice explanation → structured rationale. Source:src/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageRiskResult.csScoreExplanationService— generates the structured rationale (breakdown of CVSS, EPSS, reachability, VEX reduction, gate discounts, KEV bonus). Source:src/Signals/StellaOps.Signals/Services/ScoreExplanationService.cs- Decision predicate:
stella.ops/policy-decision@v1(defined inPredicateTypes, emitted as an attestation).
Database schema (table shape): scanner.triage_decisions (+ scanner.triage_risk_results for severity/priority).
API surface (shape only): create / revoke / list-by-finding under /triage/decisions and /triage/findings/{findingId}/decisions. See route registrations for exact paths/verbs.
Equivalence: subject (via FindingId), DecisionId, severity (Lane), priority (RiskScore), rationale (Reason + lattice explanation), actions (Verdict), and DSSE signatures are all represented.
Idempotency Key Handling
Advisory Pattern
idemKey = hash(subjectDigest || type || runId || cve || windowStart)
StellaOps Implementation
StellaOps achieves the same dedup guarantee through two mechanisms rather than one global hash:
- Event-level idempotency. Inter-service events carry an explicit
IdempotencyKey(alongside event id/kind, correlation/trace/span ids). The Scanner WebService event contract isJobEngineEvent. Source:src/Scanner/StellaOps.Scanner.WebService/Contracts/JobEngineEventContracts.csThe orchestrator→jobengine consolidation renamed the historical
OrchestratorEventcontract; the JobEngine queue/persistence side (undersrc/JobEngine/StellaOps.Scheduler.*) likewise tracks anIdempotencyKeyper job. Earlier doc revisions referenced aJobEngine.Core/Domain/Events/EventEnvelope.cswith aGenerateIdempotencyKeyhelper — that path/helper is not present insrc/; rely on the contract file above for the current shape. - Finding-id stability (Signal-14). Triage findings use a deterministic
FindingId={cve}@{purl}@{scanId}, which folds subject, type, and CVE into one stable key (window is implicit in scan/job timing). Source:src/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/TriageFinding.cs
Equivalence: subject digest (in scanId/AssetId), type (EventKind), run id (correlation/trace + attempt), CVE (in the finding id), and window (scan/job timing) are all folded into the dedup keys.
Evidence Reference Mechanisms
Advisory Pattern
evidenceRefs[i] = dsse://sha256:<payloadHash>
DSSE payloads stored as blobs, indexed by payloadHash and subjectDigest.
StellaOps Implementation
StellaOps uses content-addressable storage with two reference schemes:
- CAS URIs —
cas://reachability/graphs/{hash},cas://runtime/traces/{hash}(BLAKE3-addressed). - DSSE references —
DsseEnvelopeHash(SHA-256 of the envelope) +SignatureRef(pointer intoattestor.envelopes).
These are surfaced on:
TriageEvidenceArtifact— content hash + signature ref + CAS URI per finding (see Signal-14).ReachabilityEvidenceChain— bundles graph evidence + runtime evidence + code anchors + unknowns;GraphEvidence/RuntimeEvidenceeach carry a BLAKE3 hash, acas://URI, and analyzer/probe provenance. Source:src/__Libraries/StellaOps.Signals.Contracts/Models/Evidence/ReachabilityEvidenceChain.cs
Storage:
- PostgreSQL:
attestor.envelopes(DSSE envelopes),scanner.triage_evidence_artifacts(evidence metadata). - RustFS: CAS blob storage (S3-compatible; MinIO legacy support available).
Equivalence: hash-addressed storage (SHA-256/BLAKE3), DSSE references, cas:// URIs, S3-compatible blob store, and subject indexing (via FindingId) all map onto the advisory pattern.
API Endpoint Mapping
The advisory’s flat endpoints map onto namespaced StellaOps routes. Paths below are the shape of the surface; treat the OpenAPI spec (src/Api/StellaOps.Api.OpenApi/stella.yaml) and the route registrations as authoritative for exact verbs and paths.
| Signal | Advisory Endpoint | StellaOps surface (shape) |
|---|---|---|
| Signal-10 | POST /sbom/intake | /api/scanner/sboms/…, /api/signals/callgraph/… |
| Signal-12 | POST /attestations | implicit via signing services; /api/attestor/envelopes/{hash} |
| Signal-14 | GET /triage/facts/{findingId} | /api/scanner/triage/findings/{findingId} (+ /evidence) |
| Signal-16 | GET /diff/{from}/{to} | /api/smart-diff/scans/{scanId}/changes, /api/smart-diff/images/{digest}/candidates |
| Signal-18 | POST /decisions | /api/triage/decisions, /api/triage/findings/{findingId}/decisions |
Component Architecture Alignment
Advisory Architecture
[ Sbomer ] → Signal-10 → [ Router ]
[ Attestor ] → Signal-12 → [ Router ]
[ Scanner.Worker ] → Signal-14 → [ Triage Store ]
[ Reachability.Engine ] → updates Signal-14
[ Smart-Diff ] → Signal-16 → [ Router ]
[ Deterministic-Scorer ] → Signal-18 → [ Router/Notify ]
StellaOps Architecture
[ Scanner.Emit ] → SbomIngestionService → PostgreSQL (scanner.sboms)
[ Attestor.ProofChain ] → DsseEnvelopeSigner → PostgreSQL (attestor.envelopes)
[ Scanner.Triage ] → TriageFinding + related entities → PostgreSQL (scanner.triage_*)
[ ReachabilityAnalyzer ] → PathWitnessBuilder → TriageReachabilityResult
[ SmartDiff + ReachabilityDrift ] → MaterialRiskChangeDetector → TriageSnapshot
[ Policy.Scoring engines ] → ScoreExplanationService → TriageRiskResult + TriageDecision
[ Router.Gateway ] → TransportDispatchMiddleware → Inter-service routing
[ TimelineIndexer ] → TimelineEventEnvelope → Event ordering & storage
Mapping:
- Sbomer ↔ Scanner.Emit
- Attestor ↔ Attestor.ProofChain
- Scanner.Worker ↔ Scanner.Triage
- Reachability.Engine ↔ ReachabilityAnalyzer
- Smart-Diff ↔ SmartDiff + ReachabilityDrift
- Deterministic-Scorer ↔ Policy.Scoring engines
- Router/Timeline ↔ Router.Gateway + TimelineIndexer
Summary
Alignment Status: Fully aligned (conceptually).
StellaOps uses domain-specific entity names instead of generic “Signal-X” labels, but every advisory signal concept has an implemented equivalent:
- Signal-10: SBOM intake via
CallgraphIngestRequest/ISbomIngestionService. - Signal-12: in-toto attestations via
InTotoStatement+DsseEnvelope, with aPredicateTypesregistry and DSSE signing. - Signal-14: triage normalised into
TriageFinding+ reachability/risk/VEX/evidence satellites. - Signal-16: smart-diff via
TriageSnapshot+MaterialRiskChangeDetector(rules R1–R4) + explainableDriftCause. - Signal-18:
TriageDecision+TriageRiskResultwith DSSE signatures and structured rationale.
Why the StellaOps shape: strong entity types over generic JSON blobs, PostgreSQL referential integrity, indexed lookups, business-concept naming, and additive extensibility.
References
StellaOps Code Files
src/Signals/StellaOps.Signals/Models/CallgraphIngestRequest.cssrc/Attestor/__Libraries/StellaOps.Attestor.ProofChain/Statements/InTotoStatement.cssrc/Attestor/StellaOps.Attestor.Envelope/DsseEnvelope.cssrc/Attestor/StellaOps.Signer/StellaOps.Signer.Core/PredicateTypes.cssrc/Scanner/__Libraries/StellaOps.Scanner.Triage/Entities/*.cssrc/Scanner/__Libraries/StellaOps.Scanner.SmartDiff/Detection/MaterialRiskChangeDetector.cssrc/Scanner/__Libraries/StellaOps.Scanner.ReachabilityDrift/Services/*.cssrc/__Libraries/StellaOps.Signals.Contracts/Models/Evidence/ReachabilityEvidenceChain.cssrc/Scanner/StellaOps.Scanner.WebService/Contracts/JobEngineEventContracts.cs
API Contract
- OpenAPI spec:
src/Api/StellaOps.Api.OpenApi/stella.yaml
Advisory References
- Advisory architecture document (CycloneDX 1.7 / VEX-first / in-toto)
- Signal contracts specification (10/12/14/16/18)
- DSSE specification: https://github.com/secure-systems-lab/dsse
- in-toto attestation framework: https://github.com/in-toto/attestation
StellaOps Documentation
- Architecture Overview
- Scanner architecture
- Attestor transparency
- Witness v1 contract
- Schema Mapping — where these entities persist
