feat: Add UI benchmark driver and scenarios for graph interactions
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
- Introduced `ui_bench_driver.mjs` to read scenarios and fixture manifest, generating a deterministic run plan. - Created `ui_bench_plan.md` outlining the purpose, scope, and next steps for the benchmark. - Added `ui_bench_scenarios.json` containing various scenarios for graph UI interactions. - Implemented tests for CLI commands, ensuring bundle verification and telemetry defaults. - Developed schemas for orchestrator components, including replay manifests and event envelopes. - Added mock API for risk management, including listing and statistics functionalities. - Implemented models for risk profiles and query options to support the new API.
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
# DSSE‑Signed Offline Scanner Updates — Developer Guidelines
|
||||
|
||||
> **Date:** 2025-12-01
|
||||
> **Status:** Advisory draft (from user-provided guidance)
|
||||
> **Scope:** Offline vulnerability DB bundles (Scanner), DSSE+Rekor v2 verification, offline kit alignment, activation rules, ops playbook.
|
||||
|
||||
Here’s a tight, practical pattern to make your scanner’s vuln‑DB updates rock‑solid even when feeds hiccup:
|
||||
|
||||
## Offline, verifiable update bundles (DSSE + Rekor v2)
|
||||
|
||||
**Idea:** distribute DB updates as offline tarballs. Each tarball ships with:
|
||||
|
||||
* a **DSSE‑signed** statement (e.g., in‑toto style) over the bundle hash
|
||||
* a **Rekor v2 receipt** proving the signature/statement was logged
|
||||
* a small **manifest.json** (version, created_at, content hashes)
|
||||
|
||||
**Startup flow (happy path):**
|
||||
|
||||
1. Load latest tarball from your local `updates/` cache.
|
||||
2. Verify DSSE signature against your trusted public keys.
|
||||
3. Verify Rekor v2 receipt (inclusion proof) matches the DSSE payload hash.
|
||||
4. If both pass, unpack/activate; record the bundle’s **trust_id** (e.g., statement digest).
|
||||
5. If anything fails, **keep using the last good bundle**. No service disruption.
|
||||
|
||||
**Why this helps**
|
||||
|
||||
* **Air‑gap friendly:** no live network needed at activation time.
|
||||
* **Tamper‑evident:** DSSE + Rekor receipt proves provenance and transparency.
|
||||
* **Operational stability:** feed outages become non‑events—scanner just keeps the last good state.
|
||||
|
||||
---
|
||||
|
||||
## File layout inside each bundle
|
||||
|
||||
```
|
||||
/bundle-2025-11-29/
|
||||
manifest.json # { version, created_at, entries[], sha256s }
|
||||
payload.tar.zst # the actual DB/indices
|
||||
payload.tar.zst.sha256
|
||||
statement.dsse.json # DSSE-wrapped statement over payload hash
|
||||
rekor-receipt.json # Rekor v2 inclusion/verification material
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Acceptance/Activation rules
|
||||
|
||||
* **Trust root:** pin one (or more) publisher public keys; rotate via separate, out‑of‑band process.
|
||||
* **Monotonicity:** only activate if `manifest.version > current.version` (or if trust policy explicitly allows replay for rollback testing).
|
||||
* **Atomic switch:** unpack to `db/staging/`, validate, then symlink‑flip to `db/active/`.
|
||||
* **Quarantine on failure:** move bad bundles to `updates/quarantine/` with a reason code.
|
||||
|
||||
---
|
||||
|
||||
## Minimal .NET 10 verifier sketch (C#)
|
||||
|
||||
```csharp
|
||||
public sealed record BundlePaths(string Dir) {
|
||||
public string Manifest => Path.Combine(Dir, "manifest.json");
|
||||
public string Payload => Path.Combine(Dir, "payload.tar.zst");
|
||||
public string Dsse => Path.Combine(Dir, "statement.dsse.json");
|
||||
public string Receipt => Path.Combine(Dir, "rekor-receipt.json");
|
||||
}
|
||||
|
||||
public async Task<bool> ActivateBundleAsync(BundlePaths b, TrustConfig trust, string activeDir) {
|
||||
var manifest = await Manifest.LoadAsync(b.Manifest);
|
||||
if (!await Hashes.VerifyAsync(b.Payload, manifest.PayloadSha256)) return false;
|
||||
|
||||
// 1) DSSE verify (publisher keys pinned in trust)
|
||||
var (okSig, dssePayloadDigest) = await Dsse.VerifyAsync(b.Dsse, trust.PublisherKeys);
|
||||
if (!okSig || dssePayloadDigest != manifest.PayloadSha256) return false;
|
||||
|
||||
// 2) Rekor v2 receipt verify (inclusion + statement digest == dssePayloadDigest)
|
||||
if (!await RekorV2.VerifyReceiptAsync(b.Receipt, dssePayloadDigest, trust.RekorPub)) return false;
|
||||
|
||||
// 3) Stage, validate, then atomically flip
|
||||
var staging = Path.Combine(activeDir, "..", "staging");
|
||||
DirUtil.Empty(staging);
|
||||
await TarZstd.ExtractAsync(b.Payload, staging);
|
||||
if (!await LocalDbSelfCheck.RunAsync(staging)) return false;
|
||||
|
||||
SymlinkUtil.AtomicSwap(source: staging, target: activeDir);
|
||||
State.WriteLastGood(manifest.Version, dssePayloadDigest);
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Operational playbook
|
||||
|
||||
* **On boot & daily at HH:MM:** try `ActivateBundleAsync()` on the newest bundle; on failure, log and continue.
|
||||
* **Telemetry (no PII):** reason codes (SIG_FAIL, RECEIPT_FAIL, HASH_MISMATCH, SELFTEST_FAIL), versions, last_good.
|
||||
* **Keys & rotation:** keep `publisher.pub` and `rekor.pub` in a root‑owned, read‑only path; rotate via a separate signed “trust bundle”.
|
||||
* **Defense‑in‑depth:** verify both the **payload hash** and each file’s hash listed in `manifest.entries[]`.
|
||||
* **Rollback:** allow `--force-activate <bundle>` for emergency testing, but mark as **non‑monotonic** in state.
|
||||
|
||||
---
|
||||
|
||||
## What to hand your release team
|
||||
|
||||
* A Make/CI target that:
|
||||
1. Builds `payload.tar.zst` and computes hashes
|
||||
2. Generates `manifest.json`
|
||||
3. Creates and signs the **DSSE statement**
|
||||
4. Submits to Rekor (or your mirror) and saves the **v2 receipt**
|
||||
5. Packages the bundle folder and publishes to your offline repo
|
||||
* A checksum file (`*.sha256sum`) for ops to verify out‑of‑band.
|
||||
|
||||
---
|
||||
|
||||
If you want, I can turn this into a Stella Ops spec page (`docs/modules/scanner/offline-bundles.md`) plus a small reference implementation (C# library + CLI) that drops right into your Scanner service.
|
||||
|
||||
---
|
||||
|
||||
# Drop‑in Stella Ops Dev Guide (seed for `docs/modules/scanner/development/dsse-offline-updates.md`)
|
||||
|
||||
> **Audience**
|
||||
> Scanner, Export Center, Attestor, CLI, and DevOps engineers implementing DSSE‑signed offline vulnerability updates and integrating them into the Offline Update Kit (OUK).
|
||||
>
|
||||
> **Context**
|
||||
>
|
||||
> * OUK already ships **signed, atomic offline update bundles** with merged vulnerability feeds, container images, and an attested manifest.
|
||||
> * DSSE + Rekor is already used for **scan evidence** (SBOM attestations, Rekor proofs).
|
||||
> * Sprints 160/162 add **attestation bundles** with manifest, checksums, DSSE signature, and optional transparency log segments, and integrate them into OUK and CLI flows.
|
||||
|
||||
These guidelines tell you how to **wire all of that together** for “offline scanner updates” (feeds, rules, packs) in a way that matches Stella Ops’ determinism + sovereignty promises.
|
||||
|
||||
## 0. Mental model
|
||||
|
||||
```text
|
||||
Advisory mirrors / Feeds builders
|
||||
│
|
||||
▼
|
||||
ExportCenter.AttestationBundles
|
||||
(creates DSSE + Rekor evidence
|
||||
for each offline update snapshot)
|
||||
│
|
||||
▼
|
||||
Offline Update Kit (OUK) builder
|
||||
(adds feeds + evidence to kit tarball)
|
||||
│
|
||||
▼
|
||||
stella offline kit import / admin CLI
|
||||
(verifies Cosign + DSSE + Rekor segments,
|
||||
then atomically swaps scanner feeds)
|
||||
```
|
||||
|
||||
Online, Rekor is live; offline, you rely on **bundled Rekor segments / snapshots** and the existing OUK mechanics (import is atomic, old feeds kept until new bundle is fully verified).
|
||||
|
||||
## 1. Goals & non‑goals
|
||||
|
||||
### Goals
|
||||
|
||||
1. **Authentic offline snapshots**: every offline scanner update (OUK or delta) must be verifiably tied to a DSSE envelope, a certificate chain, and a Rekor v2 inclusion proof or bundled log segment.
|
||||
2. **Deterministic replay**: given a kit + its DSSE attestation bundle, every verifier reaches the same verdict online or air‑gapped.
|
||||
3. **Separation of concerns**: Export Center builds attestations; Scanner verifies/imports; Signer/Attestor handle DSSE/Rekor.
|
||||
4. **Operational safety**: imports remain atomic/idempotent; old feeds stay live until full verification.
|
||||
|
||||
### Non‑goals
|
||||
|
||||
* Designing new crypto or log formats.
|
||||
* Per‑feed DSSE envelopes (minimum contract is bundle‑level attestation).
|
||||
|
||||
## 2. Bundle contract for DSSE‑signed offline updates
|
||||
|
||||
**Files to ship** (inside each offline kit or delta):
|
||||
|
||||
```
|
||||
/attestations/
|
||||
offline-update.dsse.json # DSSE envelope
|
||||
offline-update.rekor.json # Rekor entry + inclusion proof (or segment descriptor)
|
||||
/manifest/
|
||||
offline-manifest.json # existing manifest
|
||||
offline-manifest.json.jws # existing detached JWS
|
||||
/feeds/
|
||||
... # existing feed payloads
|
||||
```
|
||||
|
||||
**DSSE payload (minimum):** subject = kit name + tarball sha256; predicate fields include `offline_manifest_sha256`, feed entries, builder ID/commit, created_at UTC, and channel.
|
||||
|
||||
**Rekor material:** submit DSSE to Rekor v2, store UUID/logIndex/inclusion proof as `offline-update.rekor.json`; for offline, embed a minimal log segment or rely on mirrored snapshots.
|
||||
|
||||
## 3. Implementation by module
|
||||
|
||||
### Export Center — attestation bundles
|
||||
* Compose attestation job: build DSSE payload, sign via Signer, submit to Rekor via Attestor, persist `offline-update.dsse.json` and `.rekor.json` (+ segments).
|
||||
* Integrate into offline kit packaging: place attestation files under `/attestations/`; list them in `offline-manifest.json` with sha256/size/capturedAt.
|
||||
* Define JSON schema for `offline-update.rekor.json`; version it and validate.
|
||||
|
||||
### Offline Update Kit builder
|
||||
* Preserve idempotent, atomic imports; include DSSE/Rekor files in kit staging tree.
|
||||
* Keep manifests deterministic: ordered file lists, UTC timestamps.
|
||||
* For delta kits, attest the resulting snapshot state (not just diffs).
|
||||
|
||||
### Scanner — import & activation
|
||||
* Verification sequence: Cosign tarball → manifest JWS → file digests (incl. attestation files) → DSSE verify → Rekor verify (online or offline segment) → atomic swap.
|
||||
* Config surface: `requireDsse`, `rekorOfflineMode`, `attestationVerifier` (env-var mirrored); allow observe→enforce rollout.
|
||||
* Failure behavior: keep old feeds; log structured failure fields; expose ProblemDetails.
|
||||
|
||||
### Signer & Attestor
|
||||
* Add predicate type/schema for offline updates; submit DSSE to Rekor; emit verification routines usable by CLI/Scanner with offline snapshot support.
|
||||
|
||||
### CLI & UI
|
||||
* CLI verbs to verify/import bundles with Rekor key; UI shows Cosign/JWS + DSSE/Rekor status and kit freshness.
|
||||
|
||||
## 4. Determinism & offline‑safety rules
|
||||
* No hidden network dependencies; offline must succeed with kit + Rekor snapshot.
|
||||
* Stable JSON serialization; UTC timestamps.
|
||||
* Replayable imports (idempotent); DSSE payload for a snapshot must be immutable.
|
||||
* Explainable failures with precise mismatch points.
|
||||
|
||||
## 5. Testing & CI expectations
|
||||
* Unit/integration: happy path, tampering cases (manifest/DSSE/Rekor), offline mode, rollback logic.
|
||||
* Metrics: `offlinekit_import_total{status}`, `attestation_verify_latency_seconds`, Rekor success/retry counts.
|
||||
* Golden fixtures: deterministic bundle + snapshot tests.
|
||||
|
||||
## 6. Developer checklist (TL;DR)
|
||||
1. Read operator guides: `docs/modules/scanner/operations/dsse-rekor-operator-guide.md`, `docs/24_OFFLINE_KIT.md`, relevant sprints.
|
||||
2. Implement: generate DSSE in Export Center; include attestation in kit; Scanner verifies before swap.
|
||||
3. Test: bundle composition, import rollback, determinism.
|
||||
4. Telemetry: counters + latency; log digests/UUIDs.
|
||||
5. Document: update Export Center and Scanner architecture docs, OUK docs when flows/contracts change.
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
# Proof-Linked VEX UI Developer Guidelines
|
||||
|
||||
Compiled: 2025-12-01 (UTC)
|
||||
|
||||
## Purpose
|
||||
Any VEX-influenced verdict a user sees (Findings, Advisories & VEX, Vuln Explorer, etc.) must be directly traceable to concrete evidence: normalized VEX claims, their DSSE/signatures, and the policy explain trace. Every "Not Affected" badge is a verifiable link to the proof.
|
||||
|
||||
## What this solves (in one line)
|
||||
Every "Not Affected" badge becomes a verifiable link to why it is safe.
|
||||
|
||||
## UX pattern (at a glance)
|
||||
- Badge: `Not Affected` (green pill) always renders as a link.
|
||||
- On click: open a right-side drawer with three tabs:
|
||||
1. Evidence (DSSE / in-toto / Sigstore)
|
||||
2. Attestation (predicate details + signer)
|
||||
3. Reasoning Graph (the node + edges that justify the verdict)
|
||||
- Hover state: mini popover showing proof types available (e.g., "DSSE, SLSA attestation, Graph node").
|
||||
|
||||
## Data model (API & DB)
|
||||
Canonical object returned by VEX API for each finding:
|
||||
|
||||
```json
|
||||
{
|
||||
"findingId": "vuln:CVE-2024-12345@pkg:docker/alpine@3.19",
|
||||
"status": "not_affected",
|
||||
"justificationCode": "vex:not_present",
|
||||
"proof": {
|
||||
"dsse": {
|
||||
"envelopeDigest": "sha256-…",
|
||||
"rekorEntryId": "e3f1…",
|
||||
"downloadUrl": "https://…/dsse/e3f1…",
|
||||
"signer": { "name": "StellaOps Authority", "keyId": "SHA256:…" }
|
||||
},
|
||||
"attestation": {
|
||||
"predicateType": "slsa/v1",
|
||||
"attestationId": "att:01H…",
|
||||
"downloadUrl": "https://…/att/01H…"
|
||||
},
|
||||
"graph": {
|
||||
"nodeId": "gx:NA-78f…",
|
||||
"revision": "gx-r:2025-11-30T12:01:22Z",
|
||||
"explainUrl": "https://…/graph?rev=gx-r:…&node=NA-78f…"
|
||||
}
|
||||
},
|
||||
"receipt": {
|
||||
"algorithm": "CVSS:4.0",
|
||||
"inputsHash": "sha256-…",
|
||||
"computedAt": "2025-11-30T12:01:22Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Suggested Postgres tables:
|
||||
- vex_findings(finding_id, status, justification_code, graph_node_id, graph_rev, dsse_digest, rekor_id, attestation_id, created_at, updated_at)
|
||||
- proof_artifacts(id, type, digest, url, signer_keyid, meta jsonb)
|
||||
- graph_revisions(revision_id, created_at, root_hash)
|
||||
|
||||
## API contract (minimal)
|
||||
- GET /vex/findings/:id -> returns the object above.
|
||||
- GET /proofs/:type/:id -> streams artifact (with Content-Disposition: attachment).
|
||||
- GET /graph/explain?rev=…&node=… -> returns a JSON justification subgraph.
|
||||
- Security headers: Content-SHA256, Digest, X-Proof-Root (graph root hash), and X-Signer-KeyId.
|
||||
|
||||
## Angular UI spec (drop-in)
|
||||
Component: FindingStatusBadge
|
||||
|
||||
```html
|
||||
<button class="badge badge--ok" (click)="drawer.open(finding.proof)">
|
||||
Not Affected
|
||||
</button>
|
||||
```
|
||||
|
||||
Drawer layout (3 tabs):
|
||||
1) Evidence
|
||||
- DSSE digest (copy button)
|
||||
- Rekor entry (open in new tab)
|
||||
- "Download envelope"
|
||||
2) Attestation
|
||||
- Predicate type
|
||||
- Attestation ID
|
||||
- "Download attestation"
|
||||
3) Reasoning Graph
|
||||
- Node ID + Revision
|
||||
- Inline explainer ("Why safe?" bullets)
|
||||
- "Open full graph" (routes to /graph?rev=…&node=…)
|
||||
|
||||
Micro-interactions:
|
||||
- Copy-to-clipboard with toast ("Digest copied").
|
||||
- If any artifact missing, show a yellow "Partial Proof" ribbon listing what is absent.
|
||||
|
||||
Visual language:
|
||||
- Badges: Not Affected = solid green; Partial Proof = olive with warning dot; No Proof = gray outline (still clickable, explains absence).
|
||||
- Proof chips: small caps labels `DSSE`, `ATTESTATION`, `GRAPH`; each chip opens its subsection.
|
||||
|
||||
Validation (trust & integrity):
|
||||
- On drawer open, the UI calls HEAD /proofs/... to fetch Digest header and X-Proof-Root; compare to stored digests. If mismatch, show red "Integrity Mismatch" banner with retry and report.
|
||||
|
||||
Telemetry (debugging):
|
||||
- Emit events: proof_drawer_opened, proof_artifact_downloaded, graph_explain_viewed (include findingId, artifactType, latencyMs, integrityStatus).
|
||||
|
||||
Developer checklist:
|
||||
- Every not_affected status must include at least one proof artifact.
|
||||
- Badge is never a dead label; always clickable.
|
||||
- Drawer validates artifact digests before rendering contents.
|
||||
- "Open full graph" deep-links with rev + node (stable and shareable).
|
||||
- Graceful partials: show what is present and what is missing.
|
||||
- Accessibility: focus trap in drawer, aria-labels for chips, keyboard nav.
|
||||
|
||||
Test cases (quick):
|
||||
1) Happy path: all three proofs present; digests match; downloads work.
|
||||
2) Partial proof: DSSE present, attestation missing; drawer shows warning ribbon.
|
||||
3) Integrity fail: server returns different digest; red banner appears; badge stays clickable.
|
||||
4) Graph only: reasoning node present; DSSE/attestation absent; explains rationale clearly.
|
||||
|
||||
Optional nice-to-haves:
|
||||
- Permalinks: copyable URL that re-opens the drawer to the same tab.
|
||||
- QR export: downloadable "proof card" PNG with digests + signer (for audit packets).
|
||||
- Offline kit: bundle DSSE, attestation, and a compact graph slice in a .tar.zst for air-gapped review.
|
||||
|
||||
If needed, this can be turned into:
|
||||
- A small Angular module (ProofDrawerModule) + styles.
|
||||
- A .NET 10 controller stub with integrity headers.
|
||||
- Fixture JSON so teams can wire it up quickly.
|
||||
|
||||
## Context links (from source conversation)
|
||||
- docs/ui/console-overview.md
|
||||
- docs/ui/advisories-and-vex.md
|
||||
- docs/ui/findings.md
|
||||
- src/VexLens/StellaOps.VexLens/AGENTS.md and TASKS.md
|
||||
- docs/policy/overview.md
|
||||
@@ -0,0 +1,95 @@
|
||||
# 01-Dec-2025 - Storage Blueprint for PostgreSQL Modules
|
||||
|
||||
## Summary
|
||||
A crisp, opinionated storage blueprint for StellaOps modules with zero-downtime conversion tactics. Covers module-to-store mapping, PostgreSQL patterns, JSONB/RLS scaffolds, materialized views, temporal tables, CAS usage for SBOM/VEX blobs, and phased cutover guidance.
|
||||
|
||||
## Module → Store Map (deterministic by default)
|
||||
- **Authority / OAuth / Accounts & Audit**: PostgreSQL source of truth; tables `users`, `clients`, `oauth_tokens`, `roles`, `grants`, `audit_log`; RLS on `users`, `grants`, `audit_log`; strict FK/CHECK; immutable UUID PKs; audit table with actor/action/entity/diff and timestamptz default now().
|
||||
- **VEX & Vulnerability Writes**: PostgreSQL with JSONB facts plus relational decisions; tables `vuln_fact(jsonb)`, `vex_decision(package_id, vuln_id, status, rationale, proof_ref, updated_at)`; materialized views like `mv_triage_hotset` refreshed on commit or schedule.
|
||||
- **Routing / Feature Flags / Rate-limits**: PostgreSQL truth plus Redis cache; tables `feature_flag(key, rules jsonb, version)`, `route(domain, service, instance_id, last_heartbeat)`, `rate_limiter(bucket, quota, interval)`; Redis keys `flag:{key}:{version}`, `route:{domain}`, `rl:{bucket}` with short TTLs.
|
||||
- **Unknowns Registry**: PostgreSQL with temporal tables (bitemporal via `valid_from/valid_to`, `sys_from/ sys_to`); view `unknowns_current` for open rows.
|
||||
- **Artifacts / SBOM / VEX files**: OCI-compatible CAS (e.g., self-hosted registry or MinIO) keyed by digest; metadata in Postgres `artifact_index(digest, media_type, size, signatures)`.
|
||||
|
||||
## PostgreSQL Implementation Essentials
|
||||
- **RLS scaffold (Authority)**
|
||||
```sql
|
||||
alter table audit_log enable row level security;
|
||||
create policy p_audit_read_self
|
||||
on audit_log for select
|
||||
using (
|
||||
actor_id = current_setting('app.user_id')::uuid
|
||||
or exists (
|
||||
select 1 from grants g
|
||||
where g.user_id = current_setting('app.user_id')::uuid
|
||||
and g.role = 'auditor'
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
- **JSONB facts + relational decisions**
|
||||
```sql
|
||||
create table vuln_fact (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
source text not null,
|
||||
payload jsonb not null,
|
||||
received_at timestamptz default now()
|
||||
);
|
||||
|
||||
create table vex_decision (
|
||||
package_id uuid not null,
|
||||
vuln_id text not null,
|
||||
status text check (status in ('not_affected','affected','fixed','under_investigation')),
|
||||
rationale text,
|
||||
proof_ref text,
|
||||
decided_at timestamptz default now(),
|
||||
primary key (package_id, vuln_id)
|
||||
);
|
||||
```
|
||||
|
||||
- **Materialized view for triage**
|
||||
```sql
|
||||
create materialized view mv_triage_hotset as
|
||||
select v.id as fact_id, v.payload->>'vuln' as vuln, v.received_at
|
||||
from vuln_fact v
|
||||
where (now() - v.received_at) < interval '7 days';
|
||||
-- refresh concurrently via job
|
||||
```
|
||||
|
||||
- **Temporal pattern (Unknowns)**
|
||||
```sql
|
||||
create table unknowns (
|
||||
id uuid primary key default gen_random_uuid(),
|
||||
subject_hash text not null,
|
||||
kind text not null,
|
||||
context jsonb not null,
|
||||
valid_from timestamptz not null default now(),
|
||||
valid_to timestamptz,
|
||||
sys_from timestamptz not null default now(),
|
||||
sys_to timestamptz
|
||||
);
|
||||
|
||||
create view unknowns_current as
|
||||
select * from unknowns where valid_to is null;
|
||||
```
|
||||
|
||||
## Conversion (not migration): zero-downtime, prototype-friendly
|
||||
1. Encode Mongo-shaped docs into JSONB with versioned schemas and forward-compatible projection views.
|
||||
2. Outbox pattern for exactly-once side-effects (`outbox(id, topic, key, payload jsonb, created_at, dispatched bool default false)`).
|
||||
3. Parallel read adapters behind feature flags with read-diff monitoring.
|
||||
4. CDC for analytics without coupling (logical replication).
|
||||
5. Materialized views with fixed refresh cadence; cold-path analytics in separate schemas.
|
||||
6. Phased cutover playbook: Dark Read → Shadow Serve → Authoritative → Retire (with auto-rollback).
|
||||
|
||||
## Rate-limits & Flags: single truth, fast edges
|
||||
- Truth in Postgres with versioned flag docs; history table for changes; Redis edge cache keyed by version; rate-limit quotas in Postgres, counters in Redis with reconciliation jobs.
|
||||
|
||||
## CAS for SBOM/VEX/attestations
|
||||
- Store blobs in OCI/MinIO by digest; keep pointer metadata in Postgres `artifact_index`; benefits: immutability, dedup, easy offline mirroring.
|
||||
|
||||
## Guardrails
|
||||
- Wrap multi-table writes in single transactions; prefer `jsonb_path_query` for targeted reads; enforce RLS and least-privilege roles; version everything (schemas, flags, materialized views); expose observability for statements, MV refresh latency, outbox lag, Redis hit ratio, and RLS hits.
|
||||
|
||||
## Optional Next Steps (from advisory)
|
||||
- Generate ready-to-run EF Core 10 migrations.
|
||||
- Add `/docs/architecture/store-map.md` summarizing these patterns.
|
||||
- Provide a small Docker-based dev seed with sample data.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Verifiable Proof Spine: Receipts + Benchmarks
|
||||
|
||||
Compiled: 2025-12-01 (UTC)
|
||||
|
||||
## Why this matters
|
||||
Move from “trust the scanner” to “prove every verdict.” Each finding and every “not affected” claim must carry cryptographic, replayable evidence that anyone can verify offline or online.
|
||||
|
||||
## Differentiators to build in
|
||||
- **Graph Revision ID on every verdict**: stable Merkle root over SBOM nodes/edges, policies, feeds, scan params, and tool versions. Any data change → new graph hash → new revisioned verdicts; surface the ID in UI/API.
|
||||
- **Machine-verifiable receipts (DSSE)**: emit a DSSE-wrapped in-toto statement per verdict (predicate `stellaops.dev/verdict@v1`) including graphRevisionId, artifact digests, rule id/version, inputs, and timestamps; sign with Authority keys (offline mode supported) and keep receipts queryable/exportable; mirror to Rekor-compatible ledger when online.
|
||||
- **Reachability evidence**: attach call-stack slices (entry→sink, symbols, file:line) for code-level cases; for binaries, include symbol presence proofs (bitmap/offsets) hashed and referenced from DSSE payloads.
|
||||
- **Deterministic replay manifests**: publish `replay.manifest.json` with inputs, feeds, rule/tool/container digests so auditors can recompute the same graph hash and verdicts offline.
|
||||
|
||||
## Benchmarks to publish (headline KPIs)
|
||||
- **False-positive reduction vs baseline scanners**: run public corpus across 3–4 popular scanners; label ground truth once; report mean and p95 FP reduction.
|
||||
- **Proof coverage**: percentage of findings/VEX items carrying valid DSSE receipts; break out reachable vs unreachable and “not affected.”
|
||||
- **Triage time saved**: analyst minutes from alert to final disposition with receipts visible vs hidden; publish p50/p95 deltas.
|
||||
- **Determinism stability**: re-run identical scans across nodes; publish % identical graph hashes and explain drift causes when different.
|
||||
|
||||
## Minimal implementation plan (week-by-week)
|
||||
- **Week 1 – Primitives**: add Graph Revision ID generator in scanner.webservice (Merkle over normalized SBOM+edges+policies+toolVersions); define `VerdictReceipt` schema (protobuf/JSON) and DSSE envelope types.
|
||||
- **Week 2 – Signing + storage**: wire DSSE signing via Authority with offline key support/rotation; persist receipts in `Receipts` table keyed by (graphRevisionId, verdictId); enable JSONL export and ledger mirror.
|
||||
- **Week 3 – Reachability proofs**: capture call-stack slices in reachability engine; serialize and hash; add binary symbol proof module (ELF/PE bitmap + digest) and reference from receipts.
|
||||
- **Week 4 – Replay + UX**: emit replay.manifest per scan (inputs, tool digests); UI shows “Verified” badge, graph hash, signature issuer, and one-click “Copy receipt”; API: `GET /verdicts/{id}/receipt`, `GET /graphs/{rev}/replay`.
|
||||
- **Week 5 – Benchmarks harness**: create `bench/` fixtures and runner with baseline scanner adapters, ground-truth labels, metrics export for FP%, proof coverage, triage time capture hooks.
|
||||
|
||||
## Developer guardrails (non-negotiable)
|
||||
- **No receipt, no ship**: any surfaced verdict must carry a DSSE receipt; fail closed otherwise.
|
||||
- **Schema freeze windows**: changes to rule inputs or policy logic must bump rule version and therefore graph hash.
|
||||
- **Replay-first CI**: PRs touching scanning/rules must pass a replay test that reproduces prior graph hashes on gold fixtures.
|
||||
- **Clock safety**: use monotonic time for receipts; include UTC wall-time separately.
|
||||
|
||||
## What to show buyers/auditors
|
||||
- Audit kit: sample container + receipts + replay manifest + one command to reproduce the same graph hash.
|
||||
- One-page benchmark readout: FP reduction, proof coverage, triage time saved (p50/p95), corpus description.
|
||||
|
||||
## Optional follow-ons
|
||||
- Provide DSSE predicate schema, Postgres DDL for `Receipts` and `Graphs`, and a minimal .NET verification CLI (`stellaops-verify`) that replays a manifest and validates signatures.
|
||||
@@ -31,7 +31,7 @@
|
||||
- Freeze baseline rulepacks/DBs and publish digests.
|
||||
- Document sandbox and submission attestation requirements in the submission guide and CI policy.
|
||||
|
||||
# Findings – Gaps in “Add CVSS v4.0 Score Receipts for Transparency”
|
||||
# Findings – Gaps in “Add CVSS v4.0 Score Receipts for Transparency”
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
|
||||
@@ -550,6 +550,325 @@
|
||||
- Add a ledger gaps task to a relevant sprint (e.g., reachability/policy ledger work or EvidenceLocker/export coordination) to close FL1–FL10.
|
||||
- Publish versioned schemas and canonical serialization; mandate Merkle/external anchor policy with freshness; enforce tenant/redaction rules; require DSSE/policy linkage; add golden fixtures, replay/rebuild verifiers, air-gap verify scripts, and quotas/backpressure.
|
||||
|
||||
# Findings – Gaps in “DSSE‑Signed Offline Scanner Updates — Developer Guidelines”
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
|
||||
**Compiled:** 2025-12-01 (UTC)
|
||||
|
||||
**Source reviewed:** User-provided advisory “DSSE‑Signed Offline Scanner Updates — Developer Guidelines” (not yet in repo); cross-checked against `docs/24_OFFLINE_KIT.md`, `docs/modules/scanner/operations/dsse-rekor-operator-guide.md`, and sprints 160/162 attestation work.
|
||||
|
||||
**Method:** Evaluated the proposed offline bundle pattern (DSSE envelope + Rekor v2 receipt + manifest + payload) and activation flow against existing offline-kit, scanner import, attestation, and determinism/air-gap requirements. Identified missing controls, governance, and telemetry required to make the pattern enforceable and replayable.
|
||||
|
||||
## Gap Table
|
||||
| ID | Area | Gap | Impact | Recommendation |
|
||||
| -- | ---- | --- | ------ | -------------- |
|
||||
| DS1 | Trust bundle rotation & revocation | Advisory pins publisher/rekor keys but omits rotation channel, expiry/NotAfter checks, or revocation response (key compromise, revoked cert, mirror drift). | Stale or compromised keys could continue to sign/verify bundles; rollback to bad keys possible in air-gaps. | Define signed “trust bundle” schema with key set, expiry, revocation list, and provenance; enforce NotBefore/NotAfter on activation; require quorum/M-of-N to rotate keys and store rotation receipts alongside bundles. |
|
||||
| DS2 | Rekor freshness & offline proof | Verification only checks receipt vs DSSE hash; no requirement to validate the Rekor checkpoint/root, inclusion promise window, or bundled log segment authenticity. | Attackers can replay old receipts or splice receipts from another tree; air-gapped sites may trust stale proofs. | Require checkpoint verification (root hash, size, log ID) and freshness bound; when offline, bundle signed log segment + checkpoint DSSE; fail closed if segment/hash mismatches. |
|
||||
| DS3 | Manifest/schema canonicalization | `manifest.json` shape/version/canonical rules are undefined; hash algo/encoding not fixed; no schema signature. | Producers/consumers may compute different digests → false negatives/acceptance of tampered bundles. | Publish versioned JSON Schema with canonical ordering, SHA-256 as default, strict types; sign manifest with DSSE/JWS and include schema version in filename and trust_id. |
|
||||
| DS4 | Supply-chain provenance for bundle build | Build pipeline steps (hashing, signing, Rekor submission) lack attestation/SLSA provenance; no binding to source commit, tool versions, or build runner hash. | Malicious/compromised build host could emit validly signed but malicious payloads; hard to audit. | Produce SLSA/DSSE build attestation for each bundle (builder ID, git commit, tool versions, reproducible build inputs); verify attestation before accepting bundle into cache. |
|
||||
| DS5 | Anti-replay & rollback detection | Monotonicity check uses manifest.version but no binding to prior trust state or recorded trust_id; no replay window/nonce; force-activate bypass not audited. | Old bundles can be reintroduced (malicious or operator error); rollback may go unnoticed in air-gaps. | Persist last_good {version, trust_id, rekor_root} in append-only state; require version strictly increasing unless signed rollback exception; log and DSSE-sign every activation/force-activation event. |
|
||||
| DS6 | Delta/partial bundle rules | Contract only shown for full bundles; deltas/partials not defined (expected final state, base hash, tombstones). | Deltas may apply on wrong base, producing diverging DB contents without detection. | Define delta schema: base_version/base_hash, operations (add/remove/replace), resulting snapshot hash; verify base before apply; generate synthetic full-hash after apply and compare to declared target. |
|
||||
| DS7 | Per-file integrity & compression safety | Defense-in-depth note mentions file hashes but not mandatory verification of each entry inside `payload.tar.zst`, compression flags, or TOCTOU protection when extracting. | Tampering inside tar/zst could slip through if only outer hash is checked; extraction could overwrite symlinks or traverse directories. | Require per-entry hashes in manifest, validated before extraction; use safe extractor that rejects symlinks/`..` paths and enforces uid/gid/perm allowlist; verify zstd dictionary/levels; hash post-extract contents before swap. |
|
||||
| DS8 | Config/feature flags & policy surface | `requireDsse`-style enforcement hinted but not specified across Scanner, CLI, Worker; no migration plan or policy gate. | Mixed deployments may silently skip DSSE/Rekor checks or drift from policy; inconsistent enforcement. | Add explicit config matrix (API/UI/CLI) with default `requireDsse=true`, rollout guard (`observe→enforce`), and policy gate that blocks imports lacking DSSE/Rekor unless override is signed and time-bound. |
|
||||
| DS9 | Observability & SLOs | Telemetry suggests reason codes but no SLOs, alerts, or metrics for freshness, failure streaks, rollback attempts, or trust-bundle age. | Operators lack visibility; silent drift or repeated failures may persist. | Define metrics (`bundle_activate_total{reason}`, `rekor_freshness_seconds`, `trust_bundle_age_hours`, `rollback_attempt_total`), alerts on stale checkpoint/keys or repeated failures, and trace spans around verify steps; document SLOs. |
|
||||
| DS10 | Recovery & quarantine governance | Quarantine step lacks retention period, evidence capture, or reprocessing flow; no checklist for operator actions or RCA evidence. | Quarantined bundles may be reintroduced without fix; root causes lost. | Require quarantine manifest (bundle hash, failure reason, logs, time, operator); set retention/SLA; add `reanalyze` job that re-verifies after trust-bundle/rekor updates; document runbook. |
|
||||
| DS11 | Multi-tenant/namespace scoping | Advisory assumes single trust root/cache; no scoping for multi-tenant or env-specific feeds (prod/stage/regional crypto profiles). | Wrong bundles could be activated in other tenants/regions; policy/cert profile mismatches. | Partition cache and trust state by tenant/env/crypto profile; include tenant/profile in DSSE predicate and activation state; block activation on mismatch. |
|
||||
| DS12 | Offline-kit parity & kit manifest linkage | Bundle layout is local-only; not bound to existing Offline Kit manifest/attestations; no guidance for importing via OUK or Export Center bundles. | Duplicate verification logic; kit imports may skip DSSE/Rekor or mismatch manifest coverage. | Align bundle schema with OUK: include pointers into offline-kit manifest, ensure kit contains DSSE/Rekor files, and require Scanner import to treat them as mandatory; add shared schema/docs. |
|
||||
|
||||
## Immediate follow-ups
|
||||
- Add a gaps-remediation task to the relevant attestation/offline sprints (e.g., `SPRINT_0162_0001_0001_exportcenter_i`, `SPRINT_0163_0001_0001_exportcenter_ii`, `SPRINT_0510_0001_0001_airgap`, or Scanner import sprint) covering DS1–DS12.
|
||||
- Draft and publish versioned schemas for bundle manifest, delta bundles, trust bundle, and Rekor segment packaging; include canonicalization rules and test vectors.
|
||||
- Extend offline-kit and Scanner import docs to mandate DSSE/Rekor checkpoint verification, per-entry hashing, safe extraction, append-only state, and tenant/profile scoping; wire metrics/alerts into observability docs.
|
||||
- Add CI/fixtures: reproducible bundle build attestation, delta/base mismatch tests, rollback/replay tests, stale checkpoint/key tests, and quarantine reprocessing tests.
|
||||
|
||||
# Findings – Gaps in “StellaOps Storage Blueprint (PostgreSQL patterns per module)”
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
|
||||
**Compiled:** 2025-12-01 (UTC)
|
||||
|
||||
**Source reviewed:** Pasted advisory “Here’s a crisp, opinionated storage blueprint…” / “StellaOps – PostgreSQL Patterns per Module” (2025-12-01 draft).
|
||||
|
||||
**Method:** Reviewed the blueprint against module dossiers (Authority, Routing, VEX, Unknowns, Artifact), high-level architecture, and prior advisories on ledger/evidence/offline posture to identify missing guarantees, hardening steps, and operability gaps.
|
||||
|
||||
## Gap Table
|
||||
| ID | Area | Gap | Impact | Recommendation |
|
||||
| -- | ---- | --- | ------ | -------------- |
|
||||
| SB1 | Tenant isolation | DDL examples mostly omit `tenant_id` and tenant-based RLS; policies rely only on `app.user_id`. | Cross-tenant data exposure or cache bleed; feature flags/routing/unknowns not tenant-safe. | Make `tenant_id uuid not null` mandatory on tenant-scoped tables, enforce base RLS `tenant_id = current_setting('app.tenant_id')::uuid`, and add partial indexes by tenant. |
|
||||
| SB2 | RLS hardening | Blueprint assumes `set_config` but lacks guards for unset/invalid session vars, role separation, or `SECURITY DEFINER` safety. | Mis-set sessions bypass RLS; superuser paths may leak data. | Add `check_app_context()` function used in policies, deny access when settings missing, separate DB roles per service, and forbid bypass for `pg_read_all_data`. |
|
||||
| SB3 | Partitioning & retention | High-volume tables (audit_log, oauth_token, outbox, unknowns history) not partitioned; no retention/archival plan. | Storage bloat, slow scans, expensive VACUUM; audit trails hard to manage. | Time/tenant partition heavy tables; enforce retention/archival to CAS; add `DROP PARTITION`/`vacuumd` runbooks and metrics. |
|
||||
| SB4 | Indexing & query plans | Several hot-path queries lack indexes (e.g., `feature_flag(key, version)`, `audit_log(actor_id, at)`, GIN on JSONB facts/unknowns, partial indexes on open unknowns). | Latency spikes and table scans; MV refreshes slow. | Specify required indexes per table and refresh cadence; add `EXPLAIN` baselines in migrations/tests. |
|
||||
| SB5 | HA/DR & PITR | No posture for replication, failover, backups, or PITR testing. | Data loss/outage risk; compliance gaps. | Standardize HA (streaming replica) with async/sync policy per module, scheduled base/backups + PITR drills, and recovery SLOs documented. |
|
||||
| SB6 | Migration/dual-write plan | Cutover phases describe read adapters but omit dual-write/backfill, consistency checks, and abort criteria. | Divergence between Mongo and Postgres; hard rollback. | Add dual-write phase with idempotent keys, reconciliation jobs, hash-based diff reports, and automated rollback switch; document stop conditions. |
|
||||
| SB7 | Schema governance | `schema_version` fields exist but no schema registry, compatibility rules, or SemVer/change-log requirements. | Breaking changes may ship unnoticed; clients can’t validate payloads. | Create schema catalog with SemVer and DSSE signatures; enforce compatibility checks in CI and at runtime; require migration playbooks per version bump. |
|
||||
| SB8 | CDC security & scoping | Logical replication recommended without tenant filtering, column-level exclusions, or connector isolation. | Sensitive data may leak to analytics/third parties; multi-tenant isolation broken. | Use publication per module/tenant, exclude secret columns, TLS/auth for connectors, and add redaction/field allowlists plus monitoring for lag/divergence. |
|
||||
| SB9 | Outbox robustness | Outbox table lacks idempotency keys, ordering/fencing rules, poison-message handling, and backpressure metrics. | Duplicate or lost events; dispatcher loops under load. | Add `(aggregate_type, aggregate_id, topic, created_at)` unique key, status enum, retry/backoff policy, dead-letter bucket, and observability counters; keep dispatcher transactional. |
|
||||
| SB10 | Cache governance (Redis) | Cache keys/TTLs noted but no tenant/env namespacing, warm/cold coherence rules, or fail-closed behavior. | Cross-tenant bleed or stale flags/routes; silent fallback to outdated cache. | Namespaces (`env:tenant:` prefixes), include version in keys, require cache-miss fallback to Postgres with freshness checks, and metrics/alerts on hit ratio + staleness. |
|
||||
| SB11 | Artifact index & CAS hygiene | CAS index lacks GC policy, tag/alias governance, encryption/ACL guidance, or tenant-scoped storage paths; signatures optional. | Digest store grows unbounded; cross-tenant leakage via shared blobs; unverifiable artifacts. | Add GC rules (refcount/last-access), tenant-scoped buckets/prefixes, mandatory signature refs, encryption at rest + access policy, and offline mirror/verify scripts. |
|
||||
| SB12 | Observability & SLOs | Metrics mentioned but no SLOs/alerts for MV lag, replication lag, RLS policy hits, outbox lag, refresh failures, or Redis divergence. | Operational drift undetected; regressions hit users before detection. | Define per-module SLOs and alerting; ship dashboards; add self-test queries in readiness probes; fail-fast on MV refresh/CDC gaps. |
|
||||
| SB13 | Security & compliance | No explicit at-rest/transport encryption, audit of DDL/config changes, or data-classification/PII rules for JSONB payloads. | Compliance risk; uncontrolled sensitive data storage. | Enforce TLS, TDE/disk encryption, pgaudit/DDL logging, classified columns with masking/redaction, and PII allowlists plus periodic scans. |
|
||||
|
||||
## Immediate follow-ups
|
||||
- Open a sprint task (e.g., under data/platform hardening) to close SB1–SB13 with owners/dates and link to this finding.
|
||||
- Produce migration/dual-write and partitioning runbooks per module; add schema catalog (versioned, signed) and required indexes to migrations.
|
||||
- Define HA/DR posture, CDC scoping rules, cache namespacing, artifact GC/ACL policy, and observability SLOs; wire alerts and self-tests into services.
|
||||
|
||||
# Findings – Gaps in “Verifiable Proof Spine → Moat (receipts + benchmarks)”
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
|
||||
**Compiled:** 2025-12-01 (UTC)
|
||||
|
||||
**Source reviewed:** “Here’s a crisp, practical way to turn Stella Ops’ ‘verifiable proof spine’ into a moat—and how to measure it.” (includes “Developer Guidelines – Benchmarks for a Testable Security Moat”).
|
||||
|
||||
**Method:** Read the advisory and attached developer guidelines; compared with related advisories already filed (Graph Revision IDs as Public Trust Anchors, Evidence Bundle and Replay Contracts, Reachability Benchmark Fixtures Snapshot, Comparative Evidence Patterns) and the current `bench/` layout to surface missing contracts, controls, and enforcement hooks.
|
||||
|
||||
## Gap Table
|
||||
| ID | Area | Gap | Impact | Recommendation |
|
||||
| -- | ---- | --- | ------ | -------------- |
|
||||
| VM1 | Graph Revision contract | Graph Revision ID recipe lacks canonical serialization rules (sorting, normalization, hash alg/encoding), multi-alg/PQ plan, and provenance fields (feeds/policies/tools). | Different services may compute divergent hashes; receipts tied to non-canonical IDs become unverifiable or collide. | Publish `graph-revision-manifest.schema.json` with canonical JSON rules, mandated hash alg (e.g., BLAKE3-256 hex) and optional multi-alg, plus required digests for feeds, policies, tool images, config flags; add test vectors. |
|
||||
| VM2 | DSSE predicate & receipt schema | Predicate `stellaops.dev/verdict@v1` is named but not specified (required fields, canonicalization, clock source, list ordering) nor versioning/compatibility rules. | Receipts may serialize differently across services; signature verification and replay can fail; upgrades may break stored receipts. | Define versioned predicate schema + canonical JSON (sorted keys, UTC + monotonic timestamp pair, fixed decimal precision); publish validation tests and compatibility guidance; enforce in emitters/validators. |
|
||||
| VM3 | Signing policy & key lifecycle | “Sign with Authority” omits key hierarchy, rotation cadence, dual-sign (ECDSA+PQ) strategy, Rekor/mirror anchoring, and tenant scoping. | Long-lived receipts risk key compromise or compliance gaps; no traceable lineage for rotated keys; multi-tenant trust not isolated. | Document signing policy: key roles (online/offline/HSM), M-of-N custody, rotation/burn rules, dual-sign option, Rekor/mirror anchoring metadata, and tenant-scoped key IDs; enforce policy hash in receipts. |
|
||||
| VM4 | Receipt storage, retention, and isolation | Postgres table is suggested but lacks retention/GC rules, compression/dedup, encryption-at-rest, RBAC/tenant isolation, and sharding guidance. | Store can bloat; sensitive proofs may be exposed across tenants; replay/export may be inconsistent. | Define storage contract: per-tenant partitioning/shards, append-only receipts, row-level encryption, TTL/archival policy, dedup by `(graphRevisionId, verdictId, algo)`, and export manifests with hashes. |
|
||||
| VM5 | Reachability slice / symbol proof schema | Call-stack slices and binary symbol proofs lack formal schema, size budgets, architecture coverage (ARM/ppc), redaction rules for paths/symbols, and validation tooling. | Proofs may leak PII/paths, explode in size, or be unusable for replay; binaries without symbols remain unprovable. | Publish schemas for slices and symbol proofs with max nodes/bytes, required fields (arch, offset, hash of slice), redaction/normalization rules, and validator/golden fixtures; add fallback proof type when symbols absent. |
|
||||
| VM6 | Replay Manifest governance | Replay manifest is named but not required to be DSSE-signed, canonically serialized, or to pin feeds/rulepacks/tool digests/time anchors; no CI gate uses it. | Auditors cannot trust manifests; replays may drift due to unstated feed/tool changes; CI may miss drift. | Define `replay.manifest.json` schema, canonical JSON, DSSE signing, and required fields (feeds/tool digests/policies/config, fake clock seed); add CI job to rerun gold fixtures and compare graph hashes against the manifest. |
|
||||
| VM7 | “No receipt, no ship” enforcement path | Rule is declarative; no enforcement points defined (scanner pipeline, policy engine, API, UI), no failure taxonomy, and no override/waiver process. | Receipts may be missing yet verdicts ship; users see inconsistent states; overrides may bypass audit. | Add fail-closed checks in scanner/policy APIs and UI gating; define error codes for missing/invalid receipts; require signed waiver/override records and metrics for violations. |
|
||||
| VM8 | Benchmark corpus governance & ground truth | Benchmarks call for public corpus and baselines but lack governance: licensing/sanitization checklist, ground-truth labels with evidence, competitor selection matrix, and contribution/review rules. | Metrics may be non-reproducible or legally risky; baseline comparisons could be biased or outdated. | Create benchmark governance doc: sanitized corpus manifest with hashes/DSSE, ground-truth evidence bundles, contributor CLA/review rules, competitor/baseline selection matrix, and staleness SLAs; store under `bench/manifest.*` and sign. |
|
||||
| VM9 | Benchmark determinism & resource profile | Metrics (FP reduction, triage time, proof coverage, determinism) are defined but no reference hardware/profile, seeding rules, retry/timeout policy, or multi-run hash check. | Results vary run-to-run or across machines; comparisons and claims lose credibility. | Pin reference runner (CPU/RAM, cgroups), seeds, thread limits, timeouts; add multi-run hash stability check in `bench/scripts/run_benchmarks` and publish tolerances; mark strict scenarios that must be zero-drift. |
|
||||
| VM10 | Observability, alerts, and export kits | Advisory lacks required metrics/alerts for signature failures, graph-hash drift, missing proofs, or benchmark regressions, and doesn’t define the “audit kit” packaging/signing. | Failures may go unnoticed; auditors/buyers cannot independently verify kits; offline users lack parity. | Instrument counters/alerts for receipt verify failures, graph drift, proof coverage gaps, benchmark regressions; define audit-kit layout (receipts + manifest + replay + verify script) with DSSE signature and include in offline kits/export center. |
|
||||
|
||||
## Immediate follow-ups
|
||||
- Add a proof-spine/receipt gap-remediation task to Sprint `SPRINT_0401_0001_0001_reachability_evidence_chain` covering VM1–VM7.
|
||||
- Add a benchmark governance/determinism task to Sprint `SPRINT_0513_0001_0001_public_reachability_benchmark` covering VM8–VM10, tying to `bench/` manifests and CI jobs.
|
||||
- Draft and publish schemas (graph revision, verdict predicate, replay manifest, reachability proofs) plus golden fixtures/tests; wire fail-closed receipt checks and observability alerts into scanner/policy pipelines and UI/API gating.
|
||||
|
||||
# Findings – Gaps in “SBOM→VEX Proof Spine Blueprint”
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
|
||||
**Compiled:** 2025-12-01 (UTC)
|
||||
|
||||
**Source reviewed:** Chat-supplied advisory “tight, practical blueprint to turn your SBOM→VEX links into an auditable proof spine…” (not yet filed under `docs/product-advisories/`).
|
||||
|
||||
**Method:** Parsed the advisory, aligned it with Authority/Policy/Scanner evidence-chain expectations and existing sprint `SPRINT_0401_0001_0001_reachability_evidence_chain`, and checked for determinism, governance, tenancy, and offline parity gaps.
|
||||
|
||||
## Gap Table
|
||||
| ID | Area | Gap | Impact | Recommendation |
|
||||
| -- | ---- | --- | ------ | -------------- |
|
||||
| PS1 | Trust anchor lifecycle & conflicts | Per-dependency TrustAnchor is defined but lacks lifecycle rules (creation approval, change control, supersedes flow) and conflict resolution when multiple anchors match a purl or SBOMEntry. | Anchor drift can silently change accepted signers; conflicting anchors can cause verification bypass or denial. | Require signed TrustAnchor records with `version`, `createdBy`, `supersedes`, and deterministic purl matching precedence; add dual-control approvals and DSSE for anchor mutations; fail closed on ambiguous anchor selection. |
|
||||
| PS2 | Revocation/rotation enforcement | Revocation list is mentioned but no policy for how existing spines/receipts behave after key revocation or anchor update; no rollback window or re-issuance rules. | Auditors may accept spines signed by revoked keys; replay may fail inconsistently. | Define revocation semantics (hard-fail vs warn), require re-verification tasks on revocation, emit new spines/receipts when anchors change, and publish “revoked-but-accepted-until” grace policy with metrics/alerts. |
|
||||
| PS3 | Predicate schemas & test vectors | Predicate types are named (`evidence.stella/v1`, etc.) but no JSON Schemas, canonicalization vectors, or compatibility commitments. | Producers may serialize differently, leading to hash mismatches and unverifiable bundles. | Publish signed JSON Schemas + canonical JSON rules and golden test vectors for evidence/reasoning/VEX/spine; include field-level required/optional rules and normalization of enums/whitespace/precision. |
|
||||
| PS4 | Merkle/ProofBundle recipe | ProofBundleID is “merkle root” but algorithm (tree shape, path ordering, hash algo, duplicate handling, domain separation) is unspecified. | Different implementations will derive different bundle IDs for the same inputs, breaking interoperability. | Standardize Merkle recipe (hash algo, leaf format, deterministic ordering, duplicate policy, domain tags); provide reference implementation and fixtures. |
|
||||
| PS5 | Evidence failure/negative cases | Flow assumes successful evidence; no schema for failed scans, partial results, or “absence of evidence” attestations. | Missing DSSE records allow silent gaps; verification may over-trust incomplete data. | Define `evidence.stella/v1` variants for failures/partial coverage with required error codes and scope; require DSSE for failures and include them in ProofBundleID computation. |
|
||||
| PS6 | SBOM evolution & backfill | SBOMEntryID ties to sbomDigest+purl, but no rules for updated SBOMs, component renames, or superseded SBOM versions; backfill of historical spines not described. | Proof history can fragment; replay may mismatch SBOM version to spine. | Add SBOM versioning/backfill policy: immutable sbomDigest, `supersedesSbomDigest`, migration tasks to regenerate spines for changed entries, and UI/API to view lineage. |
|
||||
| PS7 | Third-party VEX & dual anchors | Import of vendor VEX is implied but no contract for dual-anchor verification (vendor + internal), status translation, or provenance preservation. | Imported VEX may be re-signed without proof of origin; status semantics can drift from vendor meaning. | Require vendor VEX verification against vendor anchor, preserve original envelope bytes, tag provenance, and optionally co-sign under Authority; define status mapping table and conflict resolution. |
|
||||
| PS8 | Storage security & tenancy | Postgres/blob layout shown but lacks tenant scoping, row-level security, encryption at rest, and retention/GC policy for blobs and envelopes. | Cross-tenant data leakage risk; unbounded storage growth; unverifiable deletions. | Enforce tenant/namespace columns with RLS, encrypt blobs, add retention classes + GC rules, and record DSSE-backed delete/tombstone manifests instead of hard deletes. |
|
||||
| PS9 | API contract & versioning | API endpoints are sketched without authZ roles, pagination, ETags, error codes, or versioning strategy; no idempotency keys for POST. | Clients may integrate inconsistently; accidental duplication or cache poisoning possible. | Define OpenAPI with versioned paths, RBAC roles (Authority/Viewer/Auditor), pagination/caching semantics, idempotency keys, and deterministic error models; add conformance tests. |
|
||||
| PS10 | Observability & SLIs | Metrics/logging expectations are absent (only UX hints); no alerts for verification drift, revocation, hash mismatch, or signer skew. | Integrity regressions may go unnoticed; auditors lack evidence of continuous enforcement. | Add required counters/histograms (verify pass/fail by reason, anchor conflicts, revocation hits, recompute drift), structured logs with IDs, and alert thresholds; document runbooks. |
|
||||
| PS11 | Offline/export kit parity | Advisory references offline friendliness but does not define export format (bundle layout, signatures, chunking), replay script, or air-gap verification inputs. | Air-gapped users cannot verify or may accept tampered kits; deterministic replay claims weaken. | Specify offline proof kit (SBOM + envelopes + anchors + schemas + Merkle recipe) with signed manifest and verify script; include chunking rules and hardware profile for replay. |
|
||||
| PS12 | Key custody & PQC coexistence | Keys live in Authority, but custody model, M-of-N approval, audit trails, and PQC dual-sign verification order are not defined. | Single-operator compromise or ambiguous verification precedence; PQ readiness unverifiable. | Define key hierarchies per environment, dual-control ops, signed key-rotation records, verification precedence (ECDSA vs PQ), and audit logging; ship HSM/KMS policy guidance. |
|
||||
| PS13 | Receipts schema & cache invalidation | Receipt structure is mentioned but not versioned; no rules for cache TTL, re-issuance when evidence/policy changes, or signing requirements. | Stale receipts may circulate; auditors cannot trust replay date/tool versions. | Version receipt schema, include verifier version/time, anchor IDs, tool hashes, policy hash; require DSSE signing; enforce cache TTL and auto-invalidate on anchor/policy change. |
|
||||
| PS14 | Performance/backpressure & dedup | No throughput/latency SLOs, queue/backpressure rules, or deduplication of envelopes for identical inputs. | Service overload or ballooning storage; duplicate envelopes inflate Merkle roots. | Define SLOs and per-tenant quotas; require deduplication by hash/predicate; add idempotent processing with backoff and metrics on drops/retries. |
|
||||
|
||||
## Immediate follow-ups
|
||||
- Add a gaps-remediation task to `SPRINT_0401_0001_0001_reachability_evidence_chain` (or create a new sprint for the proof spine) covering PS1–PS14 with owners/dates.
|
||||
- Publish signed JSON Schemas, Merkle recipe, and test vectors for evidence/reasoning/VEX/spine/receipt; wire canonicalization tests into CI.
|
||||
- Draft TrustAnchor lifecycle/rotation policy (dual-control, revocation handling, ambiguity fail-closed) and update Authority/Policy docs accordingly.
|
||||
- Define offline proof-kit packaging + verifier script and include metrics/alerts/runbooks for verification drift and anchor conflicts.
|
||||
|
||||
# Findings – Gaps in “Time-to-Evidence (TTE) Metric”
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
|
||||
**Compiled:** 2025-12-01 (UTC)
|
||||
|
||||
**Source reviewed:** `01-Dec-2025 - Time-to-Evidence (TTE) Metric.md`
|
||||
|
||||
**Method:** Evaluated TTE proposal against StellaOps UX/telemetry architecture (UI sprints 0209/0215, Telemetry core 0180). Focused on instrumentation fidelity, data quality, SLO coverage, caching/streaming readiness, offline/tenant safety, and governance.
|
||||
|
||||
## Gap Table
|
||||
| ID | Area | Gap | Impact | Recommendation |
|
||||
| -- | ---- | --- | ------ | -------------- |
|
||||
| TTE1 | Proof eligibility definition | “First proof” not formally defined (what counts as proof per surface; screenshots vs raw artifacts). | Inconsistent measurement; teams may emit on summaries. | Define proof eligibility per surface (SBOM line with bomRef + hash, reachability edge with graph rev, VEX clause with evidence ID); forbid summaries; add contract tests. |
|
||||
| TTE2 | Event schema/versioning | Event fields are informal; no schema/version, tenant scope, or PII redaction guidance. | Broken joins and leakage across tenants; dashboards unreliable. | Publish versioned `tte-event.schema.json` with required fields (finding_id, tenant_id, proof_kind, source, ui_version, synthetic flag), redaction rules, and validation in collectors. |
|
||||
| TTE3 | Correlation & dedupe | No guidance on deduping multiple `proof_rendered` events per open, retries, or tab refresh. | Over-counting inflates TTE; noisy alerts. | Define correlation rules (per finding_id + view instance), keep first-proof TTE canonical, bucket retries separately; add idempotency key. |
|
||||
| TTE4 | Sampling & bot exclusion | Sampling hinted but no hard targets, bot filters, or synthetic tagging. | Skewed metrics; false regressions. | Require 100% in staging, ≥50% prod with bot/synthetic exclusion flag; document filter and include in rollups. |
|
||||
| TTE5 | SLO scope & budgets | P95=15s stated globally; no per-surface SLOs, error budgets, or burn alerts. | Hot pages regress without alarms; mixed workloads masked. | Set per-surface SLOs (list/detail/deep-link, per proof_kind), define 28-day error budget and burn alerts; add regression guard in CI. |
|
||||
| TTE6 | Backend readiness (indexes/streaming) | Pre-index/streaming called out but no required indexes, chunk sizes, or fallback for cold caches. | P95 fails in prod despite UI work. | Mandate indexes (pkg@version, graph node, bomRef), first-chunk SLA (<200ms), cache warmers for top-N findings, and fallback to cached proof slice. |
|
||||
| TTE7 | Offline/air-gap mode | No rules for TTE when offline kits are used (local proofs) or when proofs are unavailable. | Air-gapped users show infinite TTE or misleading empties. | Define offline TTE path: local proof sources, explicit “offline proof unavailable” state, separate `source=offline_kit`; exclude from online SLO or bucket separately. |
|
||||
| TTE8 | Alerting & dashboards | Dashboards listed but no alert policies, runbooks, or ownership. | Slow drift unnoticed; no on-call action. | Create alert rules (P95>15s 15m, P99>30s 15m) with owners, runbook, and suppression windows; add weekly trend review. |
|
||||
| TTE9 | Governance & release gates | No requirement to block releases on TTE regression or to store baselines. | Regressions ship silently. | Add release check: compare P95 vs previous release by proof_kind/page; block if >20% regression unless waived; store baseline snapshots. |
|
||||
| TTE10 | Accessibility & layout | Evidence-above-fold rule stated but no viewport spec, keyboard/a11y checks, or fallback for long proofs. | Users may still miss proof or fail accessibility audits. | Define viewport targets (e.g., 1366x768), a11y checks (ARIA/Tab order for proof panel), truncation rules with “copy full proof”, and Playwright a11y test for TTE scenarios. |
|
||||
|
||||
## Immediate follow-ups
|
||||
- Add TTE1–TTE10 remediation task `TTE-GAPS-0215-011` to Sprint `SPRINT_0215_0001_0001_vuln_triage_ux` (primary UI owner) with telemetry alignment to Sprint `SPRINT_0180_0001_0001_telemetry_core`.
|
||||
- Publish `tte-event.schema.json`, proof eligibility rules per surface, sampling/bot filters, per-surface SLO/error budgets, required indexes/streaming SLOs, offline-kit handling, alert/runbook, release gate, and a11y/viewport test cases.
|
||||
|
||||
# Findings – Gaps in Archived November Advisories (15–23 Nov 2025)
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
|
||||
**Compiled:** 2025-12-01 (UTC)
|
||||
|
||||
**Source reviewed:** All advisories in `docs/product-advisories/archived/` dated 15–23 Nov 2025 (e.g., embedded in-toto provenance events, function-level VEX explainability, binary reachability branches, SBOM-provenance spine, reachability corpus, etc.).
|
||||
|
||||
**Method:** Skimmed each archived advisory and consolidated common gaps; focused on missing schemas, determinism/replay rules, tenant/redaction, offline parity, and ownership. Kept to 1–2 high-impact gaps per advisory to seed backlog without expanding scope excessively.
|
||||
|
||||
## Gap Table
|
||||
| Advisory (archived) | Gap ID | Gap | Impact | Recommendation |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Embedded in-toto provenance events | AR-EP1 | No canonical event/predicate schema or DSSE requirement; relies on narrative. | Provenance unverifiable; toolchain drift. | Publish `provenance-event.schema.json`, require DSSE, include tool version + policy hash; add fixtures. |
|
||||
| Function-level VEX explainability | AR-FX1 | Lacks stable IDs for function nodes/edges and reachability proofs. | Explanations not replayable; links break. | Define function-node ID scheme, require graph_rev, shortest-path proof bundle; add determinism tests. |
|
||||
| Serdica census Excel import blueprint | AR-SE1 | No PII redaction or checksum rules for Excel ingest. | Data leakage; non-deterministic imports. | Add redaction/allowlist, checksum manifest, DSSE receipt per import, and replay script. |
|
||||
| Proof spine for quiet alerts | AR-PS1 | “Proof spine” undefined (hash recipe, bundle layout, failure cases). | Quiet alerts un-auditable. | Standardize spine (hash algo, ordering, failure records), DSSE-sign, and ship fixtures. |
|
||||
| Scanner roadmap diff-aware rescans | AR-SR1 | No determinism guards (seed/time clamp) for rescans. | Drift across runs; flaky diffs. | Enforce fixed seeds/UTC, sorted outputs, golden diffs CI. |
|
||||
| Layer-SBOM cache hash reuse | AR-LS1 | Cache key recipe unspecified (layer ordering, tar flags, compression). | Cache collisions/misses; incorrect reuse. | Define canonical key recipe (ordered layer digests, normalized tar, compression flags) and validators. |
|
||||
| Multi-runtime reachability corpus | AR-MR1 | Corpus lacks licensing/provenance and ground-truth assertions. | Legal risk; unvalidated results. | Add license metadata, expected reachability assertions, DSSE-signed manifest. |
|
||||
| SPDX canonical persistence / CycloneDX interchange | AR-SX1 | No canonicalization rules (ordering, whitespace, encoding) across SPDX↔CDX. | Hash drift; signature breakage. | Publish canonicalization spec + round-trip tests, DSSE-sign outputs. |
|
||||
| Validation plan for quiet scans (diff-CI) | AR-VQ1 | No acceptance thresholds or negative/failure fixtures. | Quiet scans may suppress real issues. | Define threshold matrix, include failure/edge fixtures, CI gate on false-negative budget. |
|
||||
| SBOM-Provenance-Spine (17 & 18 Nov) | AR-SP1 | Duplicate advisories; spine lacks versioning and Merkle recipe. | Divergent implementations; audit gaps. | Declare single canonical doc, versioned spine schema, Merkle/hash recipe, DSSE signing. |
|
||||
| Stripped-ELF reachability | AR-SEF1 | No symbol-stripping fallback (DWARF absent) or redaction rules. | Binaries unprovable; PII path leaks. | Require fallback heuristics, redaction, and proof attestation format. |
|
||||
| Binary Reachability Engine | AR-BR1 | Performance/SLOs and determinism seeds absent. | Non-reproducible graphs; timeouts. | Set seed/time clamps, path-ordering rules, perf SLO, golden graphs CI. |
|
||||
| C# Binary Analyzer | AR-CS1 | No PURL mapping or IL-level canonical IDs. | Findings not linkable to packages; unstable links. | Define IL symbol IDs + PURL mapping rules; add hash anchors. |
|
||||
| Patch Oracles | AR-PO1 | Oracle decision schema undefined; no audit trail. | Wrong patch suggestions; untraceable. | Create oracle schema with inputs, decision, confidence, evidence; DSSE-sign and log. |
|
||||
| Unknowns Registry (18 Nov) | AR-UR1 | Registry schema/versioning missing; decay logic undefined. | Unknowns pile up; inconsistent triage. | Version registry schema, define decay/expiry fields, audit trail, and offline export. |
|
||||
| ELF Build-ID mapping | AR-BI1 | Build-ID→PURL mapping recipe not specified; no collision policy. | Misattribution; trust breaks. | Define mapping algorithm, collision handling, attestation with subject hashes. |
|
||||
| .init_array constructors as reachability roots | AR-IA1 | No rule for weighting/ordering roots or de-duplication. | Over/under-approx reachability. | Specify root precedence, dedupe, and evidence bundle with graph_rev. |
|
||||
| Reachability & Moat Watch updates | AR-MW1 | No change-log or checkpoint signing for updates. | Consumers can’t track or trust updates. | Add signed checkpoints, changelog, and freshness SLA. |
|
||||
| Encoding binary reachability with PURL edges | AR-PE1 | Edge encoding schema not versioned; arch-specific fields absent. | Cross-arch drift; parsing errors. | Version edge schema, require arch/endianness, hash of binaries, and fixtures. |
|
||||
| Where Stella Ops Can Truly Lead | AR-ML1 | Positioning lacks measurable targets or evidence asks. | Strategy not actionable. | Add 3–5 measurable targets (perf/SLO, replay fidelity) with proof requirements and owners. |
|
||||
| Benchmarking determinism in vuln scoring | AR-BD1 | No benchmark corpus or scoring reproducibility rules. | Claims unproven; regressions undetected. | Publish corpus + expected scores, hash manifest, DSSE results, CI reruns. |
|
||||
| Publishing a reachability benchmark dataset | AR-RD1 | Dataset packaging/licensing undefined; no integrity attestation. | Cannot redistribute or verify. | Add license metadata, manifest + hashes, DSSE attestation, offline kit. |
|
||||
| Stella Ops vs Competitors | AR-SC1 | Comparison lacks normalized criteria or evidence links. | Biased/unsupported claims. | Define criteria table, data sources, timestamps; include raw evidence links. |
|
||||
| Verifying Binary Reachability via DSSE Envelopes (archived copy) | AR-VB1 | Archived version lacks current DSSE predicate and Merkle recipe updates. | Divergence from active spec. | Mark superseded; link to active advisory; provide migration notes. |
|
||||
|
||||
## Immediate follow-ups
|
||||
- Add an “Archived Advisories Gaps” tracker row to the relevant documentation sprint (e.g., `SPRINT_300_documentation_process`) to decide which archived topics merit revival; start with high-signal engine/graph items (AR-BR1, AR-SEF1, AR-PE1) and provenance items (AR-EP1, AR-SP1).
|
||||
- For any archived advisory revived, create a fresh canonical advisory and sprint tasks; retire duplicates (e.g., SBOM-Provenance-Spine) with clear supersede notes.
|
||||
|
||||
### Per-advisory gap summaries (archived)
|
||||
|
||||
| Advisory | Concise Gap | Recommendation |
|
||||
| --- | --- | --- |
|
||||
| Where Stella Ops Can Truly Lead | Strategy brief lacks measurable targets and evidence asks. | Define 3–5 measurable targets (perf/SLO, replay fidelity) with required evidence links and owners. |
|
||||
| Benchmarking Determinism in Vulnerability Scoring | No corpus/expected scores; reproducibility undefined. | Publish benchmark corpus + expected scores with hash manifest and DSSE results; add CI rerun gate. |
|
||||
| Binary-Reachability-Engine | Missing determinism seeds/time clamps and perf SLOs. | Fix seeds/UTC, path-ordering rules, perf SLO, golden graphs CI. |
|
||||
| Branch · Attach ELF Build‑IDs for Stable PURL Mapping | Mapping recipe/collision policy absent. | Define Build-ID→PURL algorithm, collision handling, attestation with subject hashes. |
|
||||
| Branch · Model .init_array Constructors as Reachability Roots | Root weighting/dedup rules missing. | Specify root precedence, dedupe policy, and graph_rev-bound evidence bundle. |
|
||||
| Branch · Reachability & Moat Watch — Verified 2025 Updates | No signed checkpoints/changelog. | Add signed checkpoints with freshness SLA and changelog; distribute via DSSE snapshot. |
|
||||
| CSharp-Binary-Analyzer | No IL symbol IDs or PURL mapping rules. | Define IL symbol ID + PURL mapping with hash anchors; add fixtures. |
|
||||
| DSSE-Signed Offline Scanner Updates | (Archived) No canonical DSSE predicate or offline kit recipe. | Publish predicate schema, offline bundle layout, and verifier script with hashes. |
|
||||
| Encoding Binary Reachability with PURL‑Resolved Edges | Edge schema unversioned; arch fields missing. | Version edge schema; require arch/endianness/binary hash; add fixtures. |
|
||||
| Patch-Oracles | Oracle decision schema/audit trail undefined. | Create decision schema (inputs, decision, confidence, evidence) with DSSE signing and logging. |
|
||||
| Publishing a Reachability Benchmark Dataset | Packaging/licensing/integrity unclear. | Add license metadata, manifest + hashes, DSSE attestation, offline kit. |
|
||||
| SBOM-Provenance-Spine (17 & 18 Nov) | Duplicate docs; spine lacks versioning/Merkle recipe. | Declare canonical version, publish schema + Merkle recipe, DSSE-sign; mark duplicate superseded. |
|
||||
| Stella Ops vs Competitors | Criteria/evidence not normalized. | Define comparison criteria table, data sources/timestamps, and raw evidence links. |
|
||||
| Storage Blueprint for PostgreSQL Modules | Patterns lack tenancy/isolation and PITR/SLA specifics. | Add tenant isolation, PITR/SLA baselines, deterministic migrations, and signed change log. |
|
||||
| Stripped-ELF-Reachability | No fallback when symbols absent; redaction undefined. | Provide fallback heuristics, redaction rules, and proof attestation format. |
|
||||
| Unknowns-Registry | Schema/versioning and decay/expiry logic missing. | Version registry schema; add decay/expiry fields, audit trail, offline export. |
|
||||
| Verifiable Proof Spine Receipts and Benchmarks | Proof spine hash recipe undefined; benchmarks missing. | Standardize hash/ordering, include failure cases, DSSE-sign; publish benchmarks. |
|
||||
| Verifying Binary Reachability via DSSE Envelopes (archived copy) | Archived version diverges from active spec. | Mark superseded; link to active advisory; provide migration notes. |
|
||||
| embedded in-toto provenance events | No event schema or DSSE requirement. | Publish provenance-event schema; require DSSE; include tool/policy hashes. |
|
||||
| function-level vex explainability | Missing stable function IDs/graph_rev binding. | Define function-node IDs, require graph_rev, shortest-path proof bundle, determinism tests. |
|
||||
| ipal serdica census excel import blueprint | No PII redaction or checksum rules. | Add redaction/allowlist, checksum manifest, DSSE receipt per import, replay script. |
|
||||
| layer-sbom cache hash reuse | Cache key recipe unspecified. | Define canonical key (ordered layer digests, normalized tar/compression flags) and validators. |
|
||||
| multi-runtime reachability corpus | Lacks licensing/provenance and ground truth. | Add license metadata, expected reachability assertions, DSSE-signed manifest. |
|
||||
| proof spine for explainable quiet alerts | Spine definition missing (hash recipe/failures). | Standardize spine schema/ordering, include failure records, DSSE-sign fixtures. |
|
||||
| scanner roadmap with deterministic diff-aware rescans | No determinism guards or seeds. | Enforce fixed seeds/UTC, sorted outputs, golden diff CI. |
|
||||
| spdx canonical persistence cyclonedx interchange | No canonicalization rules across SPDX↔CDX. | Publish canonicalization spec + round-trip tests; DSSE-sign outputs. |
|
||||
| validation plan for quiet scans provenance diff-ci | Lacks acceptance thresholds and negative fixtures. | Define thresholds and failure/edge fixtures; gate CI on false-negative budget. |
|
||||
|
||||
## Archived advisory stubs (per-advisory headings)
|
||||
*These stubs reference the consolidated AR-* gap table above; no additional gaps beyond that table.*
|
||||
|
||||
# Findings – Gaps in “Where Stella Ops Can Truly Lead”
|
||||
See AR-ML1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “ Where Stella Ops Can Truly Lead”
|
||||
See AR-ML1 in the archived gap table; archived filename contains a leading space.
|
||||
|
||||
# Findings – Gaps in “Benchmarking Determinism in Vulnerability Scoring”
|
||||
See AR-BD1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Binary-Reachability-Engine”
|
||||
See AR-BR1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Branch · Attach ELF Build‑IDs for Stable PURL Mapping”
|
||||
See AR-BI1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Branch · Model .init_array Constructors as Reachability Roots”
|
||||
See AR-IA1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Branch · Reachability & Moat Watch — Verified 2025 Updates”
|
||||
See AR-MW1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “CSharp-Binary-Analyzer”
|
||||
See AR-CS1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “DSSE-Signed Offline Scanner Updates”
|
||||
See AR-DS1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Encoding Binary Reachability with PURL‑Resolved Edges”
|
||||
See AR-PE1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Patch-Oracles”
|
||||
See AR-PO1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Publishing a Reachability Benchmark Dataset”
|
||||
See AR-RD1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “SBOM-Provenance-Spine”
|
||||
See AR-SP1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “SBOM-Provenance-Spine”
|
||||
See AR-SP1 in the archived gap table; duplicate advisory, treat 18-Nov version as canonical.
|
||||
|
||||
# Findings – Gaps in “Stella Ops vs Competitors”
|
||||
See AR-SC1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Storage Blueprint for PostgreSQL Modules”
|
||||
See AR-SB1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Stripped-ELF-Reachability”
|
||||
See AR-SEF1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Unknowns-Registry”
|
||||
See AR-UR1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Verifiable Proof Spine Receipts and Benchmarks”
|
||||
See AR-VP1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Verifying Binary Reachability via DSSE Envelopes”
|
||||
See AR-VB1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “embedded in-toto provenance events”
|
||||
See AR-EP1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “function-level vex explainability”
|
||||
See AR-FX1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “ipal serdica census excel import blueprint”
|
||||
See AR-SE1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “layer-sbom cache hash reuse”
|
||||
See AR-LS1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “multi-runtime reachability corpus”
|
||||
See AR-MR1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “proof spine for explainable quiet alerts”
|
||||
See AR-PS1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “scanner roadmap with deterministic diff-aware rescans”
|
||||
See AR-SR1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “spdx canonical persistence cyclonedx interchange”
|
||||
See AR-SX1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “validation plan for quiet scans provenance diff-ci”
|
||||
See AR-VQ1 in the archived gap table.
|
||||
|
||||
# Findings – Gaps in “Rekor Receipt Checklist for Stella Ops”
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
@@ -634,7 +953,7 @@
|
||||
- Add MI1–MI10 remediation task to UI Sprint `SPRINT_0209_0001_0001_ui_i` (or UI II/III if preferred) with owners and dates.
|
||||
- Publish motion/telemetry/testing tokens, reduced-motion rules, offline/error patterns, component mappings, and theme-aware micro-copy guidance; add Playwright/a11y checks to CI.
|
||||
|
||||
# Findings – Gaps in “Proof‑Linked VEX UI Developer Guidelines”
|
||||
# Findings – Gaps in “Proof-Linked VEX UI Developer Guidelines”
|
||||
|
||||
**Requested label:** 2025-11-31 (note: November has 30 days)
|
||||
|
||||
@@ -1361,3 +1680,12 @@
|
||||
## Immediate follow-ups
|
||||
- Add a ledger gaps task to a relevant sprint (e.g., reachability/policy ledger work or EvidenceLocker/export coordination) to close FL1–FL10.
|
||||
- Publish versioned schemas and canonical serialization; mandate Merkle/external anchor policy with freshness; enforce tenant/redaction rules; require DSSE/policy linkage; add golden fixtures, replay/rebuild verifiers, air-gap verify scripts, and quotas/backpressure.
|
||||
_id; verify on ingest/export. |
|
||||
| FL7 | Export determinism & golden fixtures | Export determinism claimed but no golden fixtures or multi-run hash CI for ledger exports. | Regressions may go unnoticed; reproducibility claims weak. | Publish golden ledger exports and CI multi-run hash checks; pin compression/ordering. |
|
||||
| FL8 | Replay/rebuild tooling | Projection rebuild guidance minimal; no checksum for rebuild outputs. | Rebuilds may diverge from ledger state; audits fail. | Provide rebuild CLI with output hashes; compare against ledger roots; add acceptance tests. |
|
||||
| FL9 | Air-gap verifier | Offline bundle verification is mentioned but not specified (hash chain, Merkle roots, anchors, revocations). | Air-gapped audits may be incomplete. | Define offline ledger verify script requirements (hash chain, Merkle root, optional external anchor checkpoint); ship script + tests. |
|
||||
| FL10 | Performance envelopes & quotas | SLOs listed but no quotas/backpressure for append/export per tenant or chain. | Hot tenants could starve others; risk of data loss under load. | Add per-tenant quotas/backpressure and alerts; document performance envelopes; test under load. |
|
||||
|
||||
## Immediate follow-ups
|
||||
- Add a ledger gaps task to a relevant sprint (e.g., reachability/policy ledger work or EvidenceLocker/export coordination) to close FL1–FL10.
|
||||
- Publish versioned schemas and canonical serialization; mandate Merkle/external anchor policy with freshness; enforce tenant/redaction rules; require DSSE/policy linkage; add golden fixtures, replay/rebuild verifiers, air-gap verify scripts, and quotas/backpressure.
|
||||
|
||||
@@ -10,6 +10,7 @@ These are the authoritative advisories to reference for implementation:
|
||||
- **Canonical:** `25-Nov-2025 - Add CVSS v4.0 Score Receipts for Transparency.md`
|
||||
- **Sprint:** SPRINT_0190_0001_0001_cvss_v4_receipts.md
|
||||
- **Gaps:** `31-Nov-2025 FINDINGS.md` (CV1–CV10 remediation task CVSS-GAPS-190-013)
|
||||
- **Timing/UI:** `01-Dec-2025 - Time-to-Evidence (TTE) Metric.md` (archived)
|
||||
- **Status:** New sprint created
|
||||
|
||||
### CVSS v4.0 Momentum Briefing
|
||||
@@ -76,6 +77,20 @@ These are the authoritative advisories to reference for implementation:
|
||||
- **Gaps:** `31-Nov-2025 FINDINGS.md` (PVX1–PVX10 remediation task UI-PROOF-VEX-0215-010)
|
||||
- **Status:** Drawer/badge pattern defined but missing scoped auth, cache/staleness policy, stronger integrity verification, failure/offline UX, evidence precedence rules, telemetry privacy schema, signed permalinks, revision reconciliation, and fixtures/tests.
|
||||
|
||||
### Time-to-Evidence (TTE) Metric
|
||||
- **Canonical:** `01-Dec-2025 - Time-to-Evidence (TTE) Metric.md`
|
||||
- **Sprint:** SPRINT_0215_0001_0001_vuln_triage_ux.md (UI) with telemetry alignment to SPRINT_0180_0001_0001_telemetry_core.md
|
||||
- **Related Docs:** UI sprints 0209/0215, telemetry architecture docs
|
||||
- **Gaps:** `31-Nov-2025 FINDINGS.md` (TTE1–TTE10 remediation task TTE-GAPS-0215-011)
|
||||
- **Status:** Metric defined but needs event schema/versioning, proof eligibility rules, sampling/bot filters, per-surface SLO/error budgets, index/streaming requirements, offline-kit handling, alert/runbook, release gate, and a11y tests.
|
||||
|
||||
### Archived Advisories (15–23 Nov 2025)
|
||||
- **Canonical:** `docs/product-advisories/archived/*.md` (embedded provenance events, function-level VEX explainability, binary reachability branches, SBOM-provenance spine, etc.)
|
||||
- **Sprint:** SPRINT_300_documentation_process.md (triage/decision)
|
||||
- **Related Docs:** None current (need revival + canonicalization)
|
||||
- **Gaps:** `31-Nov-2025 FINDINGS.md` (AR-EP1 … AR-VB1 remediation task ARCHIVED-GAPS-300-020)
|
||||
- **Status:** Archived set lacks schemas, determinism rules, redaction/licensing, changelog/signing, and duplication resolution; needs triage on which to revive into active advisories.
|
||||
|
||||
### SBOM → VEX Proof Blueprint
|
||||
- **Canonical:** `29-Nov-2025 - SBOM to VEX Proof Pipeline Blueprint.md`
|
||||
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# Time-to-Evidence (TTE) Metric
|
||||
|
||||
Compiled: 2025-12-01 (UTC)
|
||||
|
||||
## What it is
|
||||
|
||||
**Definition:** `TTE = t_first_proof_rendered − t_open_finding`.
|
||||
|
||||
**Proof** = the exact artifact or path that justifies the claim (e.g., `package-lock.json: line 214 → openssl@1.1.1`, `reachability: A → B → C sink`, or `VEX: not_affected due to unreachable code`).
|
||||
|
||||
**Target:** **P95 ≤ 15s** (stretch: **P99 ≤ 30s**). If 95% of findings show proof within 15 seconds, the UI stays honest: evidence before opinion, low noise, fast explainability.
|
||||
|
||||
## Why it matters
|
||||
|
||||
- **Trust:** People accept decisions they can verify quickly.
|
||||
- **Triage speed:** Proof-first UIs cut back-and-forth and guesswork.
|
||||
- **Noise control:** If you can’t surface proof fast, you probably shouldn’t surface the finding yet.
|
||||
|
||||
## How to measure (engineering-ready)
|
||||
|
||||
Emit two stamps per finding view:
|
||||
|
||||
- `t_open_finding` (on route enter or modal open).
|
||||
- `t_first_proof_rendered` (first DOM paint of SBOM line / path list / VEX clause).
|
||||
|
||||
Store as `tte_ms` in a lightweight events table (Postgres) with tags: `tenant`, `finding_id`, `proof_kind` (`sbom|reachability|vex`), `source` (`local|remote|cache`).
|
||||
|
||||
Nightly rollup: compute P50/P90/P95/P99 by proof_kind and page. Alert when **P95 > 15s** for 15 minutes.
|
||||
|
||||
## UI contract (keeps the UX honest)
|
||||
|
||||
- **Above the fold:** always show a compact **Proof panel** first (not hidden behind tabs).
|
||||
- **Skeletons over spinners:** reserve space; render partial proof as soon as any piece is ready.
|
||||
- **Plain text copy affordance:** “Copy SBOM line / path” button right next to the proof.
|
||||
- **Defer non-proof widgets:** CVSS badges, remediation prose, and charts load *after* proof.
|
||||
- **Empty-state truth:** if no proof exists, say “No proof available yet” and show the loader for *that* proof type only (don’t pretend with summaries).
|
||||
|
||||
## Backend rules of thumb
|
||||
|
||||
- **Pre-index for first paint:** cache top N proof items per hot finding (e.g., first SBOM hit + shortest path).
|
||||
- **Bound queries:** proof queries must be *O(log n)* on indexed columns (pkg name@version, file hash, graph node id).
|
||||
- **Chunked streaming:** send first proof chunk <200 ms after backend hit; don’t hold for the full set.
|
||||
- **Timeout budget:** 12s backend budget + 3s UI/render margin = 15s P95.
|
||||
|
||||
## Minimal contract to add in your code
|
||||
|
||||
```ts
|
||||
// Frontend: fire on open
|
||||
metrics.emit('finding_open', { findingId, t: performance.now() });
|
||||
|
||||
// When the first real proof node/line hits the DOM:
|
||||
metrics.emit('proof_rendered', { findingId, proofKind, t: performance.now() });
|
||||
```
|
||||
|
||||
```sql
|
||||
-- Rollup (hourly)
|
||||
SELECT
|
||||
proof_kind,
|
||||
percentile_cont(0.95) WITHIN GROUP (ORDER BY tte_ms) AS p95_ms
|
||||
FROM tte_events
|
||||
WHERE ts >= now() - interval '1 hour'
|
||||
GROUP BY proof_kind;
|
||||
```
|
||||
|
||||
## What to put on the team dashboard
|
||||
|
||||
- **TTE P95 by page** (Findings list, Finding details).
|
||||
- **TTE P95 by proof_kind** (sbom / reachability / vex).
|
||||
- **Error budget burn**: minutes over target per day.
|
||||
- **Top regressions**: last 7 days vs prior 7.
|
||||
|
||||
## Acceptance checklist for any finding view
|
||||
|
||||
- [ ] First paint shows a real proof snippet (not a summary).
|
||||
- [ ] “Copy proof” button works within 1 click.
|
||||
- [ ] TTE P95 in staging ≤ 10s; in prod ≤ 15s.
|
||||
- [ ] If proof missing, explicit empty-state + retry path.
|
||||
- [ ] Telemetry sampled ≥ 50% of sessions (or 100% for internal).
|
||||
|
||||
## Ready-to-drop implementation notes
|
||||
Reference in New Issue
Block a user