finish off sprint advisories and sprints
This commit is contained in:
@@ -1,258 +0,0 @@
|
||||
# Sprint 20260120-029 · Delta Delivery Attestation (Planning Only)
|
||||
|
||||
## Topic & Scope
|
||||
|
||||
- **Status:** PLANNING - Not committed to implementation
|
||||
- **Origin:** Product advisory on delta-sig attestation for verifiable update delivery
|
||||
- **Purpose:** Scope the work required to extend delta-sig from CVE detection to delta patch delivery
|
||||
- Working directory: `src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.DeltaSig`
|
||||
- This document captures analysis and proposed tasks; no implementation is scheduled.
|
||||
|
||||
## Advisory Summary
|
||||
|
||||
The advisory proposes extending Stella Ops' delta-sig capabilities to support **patch delivery and reconstruction verification**, similar to:
|
||||
|
||||
- **Chromium Courgette/Zucchini:** Instruction-aware binary diffing for smaller patches
|
||||
- **Microsoft MSDelta/LZX-delta:** Windows Update delta compression
|
||||
- **deltarpm:** RPM delta packages that rebuild full RPMs from installed content
|
||||
- **zchunk:** Chunk-based delta format with HTTP range requests and independent verification
|
||||
|
||||
### Current vs. Proposed Use Cases
|
||||
|
||||
| Aspect | Current Implementation | Advisory Proposal |
|
||||
|--------|------------------------|-------------------|
|
||||
| **Purpose** | CVE detection via signature matching | Patch delivery and reconstruction |
|
||||
| **Question answered** | "Does this binary have the security patch?" | "Can I apply this delta to reconstruct the target?" |
|
||||
| **Data flow** | Signature DB → Match target → Verdict | Base + Delta → Apply → Reconstruct target |
|
||||
| **Output** | `vulnerable`/`patched` verdict | Reconstructed binary + verification |
|
||||
|
||||
## Gap Analysis
|
||||
|
||||
### Already Covered (No Gap)
|
||||
|
||||
1. **Function-level signatures** - v1 and v2 predicates with `DeltaSignature`, `SymbolSignature`, chunk hashes
|
||||
2. **Multiple hash algorithms** - SHA-256/384/512, CFG edge hash, semantic hash
|
||||
3. **Normalization recipes** - `NormalizationRef` with recipe ID, version, steps
|
||||
4. **Deterministic signature generation** - Fully implemented
|
||||
5. **IR-level semantic analysis** - v2 has `IrDiffReferenceV2` with CAS storage
|
||||
6. **DSSE envelope signing** - Implemented via `DeltaSigAttestorIntegration`
|
||||
7. **Reproducible rebuild infrastructure** - `IRebuildService` exists (for full packages)
|
||||
|
||||
### Identified Gaps
|
||||
|
||||
#### GAP-1: Base Artifact Reference for Delta Application
|
||||
|
||||
**Advisory requirement:** "Base artifact reference: canonical artifact ID + digest(s) of the required base."
|
||||
|
||||
**Current state:** `DeltaSigPredicateV2.Subject` is a single artifact. No field to specify base for reconstruction.
|
||||
|
||||
**Proposed schema extension:**
|
||||
```json
|
||||
{
|
||||
"baselineReference": {
|
||||
"purl": "pkg:deb/debian/openssl@1.1.1k-1",
|
||||
"digest": { "sha256": "abc123..." },
|
||||
"buildId": "...",
|
||||
"requiredExact": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### GAP-2: Reconstruction Algorithm Fingerprint
|
||||
|
||||
**Advisory requirement:** "Algorithm fingerprint: `{courgette|zucchini|msdelta|deltarpm|zchunk}@version`"
|
||||
|
||||
**Current state:** `MatchAlgorithm` tracks detection algorithms, not reconstruction algorithms.
|
||||
|
||||
**Proposed schema extension:**
|
||||
```json
|
||||
{
|
||||
"reconstructionAlgorithm": {
|
||||
"algorithm": "zchunk",
|
||||
"version": "1.5.2",
|
||||
"dictionaryDigest": "sha256:def456..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### GAP-3: Chunk/Segment Map for Stream Verification
|
||||
|
||||
**Advisory requirement:** "Chunk/segment map: offsets, sizes, per-chunk hashes to stream-verify during apply."
|
||||
|
||||
**Current state:** `ChunkHash` designed for matching, not reconstruction verification.
|
||||
|
||||
**Proposed schema extension:**
|
||||
```json
|
||||
{
|
||||
"segmentMap": [
|
||||
{ "offset": 0, "size": 4096, "status": "unchanged", "hash": "..." },
|
||||
{ "offset": 4096, "size": 512, "status": "modified", "oldHash": "...", "newHash": "..." },
|
||||
{ "offset": 4608, "size": 1024, "status": "new", "hash": "..." }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### GAP-4: Proof Reference to Build Info
|
||||
|
||||
**Advisory requirement:** "Human/readable `proof_ref`: link to buildinfo or exact reproduce-instructions."
|
||||
|
||||
**Current state:** `IRebuildService` exists but not linked from predicates.
|
||||
|
||||
**Proposed schema extension:**
|
||||
```json
|
||||
{
|
||||
"proofRef": {
|
||||
"buildinfoUrl": "https://buildinfo.example.com/openssl_1.1.1k-1.buildinfo",
|
||||
"buildinfoDigest": "sha256:...",
|
||||
"reproducibilityBackend": "reproduce.debian.net"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### GAP-5: Two-Part Trust (Content + Manifest Signing)
|
||||
|
||||
**Advisory requirement:** "Two-part trust: code-sign the post-image AND sign the update manifest."
|
||||
|
||||
**Current state:** Single DSSE envelope signs the predicate.
|
||||
|
||||
**Proposed new type:**
|
||||
```json
|
||||
{
|
||||
"manifestType": "https://stella-ops.org/delta-manifest/v1",
|
||||
"baseArtifact": { "purl": "...", "digest": {...} },
|
||||
"deltaArtifact": { "url": "...", "digest": {...}, "algorithm": "zchunk@1.5" },
|
||||
"targetArtifact": { "purl": "...", "digest": {...} },
|
||||
"predicateRef": "sha256:...",
|
||||
"manifestSignatures": [...]
|
||||
}
|
||||
```
|
||||
|
||||
#### GAP-6: Reconstruction Service
|
||||
|
||||
**Advisory requirement:** "Reconstruction-first: given base + delta, reassemble in a clean sandbox."
|
||||
|
||||
**Current state:** No `IDeltaApplicationService`.
|
||||
|
||||
**Proposed interface:**
|
||||
```csharp
|
||||
public interface IDeltaApplicationService
|
||||
{
|
||||
Task<DeltaApplicationResult> ApplyAsync(
|
||||
Stream baseArtifact,
|
||||
Stream deltaArtifact,
|
||||
ReconstructionAlgorithm algorithm,
|
||||
CancellationToken ct);
|
||||
|
||||
Task<bool> VerifyReconstructionAsync(
|
||||
Stream reconstructedArtifact,
|
||||
string expectedDigest,
|
||||
CancellationToken ct);
|
||||
}
|
||||
```
|
||||
|
||||
#### GAP-7: Acceptance Test Harness
|
||||
|
||||
**Advisory requirement:** "Signature/manifest checks, byte-for-byte equality."
|
||||
|
||||
**Current state:** No reconstruction tests.
|
||||
|
||||
**Required:** Test harness for base + delta → reconstruction → verification.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
|
||||
- **Upstream:** Existing delta-sig v2 predicates (SPRINT_20260119_004 - DONE)
|
||||
- **Upstream:** Reproducible rebuild infrastructure (SPRINT_20260119_005)
|
||||
- **New dependency:** zchunk library or native binding
|
||||
- **Optional:** Courgette/Zucchini (Chrome's algorithm) if PE/ELF optimization needed
|
||||
- **Parallel-safe:** Schema design can proceed independently of algorithm implementation
|
||||
|
||||
## Proposed Task Breakdown
|
||||
|
||||
### Phase 1: Schema Extensions
|
||||
|
||||
| Task ID | Description | Effort |
|
||||
|---------|-------------|--------|
|
||||
| DDS-001 | Extend `DeltaSigPredicateV2` with `BaselineReference` field | Small |
|
||||
| DDS-002 | Add `ReconstructionAlgorithm` to predicate schema | Small |
|
||||
| DDS-003 | Define `SegmentMap` model for stream verification | Medium |
|
||||
| DDS-004 | Link predicate to `.buildinfo` via `ProofRef` | Small |
|
||||
| DDS-005 | Define `DeltaManifest` type and signing flow | Medium |
|
||||
|
||||
### Phase 2: Service Implementation
|
||||
|
||||
| Task ID | Description | Effort |
|
||||
|---------|-------------|--------|
|
||||
| DDS-006 | Implement `IDeltaApplicationService` interface | Medium |
|
||||
| DDS-007 | zchunk backend for delta application | Large |
|
||||
| DDS-008 | Optional: Courgette/Zucchini backend for PE/ELF | Large |
|
||||
| DDS-009 | Optional: MSDelta backend for Windows | Medium |
|
||||
|
||||
### Phase 3: Verification & Testing
|
||||
|
||||
| Task ID | Description | Effort |
|
||||
|---------|-------------|--------|
|
||||
| DDS-010 | Reconstruction test harness | Medium |
|
||||
| DDS-011 | Byte-for-byte equality verification tests | Small |
|
||||
| DDS-012 | Manifest signature verification tests | Small |
|
||||
|
||||
### Phase 4: Documentation
|
||||
|
||||
| Task ID | Description | Effort |
|
||||
|---------|-------------|--------|
|
||||
| DDS-013 | JSON schema for delta-manifest | Small |
|
||||
| DDS-014 | Documentation updates for delta delivery | Medium |
|
||||
| DDS-015 | CLI command updates (if applicable) | Medium |
|
||||
|
||||
## Decisions & Risks
|
||||
|
||||
### Key Decisions Needed
|
||||
|
||||
- **D1:** Which reconstruction algorithms to support initially? (zchunk recommended for cross-platform)
|
||||
- **D2:** Is manifest signing required, or is predicate signing sufficient?
|
||||
- **D3:** Should delta delivery be a separate predicate type or extension of v2?
|
||||
- **D4:** Air-gap story: pre-bundle deltas or rely on CAS?
|
||||
|
||||
### Risks
|
||||
|
||||
- **R1:** zchunk library may require native bindings (no pure .NET implementation)
|
||||
- **R2:** Courgette/Zucchini are C++ and require interop
|
||||
- **R3:** Scope creep: this is orthogonal to CVE detection and could become a separate product area
|
||||
- **R4:** Testing requires vendor binary pairs (base + patched) which may be hard to acquire
|
||||
|
||||
### Architectural Notes
|
||||
|
||||
Per the advisory:
|
||||
|
||||
> Prefer **zchunk-like chunk maps** + **trained zstd dictionaries** across package families to maximize reuse.
|
||||
|
||||
> For large PE/ELF apps, support **Zucchini/Courgette** paths for maximal shrink.
|
||||
|
||||
> Keep **MSDelta/LZX-delta** as a Windows-native backend for server components and agents.
|
||||
|
||||
> Treat **base availability as policy**: don't even queue a delta unless the precise base digest is present.
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Product decision:** Prioritize delta delivery relative to other roadmap items
|
||||
2. **Architecture review:** Validate proposed schema extensions with Attestor guild
|
||||
3. **Prototype:** Spike zchunk integration to validate effort estimates
|
||||
4. **Air-gap analysis:** Determine how deltas fit into offline deployment model
|
||||
|
||||
## References
|
||||
|
||||
- [Chromium Courgette/Zucchini](https://www.chromium.org/developers/design-documents/software-updates-courgette/)
|
||||
- [Microsoft MSDelta](https://learn.microsoft.com/en-us/windows/win32/devnotes/msdelta)
|
||||
- [deltarpm](https://www.novell.com/documentation/opensuse103/opensuse103_reference/data/sec_rpm_delta.html)
|
||||
- [zchunk](https://github.com/zchunk/zchunk)
|
||||
- [Apple Software Update Process](https://support.apple.com/guide/deployment/software-update-process-dep02c211f3e/web)
|
||||
|
||||
## Execution Log
|
||||
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-01-20 | Planning document created from product advisory gap analysis | Planning |
|
||||
| 2026-01-20 | Kickoff: started decision capture for D1-D4 to move planning toward execution. | Planning |
|
||||
|
||||
## Sprint Status
|
||||
|
||||
**STATUS: PLANNING ONLY** - This document captures scope and analysis. No implementation is committed. Convert to active sprint when prioritized.
|
||||
@@ -1,488 +0,0 @@
|
||||
# Sprint 037 – Unified Trust Score Facade (B+C+D Approach)
|
||||
|
||||
## Topic & Scope
|
||||
|
||||
Implement a **facade layer** over existing EWS and Determinization systems to provide:
|
||||
- **B: Unified API** - Single interface combining EWS scores + Determinization entropy
|
||||
- **C: Versioned weight manifests** - Extract EWS weights to `etc/weights/*.json` files
|
||||
- **D: Unknowns fraction (U)** - Expose Determinization entropy as unified metric
|
||||
|
||||
**Key principle:** Preserve existing guardrails, conflict detection, anchor verification, and decay mechanisms. No formula changes - only unification and better exposure.
|
||||
|
||||
**Working directory:** `src/Signals/`
|
||||
**Secondary directories:** `src/Policy/`, `src/Cli/`, `src/Platform/`
|
||||
**Expected evidence:** Unit tests, integration tests, CLI updates, API endpoints, updated documentation
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Concurrency
|
||||
|
||||
- **Upstream (existing, no changes to core logic):**
|
||||
- EWS: `src/Signals/StellaOps.Signals/EvidenceWeightedScore/` - 6-dimension scoring with guardrails
|
||||
- Determinization: `src/Policy/__Libraries/StellaOps.Policy.Determinization/` - entropy, decay, fingerprints
|
||||
- CLI: `src/Cli/StellaOps.Cli/Commands/ScoreGateCommandGroup.cs` - existing `stella gate score`
|
||||
|
||||
- **Concurrency:** Safe to run in parallel with other sprints; no breaking changes
|
||||
|
||||
---
|
||||
|
||||
## Documentation Prerequisites
|
||||
|
||||
- [Policy architecture](../modules/policy/architecture.md) §3.1 Determinization Configuration
|
||||
- [EWS migration](../modules/policy/design/confidence-to-ews-migration.md) - existing scoring
|
||||
- [Score Proofs API](../api/scanner-score-proofs-api.md) - determinism patterns
|
||||
|
||||
---
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### TSF-001 - Extract EWS Weights to Manifest Files
|
||||
Status: TODO
|
||||
Dependency: none
|
||||
Owners: Signals Guild
|
||||
|
||||
Task description:
|
||||
Extract existing EWS weight configuration from `EvidenceWeightPolicy` into versioned JSON manifest files. EWS continues to work exactly as before, but weights are now loaded from files.
|
||||
|
||||
**Implementation:**
|
||||
- Create `etc/weights/` directory structure
|
||||
- Create `WeightManifest` record matching existing `EvidenceWeights` structure
|
||||
- Create `IWeightManifestLoader` interface + `FileBasedWeightManifestLoader`
|
||||
- Update `EvidenceWeightPolicy` to load weights from manifest files (with fallback to defaults)
|
||||
- Add SHA-256 content hash to manifests for audit trail
|
||||
- Migrate existing default weights: `etc/weights/v2026-01-22.weights.json`
|
||||
|
||||
**Key constraint:** No change to scoring formula or behavior - just externalize configuration.
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `etc/weights/v2026-01-22.weights.json` with current EWS defaults
|
||||
- [ ] `WeightManifest.cs` record with version, effectiveFrom, weights, hash
|
||||
- [ ] `FileBasedWeightManifestLoader.cs` loading from `etc/weights/`
|
||||
- [ ] `EvidenceWeightPolicy` updated to use loader
|
||||
- [ ] Unit tests verifying identical scoring before/after extraction
|
||||
- [ ] Existing determinism tests still pass
|
||||
|
||||
---
|
||||
|
||||
### TSF-002 - Unified Score Facade Service
|
||||
Status: TODO
|
||||
Dependency: TSF-001
|
||||
Owners: Signals Guild
|
||||
|
||||
Task description:
|
||||
Create `IUnifiedScoreService` facade that combines EWS computation with Determinization entropy in a single call. Returns unified result with score, U metric, breakdown, and evidence.
|
||||
|
||||
**Implementation:**
|
||||
- Create `IUnifiedScoreService` interface in `src/Signals/StellaOps.Signals/UnifiedScore/`:
|
||||
```csharp
|
||||
Task<UnifiedScoreResult> ComputeAsync(UnifiedScoreRequest request, CancellationToken ct);
|
||||
```
|
||||
- Create `UnifiedScoreService` that internally:
|
||||
1. Calls `IEvidenceWeightedScoreCalculator.Calculate()` for EWS score
|
||||
2. Calls `IUncertaintyScoreCalculator.CalculateEntropy()` for entropy (U)
|
||||
3. Calls `IConflictDetector.Detect()` for conflict information
|
||||
4. Combines into `UnifiedScoreResult`
|
||||
- `UnifiedScoreResult` includes:
|
||||
- `Score` (0-100 from EWS)
|
||||
- `Bucket` (ActNow/ScheduleNext/Investigate/Watchlist)
|
||||
- `UnknownsFraction` (U from Determinization entropy)
|
||||
- `UnknownsBand` (Complete/Adequate/Sparse/Insufficient)
|
||||
- `Breakdown` (EWS dimension contributions)
|
||||
- `Guardrails` (which caps/floors applied)
|
||||
- `Conflicts` (from ConflictDetector)
|
||||
- `WeightManifestRef` (version + hash)
|
||||
- `EwsDigest` + `DeterminizationFingerprint` (for replay)
|
||||
- Register in DI container
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `IUnifiedScoreService` interface defined
|
||||
- [ ] `UnifiedScoreService` implementation composing EWS + Determinization
|
||||
- [ ] `UnifiedScoreRequest` / `UnifiedScoreResult` DTOs
|
||||
- [ ] DI registration in `ServiceCollectionExtensions`
|
||||
- [ ] Unit tests for facade composition
|
||||
- [ ] Verify identical EWS scores pass through unchanged
|
||||
|
||||
---
|
||||
|
||||
### TSF-003 - Unknowns Band Mapping
|
||||
Status: TODO
|
||||
Dependency: TSF-002
|
||||
Owners: Signals Guild / Policy Guild
|
||||
|
||||
Task description:
|
||||
Map Determinization entropy (0.0-1.0) to user-friendly unknowns bands with actionable thresholds.
|
||||
|
||||
**Implementation:**
|
||||
- Create `UnknownsBandMapper` in `src/Signals/StellaOps.Signals/UnifiedScore/`:
|
||||
```csharp
|
||||
UnknownsBand MapEntropyToBand(double entropy);
|
||||
string GetBandDescription(UnknownsBand band);
|
||||
string GetBandAction(UnknownsBand band);
|
||||
```
|
||||
- Band definitions (matching existing Determinization thresholds):
|
||||
| U Range | Band | Description | Action |
|
||||
|---------|------|-------------|--------|
|
||||
| 0.0-0.2 | Complete | Full signal coverage | Automated decisions |
|
||||
| 0.2-0.4 | Adequate | Sufficient signals | Automated decisions |
|
||||
| 0.4-0.6 | Sparse | Signal gaps exist | Manual review recommended |
|
||||
| 0.6-1.0 | Insufficient | Critical gaps | Block pending more signals |
|
||||
- Integrate with existing `ManualReviewEntropyThreshold` (0.60) and `RefreshEntropyThreshold` (0.40) from Determinization config
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `UnknownsBandMapper.cs` with configurable thresholds
|
||||
- [ ] `UnknownsBand` enum (Complete, Adequate, Sparse, Insufficient)
|
||||
- [ ] Configuration via `appsettings.json` aligned with Determinization
|
||||
- [ ] Unit tests for threshold boundaries
|
||||
- [ ] Integration with `UnifiedScoreResult`
|
||||
|
||||
---
|
||||
|
||||
### TSF-004 - Delta-If-Present Calculations
|
||||
Status: TODO
|
||||
Dependency: TSF-002
|
||||
Owners: Signals Guild
|
||||
|
||||
Task description:
|
||||
When signals are missing, calculate and include "delta if present" showing potential score impact. Uses existing Determinization `SignalGap` information.
|
||||
|
||||
**Implementation:**
|
||||
- Extend `UnifiedScoreResult` with `DeltaIfPresent` list:
|
||||
```csharp
|
||||
IReadOnlyList<SignalDelta> DeltaIfPresent { get; }
|
||||
```
|
||||
- `SignalDelta` record:
|
||||
```csharp
|
||||
record SignalDelta(string Signal, double MinImpact, double MaxImpact, string Description);
|
||||
```
|
||||
- For each missing signal (from Determinization gaps):
|
||||
- Calculate EWS contribution if signal were 0.0 vs 1.0
|
||||
- Include weight from manifest
|
||||
- Add descriptive text (e.g., "If reachability confirmed, score could change by -15 to +8")
|
||||
- Use existing `SignalGap` from Determinization for missing signal list
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `SignalDelta` record defined
|
||||
- [ ] Delta calculation logic in `UnifiedScoreService`
|
||||
- [ ] Integration with `UnifiedScoreResult.DeltaIfPresent`
|
||||
- [ ] Unit tests for delta calculation accuracy
|
||||
- [ ] Test with various missing signal combinations
|
||||
|
||||
---
|
||||
|
||||
### TSF-005 - Platform API Endpoints (Score Evaluate)
|
||||
Status: TODO
|
||||
Dependency: TSF-002, TSF-003, TSF-004
|
||||
Owners: Platform Guild
|
||||
|
||||
Task description:
|
||||
Expose unified score via Platform service REST API endpoints.
|
||||
|
||||
**Implementation:**
|
||||
- Add endpoints to `src/Platform/StellaOps.Platform.WebService/Endpoints/`:
|
||||
- `POST /api/v1/score/evaluate` - Compute unified score (primary scoring endpoint)
|
||||
- `GET /api/v1/score/weights` - List available weight manifests
|
||||
- `GET /api/v1/score/weights/{version}` - Get specific manifest
|
||||
- Request contract for `/score/evaluate`:
|
||||
```json
|
||||
{
|
||||
"sbom_ref": "oci://registry/app@sha256:…",
|
||||
"cvss_vector": "CVSS:3.1/…",
|
||||
"vex_refs": ["oci://…/vex1"],
|
||||
"rekor_receipts": ["BASE64-RECEIPT"],
|
||||
"runtime_witnesses": [{"type":"process","data":"…"}],
|
||||
"options": {"decay_lambda": 0.015, "weight_set_id": "v2026-01-22"}
|
||||
}
|
||||
```
|
||||
- Response includes:
|
||||
- `score_id` - unique identifier for replay lookup
|
||||
- `score_value` - 0-100 score
|
||||
- `unknowns` - list of unknown package refs
|
||||
- `proof_ref` - OCI reference to score proof bundle
|
||||
- Full `UnifiedScoreResult` structure (breakdown, U, band, deltas)
|
||||
- Support `?include_delta=true` query param for delta calculations
|
||||
- Add OpenAPI documentation
|
||||
- Tenant-scoped via Authority
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `POST /api/v1/score/evaluate` endpoint implemented
|
||||
- [ ] `/api/v1/score/weights` endpoints implemented
|
||||
- [ ] Request/response contracts match advisory spec
|
||||
- [ ] OpenAPI spec generated
|
||||
- [ ] Authentication/authorization configured
|
||||
- [ ] Integration tests for each endpoint
|
||||
|
||||
---
|
||||
|
||||
### TSF-006 - CLI `stella gate score` Enhancement
|
||||
Status: TODO
|
||||
Dependency: TSF-005
|
||||
Owners: CLI Guild
|
||||
|
||||
Task description:
|
||||
Enhance existing `stella gate score evaluate` command to show unified metrics (U, bands, deltas).
|
||||
|
||||
**Implementation:**
|
||||
- Update `ScoreGateCommandGroup.cs`:
|
||||
- Add `--show-unknowns` flag to include U metric and band
|
||||
- Add `--show-deltas` flag to include delta-if-present
|
||||
- Add `--weights-version` option to pin specific manifest
|
||||
- Update table output to show U and band when requested
|
||||
- Update JSON output to include full unified result
|
||||
- Add new subcommand `stella gate score weights`:
|
||||
- `list` - Show available weight manifest versions
|
||||
- `show <version>` - Display manifest details
|
||||
- `diff <v1> <v2>` - Compare two manifests
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `--show-unknowns` flag showing U and band
|
||||
- [ ] `--show-deltas` flag showing delta-if-present
|
||||
- [ ] `--weights-version` option for pinning
|
||||
- [ ] `stella gate score weights list|show|diff` commands
|
||||
- [ ] Updated help text and examples
|
||||
- [ ] CLI tests for new options
|
||||
|
||||
---
|
||||
|
||||
### TSF-007 - CLI `stella score` Top-Level Command
|
||||
Status: TODO
|
||||
Dependency: TSF-005, TSF-011
|
||||
Owners: CLI Guild
|
||||
|
||||
Task description:
|
||||
Add new top-level `stella score` command group for direct scoring operations (complementing existing `stella gate score` which is gate-focused).
|
||||
|
||||
**Implementation:**
|
||||
- Create `ScoreCommandGroup.cs` in `src/Cli/StellaOps.Cli/Commands/`:
|
||||
- `stella score compute` - Compute unified score from signals (similar inputs to gate evaluate)
|
||||
- `stella score explain <finding-id>` - Detailed explanation with breakdown
|
||||
- `stella score history <finding-id>` - Score history over time
|
||||
- `stella score compare <finding-id-1> <finding-id-2>` - Compare two findings
|
||||
- `stella score replay <score-id>` - Fetch and display replay proof (depends on TSF-011)
|
||||
- `stella score verify <score-id>` - Verify score by replaying computation locally
|
||||
- Support `--format json|table|markdown` output
|
||||
- Support `--offline` mode using bundled weights
|
||||
- Replay/verify commands output:
|
||||
- Canonical input hashes
|
||||
- Step-by-step algebra decisions
|
||||
- Rekor inclusion proof (if anchored)
|
||||
- Verification status (pass/fail with diff if mismatch)
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `stella score compute` command
|
||||
- [ ] `stella score explain` command
|
||||
- [ ] `stella score history` command (if backend supports)
|
||||
- [ ] `stella score compare` command
|
||||
- [ ] `stella score replay` command
|
||||
- [ ] `stella score verify` command
|
||||
- [ ] Multiple output formats
|
||||
- [ ] Offline mode support
|
||||
- [ ] CLI tests
|
||||
|
||||
---
|
||||
|
||||
### TSF-008 - Console UI Score Display Enhancement
|
||||
Status: TODO
|
||||
Dependency: TSF-005
|
||||
Owners: FE Guild
|
||||
|
||||
Task description:
|
||||
Update Console UI components that display scores to include unknowns fraction and band.
|
||||
|
||||
**Implementation:**
|
||||
- Update finding detail views to show:
|
||||
- Score with bucket (existing)
|
||||
- Unknowns fraction (U) with visual indicator
|
||||
- Unknowns band with color coding
|
||||
- Delta-if-present for missing signals
|
||||
- Weight manifest version used
|
||||
- Add tooltip/popover explaining U and what it means
|
||||
- Update score trend charts to optionally show U over time
|
||||
- Update findings list to show U indicator for high-uncertainty findings
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Finding detail view shows U metric and band
|
||||
- [ ] Color-coded band indicator (green/yellow/orange/red)
|
||||
- [ ] Delta-if-present display for missing signals
|
||||
- [ ] Tooltip explaining unknowns
|
||||
- [ ] Findings list shows high-U indicator
|
||||
- [ ] Score trend chart option for U
|
||||
|
||||
---
|
||||
|
||||
### TSF-009 - Determinism & Replay Tests
|
||||
Status: TODO
|
||||
Dependency: TSF-002
|
||||
Owners: QA / Signals Guild
|
||||
|
||||
Task description:
|
||||
Verify that the unified facade maintains determinism guarantees from underlying EWS and Determinization systems.
|
||||
|
||||
**Implementation:**
|
||||
- Create `UnifiedScoreDeterminismTests.cs`:
|
||||
- Same inputs → same unified result (100+ iterations)
|
||||
- EWS score unchanged through facade
|
||||
- Determinization entropy unchanged through facade
|
||||
- Weight manifest hash stable
|
||||
- Delta calculations deterministic
|
||||
- Create golden test fixtures:
|
||||
- Known inputs with expected unified outputs
|
||||
- Fixtures for various U bands
|
||||
- Fixtures for delta calculations
|
||||
- Verify existing EWS determinism tests still pass
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `UnifiedScoreDeterminismTests.cs` with iteration tests
|
||||
- [ ] Golden fixtures in `__Tests/Fixtures/UnifiedScore/`
|
||||
- [ ] EWS pass-through verification
|
||||
- [ ] Determinization pass-through verification
|
||||
- [ ] CI gate for determinism regression
|
||||
- [ ] Existing EWS/Determinization tests unaffected
|
||||
|
||||
---
|
||||
|
||||
### TSF-010 - Documentation Updates
|
||||
Status: TODO
|
||||
Dependency: TSF-001 through TSF-009
|
||||
Owners: Documentation
|
||||
|
||||
Task description:
|
||||
Update documentation to reflect the unified scoring facade.
|
||||
|
||||
**Implementation:**
|
||||
- Update `docs/technical/scoring-algebra.md` to describe facade approach (not rewrite)
|
||||
- Update `docs/modules/policy/architecture.md` §3.1 to reference weight manifests
|
||||
- Create `docs/modules/signals/unified-score.md` explaining:
|
||||
- What the facade provides
|
||||
- How U metric works
|
||||
- How to interpret bands
|
||||
- CLI command reference
|
||||
- Update `docs/modules/cli/guides/commands/reference.md` with new commands
|
||||
- Add troubleshooting section for common U-related issues
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `docs/technical/scoring-algebra.md` updated for facade approach
|
||||
- [ ] Policy architecture doc updated
|
||||
- [ ] `docs/modules/signals/unified-score.md` guide created
|
||||
- [ ] CLI reference updated
|
||||
- [ ] Troubleshooting guide for U issues
|
||||
|
||||
---
|
||||
|
||||
### TSF-011 - Score Replay & Verification Endpoint
|
||||
Status: TODO
|
||||
Dependency: TSF-005
|
||||
Owners: Platform Guild / Signals Guild
|
||||
|
||||
Task description:
|
||||
Add explicit replay endpoint that returns a signed replay log, enabling external auditors to independently verify any score computation.
|
||||
|
||||
**Implementation:**
|
||||
- Add endpoint to `src/Platform/StellaOps.Platform.WebService/Endpoints/`:
|
||||
- `GET /api/v1/score/{id}/replay` - Fetch signed replay proof for a score
|
||||
- Response contract:
|
||||
```json
|
||||
{
|
||||
"signed_replay_log_dsse": "BASE64",
|
||||
"rekor_inclusion": {"logIndex": 12345, "rootHash": "…"},
|
||||
"canonical_inputs": [
|
||||
{"name": "sbom.json", "sha256": "…"},
|
||||
{"name": "vex.json", "sha256": "…"},
|
||||
{"name": "kev.snapshot", "sha256": "…"}
|
||||
],
|
||||
"transforms": [
|
||||
{"name": "canonicalize_spdx", "version": "1.1"},
|
||||
{"name": "normalize_cvss_v4", "version": "1.0"},
|
||||
{"name": "age_decay", "params": {"lambda": 0.02}}
|
||||
],
|
||||
"algebra_steps": [
|
||||
{"signal": "cvss_v4_base_norm", "w": 0.30, "value": 0.78, "term": 0.234},
|
||||
{"signal": "kev_flag", "w": 0.25, "value": 1, "term": 0.25}
|
||||
],
|
||||
"final_score": 85,
|
||||
"computed_at": "2026-01-22T12:00:00Z"
|
||||
}
|
||||
```
|
||||
- DSSE attestation format:
|
||||
- Payload type: `application/vnd.stella.score+json`
|
||||
- Sign with Authority key
|
||||
- Store replay log as OCI referrer ("StellaBundle" pattern):
|
||||
- Reference: `oci://registry/score-proofs@sha256:…`
|
||||
- Attach to original artifact via OCI referrers API
|
||||
- Create `IReplayLogBuilder` service:
|
||||
- Collects canonical input hashes during scoring
|
||||
- Records transform versions and parameters
|
||||
- Captures step-by-step algebra decisions
|
||||
- Generates DSSE-signed attestation
|
||||
- Create `IReplayVerifier` service:
|
||||
- Takes replay log + original inputs
|
||||
- Re-executes scoring with pinned versions
|
||||
- Returns verification result (pass/fail with diff)
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `GET /api/v1/score/{id}/replay` endpoint implemented
|
||||
- [ ] `IReplayLogBuilder` service capturing full computation trace
|
||||
- [ ] `IReplayVerifier` service for independent verification
|
||||
- [ ] DSSE signing with `application/vnd.stella.score+json` payload type
|
||||
- [ ] OCI referrer storage for replay proofs
|
||||
- [ ] Rekor anchoring integration (optional, configurable)
|
||||
- [ ] OpenAPI spec for replay endpoint
|
||||
- [ ] Integration tests for replay/verify flow
|
||||
- [ ] Golden corpus test: score → replay → verify round-trip
|
||||
|
||||
---
|
||||
|
||||
## Execution Log
|
||||
|
||||
| Date (UTC) | Update | Owner |
|
||||
|------------|--------|-------|
|
||||
| 2026-01-22 | Sprint created from product advisory | Planning |
|
||||
| 2026-01-22 | Revised to B+C+D facade approach after deep analysis of existing systems | Planning |
|
||||
| 2026-01-22 | Added TSF-011 (replay endpoint) per second advisory; renamed `/score/unified` to `/score/evaluate`; added `stella score replay|verify` CLI commands | Planning |
|
||||
|
||||
---
|
||||
|
||||
## Decisions & Risks
|
||||
|
||||
### Decisions Made
|
||||
|
||||
1. **Facade over rewrite** - Preserve existing EWS guardrails, conflict detection, anchor verification
|
||||
2. **Weight manifest format** - JSON with SHA-256 hash, stored in `etc/weights/`
|
||||
3. **U band thresholds** - Aligned with existing Determinization config (0.40/0.60 thresholds)
|
||||
4. **No formula changes** - EWS scoring logic unchanged; only exposed differently
|
||||
5. **Endpoint naming** - Use `/score/evaluate` (per second advisory) instead of `/score/unified` for industry alignment
|
||||
6. **Explicit replay endpoint** - Add `/score/{id}/replay` returning signed DSSE attestation for auditor verification
|
||||
7. **DSSE payload type** - Use `application/vnd.stella.score+json` for score attestations
|
||||
8. **OCI referrer pattern** - Store replay proofs as OCI referrers ("StellaBundle") attached to scored artifacts
|
||||
|
||||
### Risks
|
||||
|
||||
1. **Performance** - Facade adds overhead calling two services
|
||||
- Mitigation: Both services are fast (<100μs); combined still sub-millisecond
|
||||
|
||||
2. **Backward compatibility** - Existing CLI/API consumers expect current format
|
||||
- Mitigation: New fields are additive; existing fields unchanged
|
||||
|
||||
3. **Configuration drift** - Weight manifest vs Determinization config could diverge
|
||||
- Mitigation: Single source of truth via weight manifest; Determinization references it
|
||||
|
||||
### What We're NOT Doing
|
||||
|
||||
- ❌ Replacing EWS formula
|
||||
- ❌ Replacing Determinization entropy calculation
|
||||
- ❌ Changing guardrail logic
|
||||
- ❌ Changing conflict detection
|
||||
- ❌ Breaking existing CLI commands
|
||||
- ❌ Breaking existing API contracts
|
||||
|
||||
---
|
||||
|
||||
## Next Checkpoints
|
||||
|
||||
- [ ] TSF-001 complete - Weights externalized
|
||||
- [ ] TSF-002, TSF-003, TSF-004 complete - Facade functional
|
||||
- [ ] TSF-005 complete - Score evaluate API endpoint
|
||||
- [ ] TSF-011 complete - Replay/verification endpoint + DSSE attestation
|
||||
- [ ] TSF-006, TSF-007 complete - CLI updated (including replay/verify commands)
|
||||
- [ ] TSF-008 complete - UI updated
|
||||
- [ ] TSF-009 complete - Determinism verified
|
||||
- [ ] TSF-010 complete - Documentation finalized
|
||||
@@ -1,115 +0,0 @@
|
||||
# Sprint 038 - eBPF Probe Type Enhancement
|
||||
|
||||
## Topic & Scope
|
||||
- Add probe-type categorization to runtime observation models for eBPF sources
|
||||
- Enable finer-grained filtering and policy evaluation based on probe type
|
||||
- Document offline replay verification algorithm
|
||||
- Working directory: `src/RuntimeInstrumentation/StellaOps.RuntimeInstrumentation.Tetragon/`
|
||||
- Secondary directories: `src/Cli/StellaOps.Cli/Commands/`, `docs/modules/zastava/`
|
||||
- Expected evidence: unit tests, updated CLI, architecture docs
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Upstream: None (backwards-compatible enhancement)
|
||||
- Can run in parallel with other sprints
|
||||
- Uses existing `runtimeWitness@v1` predicate type (no new type needed)
|
||||
|
||||
## Documentation Prerequisites
|
||||
- Archive manifest: `docs-archived/product/advisories/2026-01-22-ebpf-witness-contract/ARCHIVE_MANIFEST.md`
|
||||
- Tetragon bridge: `src/RuntimeInstrumentation/StellaOps.RuntimeInstrumentation.Tetragon/TetragonWitnessBridge.cs`
|
||||
- Zastava architecture: `docs/modules/zastava/architecture.md`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### EBPF-001 - Add ProbeType field to RuntimeObservation
|
||||
Status: TODO
|
||||
Dependency: none
|
||||
Owners: Developer
|
||||
|
||||
Task description:
|
||||
Extend the `RuntimeObservation` record in `TetragonWitnessBridge.cs` to include an optional `ProbeType` field. This allows distinguishing between kprobe, uprobe, tracepoint, and USDT observations while remaining backwards compatible.
|
||||
|
||||
Add enum and field:
|
||||
```csharp
|
||||
public enum EbpfProbeType
|
||||
{
|
||||
Kprobe,
|
||||
Kretprobe,
|
||||
Uprobe,
|
||||
Uretprobe,
|
||||
Tracepoint,
|
||||
Usdt,
|
||||
Fentry,
|
||||
Fexit
|
||||
}
|
||||
|
||||
// Add to RuntimeObservation record:
|
||||
public EbpfProbeType? ProbeType { get; init; }
|
||||
public string? FunctionName { get; init; }
|
||||
public long? FunctionAddress { get; init; }
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `EbpfProbeType` enum added
|
||||
- [ ] `ProbeType`, `FunctionName`, `FunctionAddress` fields added to `RuntimeObservation`
|
||||
- [ ] Existing code continues to work (fields are optional)
|
||||
- [ ] Unit tests for new fields
|
||||
|
||||
### EBPF-002 - Update Tetragon event parser to populate ProbeType
|
||||
Status: TODO
|
||||
Dependency: EBPF-001
|
||||
Owners: Developer
|
||||
|
||||
Task description:
|
||||
Update the Tetragon event parsing logic to extract and populate the `ProbeType` field from Tetragon events. Tetragon events include probe type information that should be mapped to the new enum.
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Tetragon event parser extracts probe type
|
||||
- [ ] Mapping from Tetragon probe types to `EbpfProbeType` enum
|
||||
- [ ] Integration tests with sample Tetragon events
|
||||
|
||||
### EBPF-003 - Add --probe-type filter to witness list CLI
|
||||
Status: TODO
|
||||
Dependency: EBPF-001
|
||||
Owners: Developer
|
||||
|
||||
Task description:
|
||||
Extend the `witness list` CLI command to support filtering by probe type. Add a `--probe-type` option that accepts: kprobe, uprobe, tracepoint, usdt.
|
||||
|
||||
Location: `src/Cli/StellaOps.Cli/Commands/WitnessCommandGroup.cs`
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `--probe-type` option added to `witness list` command
|
||||
- [ ] Filtering logic implemented in handler
|
||||
- [ ] Help text updated
|
||||
- [ ] CLI test coverage added
|
||||
|
||||
### EBPF-004 - Document offline replay verification algorithm
|
||||
Status: TODO
|
||||
Dependency: none
|
||||
Owners: Documentation author
|
||||
|
||||
Task description:
|
||||
Add a section to `docs/modules/zastava/architecture.md` documenting the deterministic replay verification algorithm for runtime witnesses. This should specify:
|
||||
- Input canonicalization steps (RFC 8785 JCS)
|
||||
- Observation ordering rules for deterministic hashing
|
||||
- Signature verification sequence
|
||||
- Offline bundle structure requirements for witness verification
|
||||
|
||||
Completion criteria:
|
||||
- [ ] New section "Offline Witness Verification" added to Zastava architecture
|
||||
- [ ] Canonicalization steps documented
|
||||
- [ ] Observation ordering rules specified
|
||||
- [ ] Offline bundle requirements defined
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-01-22 | Sprint created from eBPF witness advisory. Simplified approach: extend existing model rather than new predicate type. | Planning |
|
||||
|
||||
## Decisions & Risks
|
||||
- **Decision**: Extend existing `RuntimeObservation` with optional `ProbeType` field rather than creating new `ebpfWitness@v1` predicate type. Rationale: simpler, backwards compatible, `SourceType=Tetragon` already identifies eBPF source.
|
||||
- **Risk**: None significant - all new fields are optional, existing witnesses remain valid.
|
||||
|
||||
## Next Checkpoints
|
||||
- EBPF-001 and EBPF-004 can start immediately (no dependencies)
|
||||
- EBPF-002 and EBPF-003 depend on EBPF-001
|
||||
@@ -1,886 +0,0 @@
|
||||
# Sprint 039 – Runtime→Static Linkage Verification
|
||||
|
||||
## Topic & Scope
|
||||
|
||||
Implement the **proof layer** that connects runtime eBPF observations to static analysis claims, enabling users to:
|
||||
- Declare expected call-paths via a **function_map predicate** derived from SBOM
|
||||
- Verify that runtime observations match declared expectations
|
||||
- Complete the offline trust chain with **checkpoint signature verification**
|
||||
- Query historical observations for compliance reporting
|
||||
|
||||
This sprint delivers the missing "contract" and "proof" layers identified in the eBPF witness advisory gap analysis.
|
||||
|
||||
**Working directory:** `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/`
|
||||
**Secondary directories:**
|
||||
- `src/Attestor/` (checkpoint signature fix)
|
||||
- `src/Cli/StellaOps.Cli/Commands/` (CLI commands)
|
||||
- `src/RuntimeInstrumentation/` (observation persistence)
|
||||
- `src/Platform/` (API endpoints)
|
||||
- `src/Web/` (UI components)
|
||||
|
||||
**Expected evidence:** Unit tests, integration tests, CLI commands, API endpoints, UI components, updated documentation
|
||||
|
||||
---
|
||||
|
||||
## User Stories
|
||||
|
||||
### US-1: Security Engineer declares expected call-paths
|
||||
> "As a security engineer, I want to declare which functions my service is expected to call, so I can detect unexpected runtime behavior."
|
||||
|
||||
### US-2: DevOps verifies runtime matches expectations
|
||||
> "As a DevOps engineer, I want to verify that runtime observations match our declared function map, so I can prove our services behave as expected."
|
||||
|
||||
### US-3: Auditor verifies offline
|
||||
> "As an auditor, I want to verify runtime-to-static linkage in an air-gapped environment with full cryptographic proof."
|
||||
|
||||
### US-4: SOC analyst queries observation history
|
||||
> "As a SOC analyst, I want to query historical observations for a specific function to investigate anomalies."
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & Concurrency
|
||||
|
||||
- **Upstream (required before starting):**
|
||||
- Sprint 038 EBPF-001: `ProbeType` field in `RuntimeObservation` (for richer verification)
|
||||
- Existing `PathWitness` model in `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/Witnesses/`
|
||||
- Existing `ClaimIdGenerator` for claim linking
|
||||
- Existing `TetragonWitnessBridge` for observation buffering
|
||||
|
||||
- **Upstream (no changes needed):**
|
||||
- `HttpRekorClient` - will be patched for checkpoint signatures
|
||||
- `BundleManifest` v2.0.0 - function_map will be added as artifact type
|
||||
|
||||
- **Concurrency:**
|
||||
- Safe to run in parallel with Sprint 037 (trust score)
|
||||
- Depends on Sprint 038 EBPF-001 completing first
|
||||
|
||||
---
|
||||
|
||||
## Documentation Prerequisites
|
||||
|
||||
- [Witness contract v1](../contracts/witness-v1.md) - Node hash and path hash recipes
|
||||
- [Zastava architecture](../modules/zastava/architecture.md) - Runtime signal flow
|
||||
- [Attestor offline verification](../modules/attestor/guides/offline-verification.md) - Bundle verification
|
||||
- Sprint 038 EBPF-004 output (offline replay algorithm docs)
|
||||
|
||||
---
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### RLV-001 - Define function_map Predicate Schema
|
||||
Status: TODO
|
||||
Dependency: none
|
||||
Owners: Scanner Guild / Attestor Guild
|
||||
|
||||
Task description:
|
||||
Define the `function_map` predicate schema that declares expected call-paths for a service. This is the "contract" that runtime observations will be verified against.
|
||||
|
||||
**Schema design:**
|
||||
```json
|
||||
{
|
||||
"_type": "https://stella.ops/predicates/function-map/v1",
|
||||
"subject": {
|
||||
"purl": "pkg:oci/myservice@sha256:abc123...",
|
||||
"digest": { "sha256": "abc123..." }
|
||||
},
|
||||
"predicate": {
|
||||
"schemaVersion": "1.0.0",
|
||||
"service": "myservice",
|
||||
"buildId": "abc123def456...",
|
||||
"generatedFrom": {
|
||||
"sbomRef": "sha256:...",
|
||||
"staticAnalysisRef": "sha256:..."
|
||||
},
|
||||
"expectedPaths": [
|
||||
{
|
||||
"pathId": "path-001",
|
||||
"description": "TLS handshake via OpenSSL",
|
||||
"entrypoint": {
|
||||
"symbol": "myservice::handle_request",
|
||||
"nodeHash": "sha256:..."
|
||||
},
|
||||
"expectedCalls": [
|
||||
{
|
||||
"symbol": "SSL_connect",
|
||||
"purl": "pkg:deb/debian/openssl@3.0.11",
|
||||
"nodeHash": "sha256:...",
|
||||
"probeTypes": ["uprobe", "uretprobe"],
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"symbol": "SSL_read",
|
||||
"purl": "pkg:deb/debian/openssl@3.0.11",
|
||||
"nodeHash": "sha256:...",
|
||||
"probeTypes": ["uprobe"],
|
||||
"optional": false
|
||||
}
|
||||
],
|
||||
"pathHash": "sha256:..."
|
||||
}
|
||||
],
|
||||
"coverage": {
|
||||
"minObservationRate": 0.95,
|
||||
"windowSeconds": 1800
|
||||
},
|
||||
"generatedAt": "2026-01-22T12:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Key design decisions:**
|
||||
- Uses existing `nodeHash` recipe from witness-v1 contract for consistency
|
||||
- `expectedCalls` array defines the "hot functions" from the advisory
|
||||
- `probeTypes` specifies which probe types are acceptable for each function
|
||||
- `coverage.minObservationRate` maps to advisory's "≥ 95% of calls witnessed"
|
||||
- `optional` flag allows for conditional paths (feature flags, error handlers)
|
||||
|
||||
**Implementation:**
|
||||
- Create `FunctionMapPredicate.cs` record in `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/FunctionMap/`
|
||||
- Create `ExpectedPath.cs` and `ExpectedCall.cs` supporting records
|
||||
- Add JSON schema to `docs/schemas/function-map-v1.schema.json`
|
||||
- Register predicate type with Attestor predicate router
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `FunctionMapPredicate.cs` with full schema
|
||||
- [ ] JSON schema in `docs/schemas/`
|
||||
- [ ] Predicate type registered: `https://stella.ops/predicates/function-map/v1`
|
||||
- [ ] Unit tests for serialization/deserialization
|
||||
- [ ] Schema validation tests
|
||||
|
||||
---
|
||||
|
||||
### RLV-002 - Implement FunctionMapGenerator
|
||||
Status: TODO
|
||||
Dependency: RLV-001
|
||||
Owners: Scanner Guild
|
||||
|
||||
Task description:
|
||||
Implement a generator that produces a `function_map` predicate from SBOM + static analysis results. This enables users to declare expected paths without manually authoring JSON.
|
||||
|
||||
**Implementation:**
|
||||
- Create `IFunctionMapGenerator` interface:
|
||||
```csharp
|
||||
public interface IFunctionMapGenerator
|
||||
{
|
||||
Task<FunctionMapPredicate> GenerateAsync(
|
||||
FunctionMapGenerationRequest request,
|
||||
CancellationToken ct);
|
||||
}
|
||||
```
|
||||
- Create `FunctionMapGenerationRequest`:
|
||||
```csharp
|
||||
public record FunctionMapGenerationRequest
|
||||
{
|
||||
public required string SbomPath { get; init; }
|
||||
public required string ServiceName { get; init; }
|
||||
public string? StaticAnalysisPath { get; init; }
|
||||
public IReadOnlyList<string>? HotFunctionPatterns { get; init; }
|
||||
public double MinObservationRate { get; init; } = 0.95;
|
||||
public int WindowSeconds { get; init; } = 1800;
|
||||
}
|
||||
```
|
||||
- Create `FunctionMapGenerator` implementation:
|
||||
1. Parse SBOM to extract components with PURLs
|
||||
2. If static analysis provided, extract call paths
|
||||
3. If hot function patterns provided, filter to matching symbols
|
||||
4. Generate node hashes using existing `NodeHashRecipe`
|
||||
5. Compute path hashes using existing `PathHashRecipe`
|
||||
6. Return populated `FunctionMapPredicate`
|
||||
|
||||
**Location:** `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/FunctionMap/`
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `IFunctionMapGenerator` interface
|
||||
- [ ] `FunctionMapGenerator` implementation
|
||||
- [ ] Integration with existing SBOM parser
|
||||
- [ ] Support for hot function pattern matching (glob/regex)
|
||||
- [ ] Unit tests with sample SBOM
|
||||
- [ ] Integration test: SBOM → function_map → valid predicate
|
||||
|
||||
---
|
||||
|
||||
### RLV-003 - Implement IClaimVerifier
|
||||
Status: TODO
|
||||
Dependency: RLV-001, Sprint 038 EBPF-001
|
||||
Owners: Scanner Guild
|
||||
|
||||
Task description:
|
||||
Implement the claim verification logic that proves runtime observations match a declared function_map. This is the core "proof" step.
|
||||
|
||||
**Implementation:**
|
||||
- Create `IClaimVerifier` interface in `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/Verification/`:
|
||||
```csharp
|
||||
public interface IClaimVerifier
|
||||
{
|
||||
Task<ClaimVerificationResult> VerifyAsync(
|
||||
FunctionMapPredicate functionMap,
|
||||
IReadOnlyList<RuntimeObservation> observations,
|
||||
ClaimVerificationOptions options,
|
||||
CancellationToken ct);
|
||||
}
|
||||
```
|
||||
- Create `ClaimVerificationResult`:
|
||||
```csharp
|
||||
public record ClaimVerificationResult
|
||||
{
|
||||
public required bool Verified { get; init; }
|
||||
public required double ObservationRate { get; init; }
|
||||
public required IReadOnlyList<PathVerificationResult> Paths { get; init; }
|
||||
public required IReadOnlyList<string> UnexpectedSymbols { get; init; }
|
||||
public required IReadOnlyList<string> MissingExpectedSymbols { get; init; }
|
||||
public required ClaimVerificationEvidence Evidence { get; init; }
|
||||
}
|
||||
|
||||
public record PathVerificationResult
|
||||
{
|
||||
public required string PathId { get; init; }
|
||||
public required bool Observed { get; init; }
|
||||
public required int ObservationCount { get; init; }
|
||||
public required IReadOnlyList<string> MatchedNodeHashes { get; init; }
|
||||
public required IReadOnlyList<string> MissingNodeHashes { get; init; }
|
||||
}
|
||||
|
||||
public record ClaimVerificationEvidence
|
||||
{
|
||||
public required string FunctionMapDigest { get; init; }
|
||||
public required string ObservationsDigest { get; init; }
|
||||
public required DateTimeOffset VerifiedAt { get; init; }
|
||||
public required string VerifierVersion { get; init; }
|
||||
}
|
||||
```
|
||||
- Create `ClaimVerifier` implementation:
|
||||
1. Group observations by node hash
|
||||
2. For each expected path in function_map:
|
||||
- Check if all required node hashes were observed
|
||||
- Check if probe types match expectations
|
||||
- Calculate observation rate
|
||||
3. Detect unexpected symbols (observed but not in function_map)
|
||||
4. Calculate overall observation rate
|
||||
5. Compare against `coverage.minObservationRate`
|
||||
6. Build evidence record for audit trail
|
||||
|
||||
**Verification algorithm:**
|
||||
```
|
||||
For each path in functionMap.expectedPaths:
|
||||
matched = 0
|
||||
for each call in path.expectedCalls:
|
||||
if observations.any(o => o.nodeHash == call.nodeHash && call.probeTypes.contains(o.probeType)):
|
||||
matched++
|
||||
path.observationRate = matched / path.expectedCalls.count
|
||||
|
||||
overallRate = observedPaths / totalPaths
|
||||
verified = overallRate >= functionMap.coverage.minObservationRate
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `IClaimVerifier` interface defined
|
||||
- [ ] `ClaimVerifier` implementation with verification algorithm
|
||||
- [ ] `ClaimVerificationResult` with detailed breakdown
|
||||
- [ ] Evidence record for audit trail
|
||||
- [ ] Detection of unexpected symbols
|
||||
- [ ] Unit tests for various scenarios (full match, partial, no match)
|
||||
- [ ] Integration test with real observations
|
||||
|
||||
---
|
||||
|
||||
### RLV-004 - Fix Checkpoint Signature Verification
|
||||
Status: TODO
|
||||
Dependency: none
|
||||
Owners: Attestor Guild
|
||||
|
||||
Task description:
|
||||
Complete the Rekor checkpoint signature verification that currently returns `false` unconditionally. This is required for full offline trust chain.
|
||||
|
||||
**Current state (HttpRekorClient.cs:282-289):**
|
||||
```csharp
|
||||
_logger.LogDebug(
|
||||
"Checkpoint signature verification is unavailable for UUID {Uuid}; treating checkpoint as unverified",
|
||||
rekorUuid);
|
||||
// ...
|
||||
return RekorInclusionVerificationResult.Success(
|
||||
logIndex.Value,
|
||||
computedRootHex,
|
||||
proof.Checkpoint.RootHash,
|
||||
checkpointSignatureValid: false); // Always false
|
||||
```
|
||||
|
||||
**Implementation:**
|
||||
- Update `HttpRekorClient.VerifyInclusionAsync()` to:
|
||||
1. Extract checkpoint note from response
|
||||
2. Parse note format: body + signature lines
|
||||
3. Verify signature using `CheckpointSignatureVerifier` (already exists)
|
||||
4. Return actual verification result
|
||||
- Add `RekorPublicKey` configuration option for pinned verification
|
||||
- Support both online (fetch from Rekor) and offline (pinned key) modes
|
||||
|
||||
**Location:** `src/Attestor/__Libraries/StellaOps.Attestor.Infrastructure/Rekor/HttpRekorClient.cs`
|
||||
|
||||
**Testing:**
|
||||
- Verify against real Rekor checkpoint
|
||||
- Verify with pinned public key (offline mode)
|
||||
- Verify rejection of tampered checkpoint
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Checkpoint signature verification implemented
|
||||
- [ ] `checkpointSignatureValid` returns actual result
|
||||
- [ ] Support for pinned public key (air-gap mode)
|
||||
- [ ] Unit tests with test vectors
|
||||
- [ ] Integration test against Rekor staging
|
||||
|
||||
---
|
||||
|
||||
### RLV-005 - Implement Runtime Observation Store
|
||||
Status: TODO
|
||||
Dependency: Sprint 038 EBPF-001
|
||||
Owners: Signals Guild
|
||||
|
||||
Task description:
|
||||
Implement persistent storage for runtime observations to support historical queries and compliance reporting.
|
||||
|
||||
**Implementation:**
|
||||
- Create `IRuntimeObservationStore` interface (if not exists) in `src/RuntimeInstrumentation/`:
|
||||
```csharp
|
||||
public interface IRuntimeObservationStore
|
||||
{
|
||||
Task StoreAsync(RuntimeObservation observation, CancellationToken ct);
|
||||
Task StoreBatchAsync(IReadOnlyList<RuntimeObservation> observations, CancellationToken ct);
|
||||
|
||||
Task<IReadOnlyList<RuntimeObservation>> QueryBySymbolAsync(
|
||||
string nodeHash,
|
||||
DateTimeOffset from,
|
||||
DateTimeOffset to,
|
||||
CancellationToken ct);
|
||||
|
||||
Task<IReadOnlyList<RuntimeObservation>> QueryByContainerAsync(
|
||||
string containerId,
|
||||
DateTimeOffset from,
|
||||
DateTimeOffset to,
|
||||
CancellationToken ct);
|
||||
|
||||
Task<ObservationSummary> GetSummaryAsync(
|
||||
string nodeHash,
|
||||
DateTimeOffset from,
|
||||
DateTimeOffset to,
|
||||
CancellationToken ct);
|
||||
|
||||
Task PruneOlderThanAsync(TimeSpan retention, CancellationToken ct);
|
||||
}
|
||||
```
|
||||
- Create `PostgresRuntimeObservationStore` implementation:
|
||||
- Table: `runtime_observations` with indexes on `node_hash`, `container_id`, `observed_at`
|
||||
- Batch insert with conflict handling (dedup by observation_id)
|
||||
- Efficient time-range queries using BRIN index on `observed_at`
|
||||
- Configurable retention policy (default: 7 days)
|
||||
- Create migration: `src/RuntimeInstrumentation/.../Migrations/001_runtime_observations.sql`
|
||||
- Wire into `TetragonWitnessBridge` to persist observations as they arrive
|
||||
|
||||
**Schema:**
|
||||
```sql
|
||||
CREATE TABLE runtime_observations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
observation_id TEXT NOT NULL UNIQUE,
|
||||
node_hash TEXT NOT NULL,
|
||||
symbol_name TEXT,
|
||||
container_id TEXT NOT NULL,
|
||||
pod_name TEXT,
|
||||
namespace TEXT,
|
||||
probe_type TEXT,
|
||||
function_address BIGINT,
|
||||
stack_sample_hash TEXT,
|
||||
observation_count INTEGER DEFAULT 1,
|
||||
duration_us BIGINT,
|
||||
observed_at TIMESTAMPTZ NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_observations_node_hash ON runtime_observations (node_hash);
|
||||
CREATE INDEX idx_observations_container ON runtime_observations (container_id);
|
||||
CREATE INDEX idx_observations_time USING BRIN ON runtime_observations (observed_at);
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `IRuntimeObservationStore` interface
|
||||
- [ ] `PostgresRuntimeObservationStore` implementation
|
||||
- [ ] Database migration
|
||||
- [ ] Integration with `TetragonWitnessBridge`
|
||||
- [ ] Configurable retention policy
|
||||
- [ ] Unit tests for store operations
|
||||
- [ ] Integration tests with real Postgres
|
||||
|
||||
---
|
||||
|
||||
### RLV-006 - CLI: `stella function-map generate`
|
||||
Status: TODO
|
||||
Dependency: RLV-002
|
||||
Owners: CLI Guild
|
||||
|
||||
Task description:
|
||||
Add CLI command to generate a function_map predicate from SBOM.
|
||||
|
||||
**Implementation:**
|
||||
- Create `FunctionMapCommandGroup.cs` in `src/Cli/StellaOps.Cli/Commands/`
|
||||
- Add command: `stella function-map generate`
|
||||
|
||||
**Command spec:**
|
||||
```
|
||||
stella function-map generate [options]
|
||||
|
||||
Options:
|
||||
--sbom <path> Path to SBOM file (CycloneDX/SPDX) [required]
|
||||
--service <name> Service name for the function map [required]
|
||||
--static-analysis <path> Path to static analysis results (optional)
|
||||
--hot-functions <pattern> Glob pattern for hot functions (can repeat)
|
||||
Example: --hot-functions "SSL_*" --hot-functions "crypto_*"
|
||||
--min-rate <0.0-1.0> Minimum observation rate (default: 0.95)
|
||||
--window <seconds> Observation window in seconds (default: 1800)
|
||||
--output <path> Output path (default: stdout)
|
||||
--format <json|yaml> Output format (default: json)
|
||||
--sign Sign the predicate with configured key
|
||||
--attest Create DSSE envelope and push to Rekor
|
||||
|
||||
Examples:
|
||||
# Generate from SBOM with default hot functions
|
||||
stella function-map generate --sbom sbom.json --service myservice
|
||||
|
||||
# Generate with specific hot functions
|
||||
stella function-map generate --sbom sbom.json --service myservice \
|
||||
--hot-functions "SSL_*" --hot-functions "EVP_*" --hot-functions "connect"
|
||||
|
||||
# Generate, sign, and attest
|
||||
stella function-map generate --sbom sbom.json --service myservice \
|
||||
--sign --attest --output function-map.json
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `stella function-map generate` command implemented
|
||||
- [ ] All options working
|
||||
- [ ] DSSE signing integration (--sign)
|
||||
- [ ] Rekor attestation integration (--attest)
|
||||
- [ ] JSON and YAML output formats
|
||||
- [ ] Help text and examples
|
||||
- [ ] CLI tests
|
||||
|
||||
---
|
||||
|
||||
### RLV-007 - CLI: `stella function-map verify`
|
||||
Status: TODO
|
||||
Dependency: RLV-003, RLV-005
|
||||
Owners: CLI Guild
|
||||
|
||||
Task description:
|
||||
Add CLI command to verify runtime observations against a function_map.
|
||||
|
||||
**Command spec:**
|
||||
```
|
||||
stella function-map verify [options]
|
||||
|
||||
Options:
|
||||
--function-map <path|ref> Path or OCI reference to function_map predicate [required]
|
||||
--container <id> Container ID to verify (optional, default: all)
|
||||
--from <timestamp> Start of observation window (default: 30 minutes ago)
|
||||
--to <timestamp> End of observation window (default: now)
|
||||
--output <path> Output verification report (default: stdout)
|
||||
--format <json|table|md> Output format (default: table)
|
||||
--strict Fail on any unexpected symbols
|
||||
--sign Sign the verification report
|
||||
--offline Offline mode (use bundled observations)
|
||||
--observations <path> Path to observations file (for offline mode)
|
||||
|
||||
Output:
|
||||
Verified: true/false
|
||||
Observation Rate: 97.2% (target: 95.0%)
|
||||
|
||||
Path Coverage:
|
||||
┌──────────────┬──────────┬───────────┬─────────────┐
|
||||
│ Path ID │ Status │ Rate │ Missing │
|
||||
├──────────────┼──────────┼───────────┼─────────────┤
|
||||
│ path-001 │ ✓ │ 100% │ - │
|
||||
│ path-002 │ ✓ │ 95.5% │ - │
|
||||
│ path-003 │ ✗ │ 80.0% │ SSL_write │
|
||||
└──────────────┴──────────┴───────────┴─────────────┘
|
||||
|
||||
Unexpected Symbols: none
|
||||
|
||||
Evidence:
|
||||
Function Map Digest: sha256:abc123...
|
||||
Observations Digest: sha256:def456...
|
||||
Verified At: 2026-01-22T12:00:00Z
|
||||
|
||||
Examples:
|
||||
# Verify against stored observations
|
||||
stella function-map verify --function-map function-map.json
|
||||
|
||||
# Verify specific container
|
||||
stella function-map verify --function-map function-map.json \
|
||||
--container abc123 --from "2026-01-22T11:30:00Z"
|
||||
|
||||
# Offline verification with bundled observations
|
||||
stella function-map verify --function-map function-map.json \
|
||||
--offline --observations observations.ndjson
|
||||
|
||||
# Sign verification report for audit
|
||||
stella function-map verify --function-map function-map.json \
|
||||
--sign --output verification-report.json
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `stella function-map verify` command implemented
|
||||
- [ ] Query observations from store
|
||||
- [ ] Offline mode with file input
|
||||
- [ ] Table, JSON, and Markdown output formats
|
||||
- [ ] Signed verification report option
|
||||
- [ ] CLI tests
|
||||
|
||||
---
|
||||
|
||||
### RLV-008 - CLI: `stella observations query`
|
||||
Status: TODO
|
||||
Dependency: RLV-005
|
||||
Owners: CLI Guild
|
||||
|
||||
Task description:
|
||||
Add CLI command to query historical runtime observations.
|
||||
|
||||
**Command spec:**
|
||||
```
|
||||
stella observations query [options]
|
||||
|
||||
Options:
|
||||
--symbol <name> Filter by symbol name (glob pattern)
|
||||
--node-hash <hash> Filter by exact node hash
|
||||
--container <id> Filter by container ID
|
||||
--pod <name> Filter by pod name
|
||||
--namespace <ns> Filter by Kubernetes namespace
|
||||
--probe-type <type> Filter by probe type (kprobe|uprobe|tracepoint|usdt)
|
||||
--from <timestamp> Start time (default: 1 hour ago)
|
||||
--to <timestamp> End time (default: now)
|
||||
--limit <n> Maximum results (default: 100)
|
||||
--format <json|table|csv> Output format (default: table)
|
||||
--summary Show summary statistics instead of individual observations
|
||||
|
||||
Examples:
|
||||
# Query all SSL_connect observations in last hour
|
||||
stella observations query --symbol "SSL_connect"
|
||||
|
||||
# Query by container
|
||||
stella observations query --container abc123 --from "2026-01-22T11:00:00Z"
|
||||
|
||||
# Get summary statistics
|
||||
stella observations query --symbol "SSL_*" --summary
|
||||
|
||||
# Export to CSV for analysis
|
||||
stella observations query --namespace production --format csv > observations.csv
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `stella observations query` command implemented
|
||||
- [ ] All filter options working
|
||||
- [ ] Summary statistics mode
|
||||
- [ ] CSV export for external analysis
|
||||
- [ ] CLI tests
|
||||
|
||||
---
|
||||
|
||||
### RLV-009 - Platform API: Function Map Endpoints
|
||||
Status: TODO
|
||||
Dependency: RLV-002, RLV-003
|
||||
Owners: Platform Guild
|
||||
|
||||
Task description:
|
||||
Expose function_map operations via Platform service REST API.
|
||||
|
||||
**Endpoints:**
|
||||
```
|
||||
POST /api/v1/function-maps Create/store function map
|
||||
GET /api/v1/function-maps List function maps
|
||||
GET /api/v1/function-maps/{id} Get function map by ID
|
||||
DELETE /api/v1/function-maps/{id} Delete function map
|
||||
|
||||
POST /api/v1/function-maps/{id}/verify Verify observations against map
|
||||
GET /api/v1/function-maps/{id}/coverage Get current coverage statistics
|
||||
```
|
||||
|
||||
**Request/Response contracts:**
|
||||
|
||||
`POST /api/v1/function-maps`:
|
||||
```json
|
||||
{
|
||||
"sbomRef": "oci://registry/app@sha256:...",
|
||||
"serviceName": "myservice",
|
||||
"hotFunctions": ["SSL_*", "EVP_*"],
|
||||
"options": {
|
||||
"minObservationRate": 0.95,
|
||||
"windowSeconds": 1800
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`POST /api/v1/function-maps/{id}/verify`:
|
||||
```json
|
||||
{
|
||||
"containerId": "abc123",
|
||||
"from": "2026-01-22T11:00:00Z",
|
||||
"to": "2026-01-22T12:00:00Z",
|
||||
"strict": false
|
||||
}
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"verified": true,
|
||||
"observationRate": 0.972,
|
||||
"targetRate": 0.95,
|
||||
"paths": [...],
|
||||
"unexpectedSymbols": [],
|
||||
"evidence": {
|
||||
"functionMapDigest": "sha256:...",
|
||||
"observationsDigest": "sha256:...",
|
||||
"verifiedAt": "2026-01-22T12:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] All endpoints implemented
|
||||
- [ ] OpenAPI spec generated
|
||||
- [ ] Tenant-scoped authorization
|
||||
- [ ] Integration tests
|
||||
- [ ] Rate limiting configured
|
||||
|
||||
---
|
||||
|
||||
### RLV-010 - UI: Function Map Management
|
||||
Status: TODO
|
||||
Dependency: RLV-009
|
||||
Owners: FE Guild
|
||||
|
||||
Task description:
|
||||
Add UI components for managing function maps and viewing verification results.
|
||||
|
||||
**Components:**
|
||||
|
||||
1. **Function Map List View** (`/settings/function-maps`)
|
||||
- Table showing all function maps for tenant
|
||||
- Columns: Service, Created, Last Verified, Coverage Status
|
||||
- Actions: View, Verify Now, Delete
|
||||
|
||||
2. **Function Map Detail View** (`/settings/function-maps/{id}`)
|
||||
- Service info and generation metadata
|
||||
- Expected paths table with symbols
|
||||
- Coverage thresholds configuration
|
||||
- Recent verification history
|
||||
|
||||
3. **Function Map Generator Wizard** (`/settings/function-maps/new`)
|
||||
- Step 1: Select SBOM source (file upload or OCI reference)
|
||||
- Step 2: Configure hot function patterns (with suggestions)
|
||||
- Step 3: Set coverage thresholds
|
||||
- Step 4: Review and create
|
||||
|
||||
4. **Verification Results Panel** (embedded in service detail)
|
||||
- Current verification status (verified/not verified)
|
||||
- Observation rate gauge with threshold indicator
|
||||
- Path coverage breakdown (expandable)
|
||||
- Unexpected symbols warning (if any)
|
||||
- Link to full verification report
|
||||
|
||||
5. **Observation Timeline** (`/services/{id}/observations`)
|
||||
- Time-series chart of observation counts
|
||||
- Filter by symbol/probe type
|
||||
- Drill-down to individual observations
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Function map list view
|
||||
- [ ] Function map detail view
|
||||
- [ ] Generator wizard
|
||||
- [ ] Verification results panel
|
||||
- [ ] Observation timeline chart
|
||||
- [ ] Responsive design
|
||||
- [ ] Loading states and error handling
|
||||
- [ ] E2E tests
|
||||
|
||||
---
|
||||
|
||||
### RLV-011 - Bundle Integration: function_map Artifact Type
|
||||
Status: TODO
|
||||
Dependency: RLV-001
|
||||
Owners: AirGap Guild
|
||||
|
||||
Task description:
|
||||
Add `function_map` as a supported artifact type in StellaBundle for offline verification.
|
||||
|
||||
**Implementation:**
|
||||
- Update `BundleArtifactType` enum to include `FunctionMap`
|
||||
- Update `BundleBuilder` to package function_map predicates
|
||||
- Update `BundleValidator` to validate function_map artifacts
|
||||
- Update `BundleVerifyCommand` to verify function_map signatures
|
||||
|
||||
**Bundle structure addition:**
|
||||
```
|
||||
bundle/
|
||||
├── manifest.json
|
||||
├── function-maps/
|
||||
│ └── myservice-function-map.json
|
||||
├── observations/
|
||||
│ └── observations-2026-01-22.ndjson
|
||||
└── verification/
|
||||
└── verification-report.dsse.json
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `FunctionMap` artifact type added
|
||||
- [ ] Bundle export includes function maps
|
||||
- [ ] Bundle verify validates function map signatures
|
||||
- [ ] Offline verification includes function map checking
|
||||
- [ ] Documentation updated
|
||||
|
||||
---
|
||||
|
||||
### RLV-012 - Documentation: Runtime Linkage Verification Guide
|
||||
Status: TODO
|
||||
Dependency: RLV-001 through RLV-011
|
||||
Owners: Documentation
|
||||
|
||||
Task description:
|
||||
Create comprehensive documentation for the runtime→static linkage verification feature.
|
||||
|
||||
**Documents to create/update:**
|
||||
|
||||
1. **New: `docs/modules/scanner/guides/runtime-linkage.md`**
|
||||
- What is runtime→static linkage verification?
|
||||
- When to use function maps
|
||||
- Step-by-step guide: generate → deploy probes → verify
|
||||
- Troubleshooting common issues
|
||||
|
||||
2. **New: `docs/contracts/function-map-v1.md`**
|
||||
- Predicate schema specification
|
||||
- Node hash and path hash recipes (reference witness-v1)
|
||||
- Coverage calculation algorithm
|
||||
- Verification algorithm
|
||||
|
||||
3. **Update: `docs/modules/cli/guides/commands/reference.md`**
|
||||
- Add `stella function-map` command group
|
||||
- Add `stella observations` command group
|
||||
|
||||
4. **Update: `docs/modules/airgap/guides/offline-bundle-format.md`**
|
||||
- Add function_map artifact type documentation
|
||||
|
||||
5. **New: `docs/runbooks/runtime-linkage-ops.md`**
|
||||
- Operational runbook for production deployment
|
||||
- Probe selection guidance
|
||||
- Performance tuning
|
||||
- Alert configuration
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Runtime linkage guide created
|
||||
- [ ] function_map contract documented
|
||||
- [ ] CLI reference updated
|
||||
- [ ] Bundle format docs updated
|
||||
- [ ] Operational runbook created
|
||||
|
||||
---
|
||||
|
||||
### RLV-013 - Acceptance Tests: 90-Day Pilot Criteria
|
||||
Status: TODO
|
||||
Dependency: All above tasks
|
||||
Owners: QA Guild
|
||||
|
||||
Task description:
|
||||
Implement acceptance tests matching the advisory's success criteria:
|
||||
|
||||
**Advisory acceptance criteria:**
|
||||
1. **Coverage:** ≥ 95% of calls to the 6 hot funcs are witnessed over a steady-state 30-min window
|
||||
2. **Integrity:** 100% DSSE sig verify + valid Rekor inclusion + valid TST
|
||||
3. **Replayability:** Offline verifier reproduces the same mapping on 3 separate air-gapped runs
|
||||
4. **Perf:** < 2% CPU overhead, < 50 MB RSS for collector under target load
|
||||
5. **Privacy:** No raw args; only hashes and minimal context
|
||||
|
||||
**Test implementation:**
|
||||
|
||||
1. **Coverage test:**
|
||||
- Generate function_map with 6 hot functions
|
||||
- Run load generator for 30 minutes
|
||||
- Verify observation rate ≥ 95%
|
||||
|
||||
2. **Integrity test:**
|
||||
- Generate function_map with signing
|
||||
- Create DSSE envelope
|
||||
- Post to Rekor
|
||||
- Add RFC-3161 timestamp
|
||||
- Verify all signatures and proofs
|
||||
|
||||
3. **Replayability test:**
|
||||
- Export StellaBundle with function_map + observations
|
||||
- Run offline verification 3 times in isolated environments
|
||||
- Assert identical results
|
||||
|
||||
4. **Performance test (if feasible in CI):**
|
||||
- Measure CPU overhead with/without probes
|
||||
- Measure collector memory usage
|
||||
- Assert within thresholds
|
||||
|
||||
5. **Privacy test:**
|
||||
- Inspect all observation payloads
|
||||
- Assert no raw arguments present
|
||||
- Assert only hashes and minimal context
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Coverage acceptance test
|
||||
- [ ] Integrity acceptance test
|
||||
- [ ] Replayability acceptance test (3 runs)
|
||||
- [ ] Performance benchmark (manual or CI)
|
||||
- [ ] Privacy audit test
|
||||
- [ ] All tests passing in CI
|
||||
|
||||
---
|
||||
|
||||
## Execution Log
|
||||
|
||||
| Date (UTC) | Update | Owner |
|
||||
|------------|--------|-------|
|
||||
| 2026-01-22 | Sprint created from eBPF witness advisory gap analysis | Planning |
|
||||
|
||||
---
|
||||
|
||||
## Decisions & Risks
|
||||
|
||||
### Decisions Made
|
||||
|
||||
1. **function_map as separate predicate** - Not extending witness-v1, cleaner separation of concerns
|
||||
2. **Reuse existing hash recipes** - NodeHash and PathHash from witness-v1 contract for consistency
|
||||
3. **Postgres for observation storage** - Leverages existing infrastructure, supports time-range queries
|
||||
4. **CLI-first verification** - Offline verification via CLI before UI for air-gap users
|
||||
|
||||
### Risks
|
||||
|
||||
1. **Observation volume** - High-traffic services may generate many observations
|
||||
- Mitigation: Configurable sampling, aggregation, retention policy
|
||||
|
||||
2. **Clock skew** - Distributed observations may have timestamp drift
|
||||
- Mitigation: Use server-side timestamps, configurable tolerance
|
||||
|
||||
3. **Symbol resolution accuracy** - Different runtimes have different symbol formats
|
||||
- Mitigation: Use node hashes (PURL + normalized symbol) for matching
|
||||
|
||||
4. **Performance impact of persistence** - Writing every observation could be costly
|
||||
- Mitigation: Batch writes, async persistence, sampling option
|
||||
|
||||
### Open Questions
|
||||
|
||||
1. Should function_map support version ranges for expected components, or exact versions only?
|
||||
2. Should we support "learning mode" that auto-generates function_map from observations?
|
||||
3. How to handle function maps for services with feature flags (conditional paths)?
|
||||
|
||||
---
|
||||
|
||||
## Next Checkpoints
|
||||
|
||||
- [ ] RLV-001 complete - Schema defined
|
||||
- [ ] RLV-002, RLV-003 complete - Core verification logic works
|
||||
- [ ] RLV-004 complete - Checkpoint signatures verified (trust chain complete)
|
||||
- [ ] RLV-005 complete - Observations persisted
|
||||
- [ ] RLV-006, RLV-007, RLV-008 complete - CLI fully functional
|
||||
- [ ] RLV-009, RLV-010 complete - API and UI ready
|
||||
- [ ] RLV-011 complete - Bundle integration for offline
|
||||
- [ ] RLV-012 complete - Documentation finalized
|
||||
- [ ] RLV-013 complete - Acceptance criteria met
|
||||
Reference in New Issue
Block a user