- 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.
10 KiB
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):
- Load latest tarball from your local
updates/cache. - Verify DSSE signature against your trusted public keys.
- Verify Rekor v2 receipt (inclusion proof) matches the DSSE payload hash.
- If both pass, unpack/activate; record the bundle’s trust_id (e.g., statement digest).
- 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 todb/active/. - Quarantine on failure: move bad bundles to
updates/quarantine/with a reason code.
Minimal .NET 10 verifier sketch (C#)
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.pubandrekor.pubin 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:
- Builds
payload.tar.zstand computes hashes - Generates
manifest.json - Creates and signs the DSSE statement
- Submits to Rekor (or your mirror) and saves the v2 receipt
- Packages the bundle folder and publishes to your offline repo
- Builds
- 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
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
- 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.
- Deterministic replay: given a kit + its DSSE attestation bundle, every verifier reaches the same verdict online or air‑gapped.
- Separation of concerns: Export Center builds attestations; Scanner verifies/imports; Signer/Attestor handle DSSE/Rekor.
- 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.jsonand.rekor.json(+ segments). - Integrate into offline kit packaging: place attestation files under
/attestations/; list them inoffline-manifest.jsonwith 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)
- Read operator guides:
docs/modules/scanner/operations/dsse-rekor-operator-guide.md,docs/24_OFFLINE_KIT.md, relevant sprints. - Implement: generate DSSE in Export Center; include attestation in kit; Scanner verifies before swap.
- Test: bundle composition, import rollback, determinism.
- Telemetry: counters + latency; log digests/UUIDs.
- Document: update Export Center and Scanner architecture docs, OUK docs when flows/contracts change.