Files
git.stella-ops.org/docs/product-advisories/01-Dec-2025 - DSSE-Signed Offline Scanner Updates.md
StellaOps Bot 44171930ff
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
feat: Add UI benchmark driver and scenarios for graph interactions
- 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.
2025-12-02 01:28:17 +02:00

10 KiB
Raw Blame History

DSSESigned 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.

Heres a tight, practical pattern to make your scanners vulnDB updates rocksolid even when feeds hiccup:

Offline, verifiable update bundles (DSSE + Rekor v2)

Idea: distribute DB updates as offline tarballs. Each tarball ships with:

  • a DSSEsigned statement (e.g., intoto 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 bundles trust_id (e.g., statement digest).
  5. If anything fails, keep using the last good bundle. No service disruption.

Why this helps

  • Airgap friendly: no live network needed at activation time.
  • Tamperevident: DSSE + Rekor receipt proves provenance and transparency.
  • Operational stability: feed outages become nonevents—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, outofband 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 symlinkflip to db/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.pub and rekor.pub in a rootowned, readonly path; rotate via a separate signed “trust bundle”.
  • Defenseindepth: verify both the payload hash and each files hash listed in manifest.entries[].
  • Rollback: allow --force-activate <bundle> for emergency testing, but mark as nonmonotonic 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 outofband.

If you want, I can turn this into a StellaOps spec page (docs/modules/scanner/offline-bundles.md) plus a small reference implementation (C# library + CLI) that drops right into your Scanner service.


Dropin Stella Ops Dev Guide (seed for docs/modules/scanner/development/dsse-offline-updates.md)

Audience Scanner, Export Center, Attestor, CLI, and DevOps engineers implementing DSSEsigned 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 & nongoals

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 airgapped.
  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.

Nongoals

  • Designing new crypto or log formats.
  • Perfeed DSSE envelopes (minimum contract is bundlelevel attestation).

2. Bundle contract for DSSEsigned 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 & offlinesafety 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.