new two advisories and sprints work on them

This commit is contained in:
master
2026-01-16 18:39:36 +02:00
parent 9daf619954
commit c3a6269d55
72 changed files with 15540 additions and 18 deletions

View File

@@ -0,0 +1,352 @@
# Advisory: DSSE, Rekor, Gates, Audited Decisions
> **Status:** ARCHIVED (2026-01-17)
> **Disposition:** Translated to implementation sprints
> **Sprints Created:**
> - `SPRINT_20260117_001_ATTESTOR_periodic_rekor_verification`
> - `SPRINT_20260117_002_EXCITITOR_vex_rekor_linkage`
> - `SPRINT_20260117_003_BINDEX_delta_sig_predicate`
---
## Implementation Notes
### Gap Analysis Summary
| Advisory Claim | Current State | Action Taken |
|----------------|---------------|--------------|
| Authority handles DSSE signing | **Signer** handles DSSE; Authority handles identity/auth | No change - current design correct |
| "Router" submits to Rekor v2 | **Attestor** already does this | No change |
| CycloneDX 1.6 with hashes | Scanner supports CDX 1.6/1.7 | No change |
| OPA/Rego CI gate | Policy Engine has native gates (SPL + SignatureRequiredGate) | No change - SPL is equivalent |
| Periodic Rekor re-verification | Missing | **SPRINT_20260117_001** created |
| VEX-Rekor linkage | Incomplete backlinks | **SPRINT_20260117_002** created |
| Delta-sig predicate | Not implemented | **SPRINT_20260117_003** created |
### Decisions
1. **OPA/Rego NOT adopted** - Stella Ops already has SPL (Policy DSL) and native .NET gates (`SignatureRequiredGate`, `SbomPresenceGate`, etc.) that provide equivalent capability. Adding OPA would create two policy languages to maintain with no capability benefit.
2. **Authority signing NOT changed** - The advisory incorrectly suggests Authority should handle DSSE signing. Current architecture correctly separates:
- Authority: Identity, OAuth2/OIDC tokens, sender-constrained OpToks
- Signer: DSSE bundle creation, Fulcio/KMS signing
3. **Delta-sig leverages existing Ghidra/B2R2** - BinaryIndex module already has:
- `GhidraHeadlessManager` with process pooling
- `B2R2LowUirLiftingService` for IR lifting
- `VersionTrackingService` for function matching
- `BSim` for semantic similarity
---
## Original Advisory Content
Here's a short, implementationready plan to turn your SBOMs into enforceable, cryptographic gates in Stella Ops—sequence, gate checks, and a compact threat model you can wire into a sprint.
---
# Minimal sequence (do now)
1. **CI build → Scanner/Sbomer**
Compute `sha256` of each artifact and emit CycloneDX 1.6 SBOM with `components[].hashes[]`. ([CycloneDX][1])
2. **Authority (DSSE sign)**
Canonicalize SBOM JSON; wrap as DSSE `payloadType` for attestations and sign (HSM/KMS key). ([in-toto][2])
3. **Router (Rekor v2)**
Upload DSSE / intoto Statement to Rekor v2; persist returned `uuid`, `logIndex`, `integratedTime`. ([Sigstore Blog][3])
4. **Vexer/Excititor (VEX)**
Emit OpenVEX/CSAF (or intoto predicate) referencing CycloneDX `serialNumber`/`bom-ref` and the Rekor `uuid`. ([in-toto][2])
5. **CI gate (OPA/Rego)**
Verify (a) DSSE signature chain, (b) `payloadType` matches expected, (c) Rekor inclusion (via `logIndex`/UUID), (d) allowed `predicateType`, (e) component hash equals subject digest. ([Witness][4])
---
# Pastein Rego (gate)
```rego
package stella.gate
deny[msg] {
input.attestation.payloadType != "application/vnd.cyclonedx+json"
msg = "unexpected payloadType"
}
deny[msg] {
not input.rekor.logIndex
msg = "missing rekor logIndex"
}
/* extend:
- verify DSSE signature against Authority key
- verify Rekor inclusion proof/integratedTime
- ensure predicateType {
"https://cyclonedx.org/schema/bom-1.6",
"https://openvex.org/v1"
}
- ensure subject digest == components[].hashes[].content
*/
```
---
# Compact threat model (top 3 + mitigations)
* **Tampering at rest** → Anchor in Rekor v2; verify inclusion + `integratedTime`; require DSSE signature with Authority HSM key. ([Sigstore Blog][3])
* **Timeshift / backdating** → Reject if `integratedTime` < pipeline build time skew; optional RFC3161 timestamping on uploads. (Policy check in Scheduler.) ([Sigstore Blog][3])
* **Provenance spoofing** Enforce valid `predicateType` (intoto/OpenVEX), and map `signatures[].keyid` to trusted Authority keys (Fulcio/HSM). ([in-toto][2])
---
# Where this lands in Stella
* **Scanner**: compute subject digests; emit artifact metadata.
* **Sbomer**: produce CycloneDX 1.6 with hashes, CBOM/attestations support ready. ([CycloneDX][1])
* **Authority**: create DSSE envelope + sign; maintain key roster & rotation. ([Gradle Documentation][5])
* **Router**: call Rekor v2; persist `uuid`/`logIndex`/`integratedTime` and expose `verifyRekor(uuid)`. ([Sigstore Blog][3])
* **Vexer/Excititor**: emit OpenVEX / intoto predicates linking `bom-ref` and Rekor `uuid`. ([in-toto][2])
---
# Final sprint checklist
* Enable DSSE wrapping + Authority signing in one CI pipeline; push to Rekor v2; store `logIndex`. ([Sigstore Blog][3])
* Add OPA policy to verify `payloadType`, Rekor presence, and digest match; fail CI on violation. ([Witness][4])
* Add Scheduler job to periodically reverify Rekor roots and enforce timeskew rules. ([Sigstore Blog][3])
**Why now:** CycloneDX 1.6 added attestations/CBOM, making SBOMs firstclass, signed evidence; Rekor v2 lowers cost and simplifies opsideal for anchoring these facts and gating releases. ([CycloneDX][1])
If you want, I can drop this into `docs/policies/OPA/stella.gate.rego` and a sample CI job for your GitLab pipeline next.
[1]: https://cyclonedx.org/news/cyclonedx-v1.6-released/?utm_source=chatgpt.com "CycloneDX v1.6 Released, Advances Software Supply ..."
[2]: https://in-toto.io/docs/specs/?utm_source=chatgpt.com "Specifications"
[3]: https://blog.sigstore.dev/rekor-v2-ga/?utm_source=chatgpt.com "Rekor v2 GA - Cheaper to run, simpler to maintain"
[4]: https://witness.dev/docs/docs/concepts/policy/?utm_source=chatgpt.com "Policies"
[5]: https://docs.gradle.com/develocity/dpg/current/?utm_source=chatgpt.com "Develocity Provenance Governor"
---
Here's a compact, engineerfirst guide to emitting a CycloneDX SBOM, wrapping it in a DSSE/intoto attestation, and anchoring it in Rekor v2so you can copy/paste shapes straight into your Sbomer Authority Router flow.
---
# Why this matters (quick background)
* **CycloneDX**: the SBOM format you'll emit.
* **DSSE**: minimal, unambiguous envelope for signing arbitrary payloads (your SBOM).
* **intoto Statement**: standard wrapper with `subject` + `predicate` so policy engines can reason about artifacts.
* **Rekor (v2)**: transparency log anchor (UUID, index, integrated time) to verify later at gates.
---
# Minimal CycloneDX 1.6 SBOM (emit from `Sbomer`)
```json
{
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": "urn:uuid:11111111-2222-3333-4444-555555555555",
"metadata": {
"component": {
"bom-ref": "stella-app",
"type": "application",
"name": "stella-app",
"version": "1.2.3"
}
},
"components": [
{
"bom-ref": "lib-a",
"type": "library",
"name": "lib-a",
"version": "0.1.0",
"hashes": [
{ "alg": "SHA-256", "content": "<hex-hash>" }
]
}
]
}
```
**Mustemit fields (Sbomer):** `specVersion`, `serialNumber`, `components[].bom-ref`, `components[].hashes[].(alg,content)`.
---
# Wrap SBOM with DSSE (signed by `Authority`)
```json
{
"payloadType": "application/vnd.cyclonedx+json",
"payload": "<base64(cyclonedx-bom.json)>",
"signatures": [
{ "keyid": "cosign:sha256:abcd...", "sig": "<base64-signature>" }
]
}
```
**Mustemit (Authority):** `payloadType`, `payload` (base64), `signatures[].keyid`, `signatures[].sig`.
---
# Optional: intoto Statement (produced by `Excititor/Vexer`)
```json
{
"_type": "https://in-toto.io/Statement/v0.1",
"subject": [
{ "name": "stella-app", "digest": { "sha256": "<artifact-sha256>" } }
],
"predicateType": "https://cyclonedx.org/schema/bom-1.6",
"predicate": {
"bomRef": "stella-app",
"uri": "oci://registry.example.com/stella-app@sha256:<digest>#sbom"
}
}
```
**Mustemit (Excititor/Vexer):** `predicateType` and a `predicate` your policy engine can dereference (embed SBOM or provide a pointer).
---
# Rekor v2 anchor (persist in `Router`, verify at gates)
```json
{
"uuid": "c3f2e4a8-...",
"logIndex": 123456,
"integratedTime": "2026-01-15T12:34:56Z"
}
```
**Muststore (Router):** `uuid`, `logIndex`, `integratedTime`.
---
# Endtoend checks (put these in your CI gate)
* **SBOM shape**: JSON Schema validate CycloneDX; ensure `serialNumber` + percomponent hashes exist.
* **DSSE**: verify signature over `payload` and `payloadType`; match `keyid` to trusted keys/profile.
* **intoto**: confirm `subject.digest` equals the release OCI digest; `predicateType` matches CycloneDX 1.6/1.7.
* **Rekor v2**: look up `uuid` confirm `logIndex` & `integratedTime` and verify inclusion proof.
---
# Stella Ops module contract (TL;DR)
* **Sbomer** emits CycloneDX 1.6/1.7 with `bom-ref` + hashes.
* **Authority** DSSE sign (`payloadType=application/vnd.cyclonedx+json`).
* **Excititor/Vexer** optional intoto Statement with CycloneDX predicate or pointer.
* **Router** store Rekor v2 tuple; expose verify endpoint for gates.
If you want, I can turn this into readytorun .NET 10 DTOs + validation (FluentValidation) and a tiny verifier CLI that checks all four layers in one go.
Here's a compact, auditorfriendly way to sign **binary diffs** so they fit cleanly into today's supplychain tooling (DSSE, intoto, Sigstore/Rekor) without inventing a new envelope.
---
# DSSE "deltasig" predicate for signed binary diffs (what & why)
* **Goal:** prove *exactly what changed* in a compiled artifact (perfunction patching, hotfixes/backports) and who signed itusing the standard **DSSE** (Dead Simple Signing Envelope) + **intoto predicate typing** so verifiers and transparency logs work outofthebox.
* **Why not just hash the whole file?** Fullfile hashes miss *where* and *how* a patch changed code. A delta predicate captures functionlevel changes with canonical digests, so auditors can verify the patch is minimal and intentional, and policy can gate on "only approved backports applied."
---
# Envelope strategy
* Keep the **DSSE envelope** as usual (`payloadType`, `payload`, `signatures`).
* The DSSE `payload` is a **canonical JSON** object typed as an intoto predicate.
* Predicate type (minimal): `stellaops/delta-sig/v1`.
This keeps interoperability with:
* **Sigstore/Rekor** (log DSSE envelopes),
* **intoto** (predicate typing & subject semantics),
* existing verification flows (cosign/sigstorepython/intotoverify).
---
# Minimal predicate schema
```json
{
"predicateType": "stellaops/delta-sig/v1",
"subject": [
{
"uri": "oci://registry.example.com/app@sha256:…",
"digest": { "algo": "sha256", "hex": "<artifact_sha256>" },
"filename": "bin/app",
"arch": "linux-amd64"
}
],
"delta": [
{
"function_id": "foo::bar(int,char)",
"addr": 140737488355328,
"old_hash": "<sha256_of_old_bytes>",
"new_hash": "<sha256_of_new_bytes>",
"hash_algo": "sha256",
"diff_len": 112,
"patch_offset": 4096,
"compressed_diff_b64": "<optional_zstd_or_gzip_b64>"
}
],
"tooling": {
"lifter": "ghidra",
"lifter_version": "11.1",
"canonical_ir": "llvm-ir-15"
},
"canonicalization": {
"json_canonicalization_version": "RFC8785"
},
"signer": {
"keyid": "SHA256:…",
"signer_name": "Release Engineering"
},
"signed_digest": {
"algo": "sha256",
"hex": "<sha256_of_canonical_payload_bytes>"
}
}
```
**Notes**
* Use **SHA256** for `subject.digest`, `old_hash`, `new_hash`, and `signed_digest` to maximize compatibility with Rekor/Sigstore. (If you control both ends, **BLAKE2b256** is a fine faster alternative.)
* `function_id` should be a **stable signature** (normalized symbol or demangled prototype); fall back to address + size if needed.
* `compressed_diff_b64` is optional but handy for reproducible patch replay.
---
# Signing & verification (practical)
1. **Produce canonical payload**
* Serialize JSON with **RFC 8785** canonicalization (no insignificant whitespace, deterministic key order).
2. **Wrap in DSSE**
* `payloadType`: `application/vnd.in-toto+json` (common) or a dedicated type string if you prefer.
* `payload`: base64 of canonical JSON bytes.
3. **Sign**
* Use **cosign** or **sigstorepython** to sign DSSE; store in **Rekor** (transparency).
4. **Verify**
* Check DSSE signature decode predicate verify each `old_hash`/`new_hash` against the target bytes optionally replay `compressed_diff_b64` and rehash to confirm `new_hash`.
Policy examples you can enforce:
* Only allow releases whose delta predicate touches ** N functions** and **no controlflow edges** outside whitelisted modules.
* Require `tooling.lifter` in an approved set and `signed_digest.algo == "sha256"`.
---
# Why this fits your stack (Stella Ops, CI/CD, auditors)
* **Auditable:** functionlevel intent captured, reproducible verification, deterministic hashing.
* **Composable:** works with existing DSSE/intoto pipelines; attach to OCI artifacts or release manifests.
* **Gateable:** let release policy check the delta surface and signer identity before promotion.
* **Futureproof:** can add PQC keys later without changing the predicate.
If you want, I can generate:
* A JSON Schema (`$id`, types, enums, bounds) for `stellaops/delta-sig/v1`.
* A tiny reference **signer** (CLI) that emits canonical JSON + DSSE, and a **verifier** that checks functionlevel diffs against a binary.

View File

@@ -0,0 +1,148 @@
Here's a tight, practical first pass for a **"doctor" setup wizard** that runs right after install and anytime from Settings → Diagnostics. It gives instant confidence that Stella Ops is wired correctly, without needing full integrations configured.
---
# What the "doctor" does (in plain terms)
It runs a few lightweight health checks to confirm your system can:
* talk to its database,
* reach its attestation store (for signed proofs),
* verify a sample artifact endtoend (SBOM + VEX).
If these pass, your install is sound and you can add integrations later at your pace.
---
# Mandatory checks (first pass)
1. **DB connectivity + schema version**
* **Why**: If the DB is unreachable or the schema is outdated, nothing else matters.
* **Checks**:
* TCP/connect to Postgres URI.
* `SELECT 1;` liveness.
* Read `schema_version` from `stella.meta` (or your flyway/liquibase table).
* Compare to the app's expected version; warn if migrations pending.
* **CLI sketch**:
```bash
stella doctor db \
--url "$STELLA_DB_URL" \
--expect-schema "2026.01.0"
```
* **Pass criteria**: reachable + current (or actionable "run migrations" hint).
2. **Attestation store availability (Rekor/Cosign)**
* **Why**: Stella relies on signed evidence; if the ledger/store isn't reachable, you can't prove integrity.
* **Checks**:
* Resolve/HTTP 200 for Rekor base URL (or your mirror).
* Cosign key material present (KMS, keyless, or offline bundle).
* Clock skew sanity (<5s) for signature verification.
* **CLI sketch**:
```bash
stella doctor attest \
--rekor-url "$STELLA_REKOR_URL" \
--cosign-key "$STELLA_COSIGN_KEY" \
--mode "online|offline"
```
* **Pass criteria**: ledger reachable (or offline bundle found) + keys valid.
3. **Artifact verification pipeline run (SBOM + VEX sample)**
* **Why**: Proves the *whole* trust path works—fetch, verify, evaluate policy.
* **Checks**:
* Pull a tiny, known test artifact by **digest** (immutable).
* Verify signature/attestations (DSSE in Rekor or offline bundle).
* Fetch/validate **SBOM** (CycloneDX/SPDX) and a sample **VEX**.
* Run policy engine: "nogo if critical vulns without VEX justification."
* **CLI sketch**:
```bash
stella doctor verify \
--artifact "oci://registry.example/test@sha256:deadbeef..." \
--require-sbom \
--require-vex
```
* **Pass criteria**: signature + SBOM + VEX validate; policy engine returns ✅.
---
# Output & UX
* **Onescreen summary** with green/yellow/red statuses and terse fixes.
* **Copypaste remediations** (DB URI example, Rekor URL, cosign key path).
* **Evidence links** (e.g., "View attestation entry" or "Open policy run").
* **Export**: `stella doctor --json > doctor-report.json` for support.
---
# Where this fits in the installer/wizard
* **UI & CLI** both follow the same steps:
1. DB setup → quick migration → **Doctor: DB**
2. Choose attestation mode (Rekor/cosign keyless/offline bundle) → **Doctor: Attest**
3. Minimal "verification pipeline" config (test registry creds or bundled sample) → **Doctor: Verify**
* Each step has **defaults** (Postgres + Rekor URL + bundled demo artifact) and a **"Skip for now"** with a reminder tile in Settings → Integrations.
---
# Failure → Suggested fixes (examples)
* **DB schema mismatch** → "Run `stella migrate up` to 2026.01.0."
* **Rekor unreachable** → "Check DNS/proxy; or switch to Offline Attestations in Settings."
* **Cosign key missing** → "Add key (KMS/file) or enable keyless; see Keys → Add."
* **SBOM/VEX missing** → "Enable 'Generate SBOM on build' and 'Collect VEX from vendors', or load a demo bundle."
---
# Next steps (beyond first pass)
* Optional checks the wizard can add later:
* **Registry** reachability (pull by digest).
* **Settings store** (Valkey cache reachability).
* **Notifications** (send test webhook/email).
* **SCM/Vault/LDAP** plugin stubs: ping + auth flow (but not required to pass install).
If you want, I can turn this into:
* a readytoship **CLI command spec**,
* a **UI wireframe** of the three-step doctor,
* or **JSON schemas** for the doctor's machinereadable report.
---
## Implementation Status
**IMPLEMENTED** on 2026-01-16.
The advisory has been translated into the following Doctor plugins:
1. **Database checks** (already existed in `stellaops.doctor.database`):
- `check.db.connection` - Database connectivity
- `check.db.schema.version` - Schema version check
2. **Attestation plugin** (`stellaops.doctor.attestation`) - NEW:
- `check.attestation.rekor.connectivity` - Rekor transparency log connectivity
- `check.attestation.cosign.keymaterial` - Cosign key material availability
- `check.attestation.clock.skew` - Clock skew sanity check
- `check.attestation.offline.bundle` - Offline bundle availability
3. **Verification plugin** (`stellaops.doctor.verification`) - NEW:
- `check.verification.artifact.pull` - Test artifact pull
- `check.verification.signature` - Signature verification
- `check.verification.sbom.validation` - SBOM validation
- `check.verification.vex.validation` - VEX validation
- `check.verification.policy.engine` - Policy engine evaluation
Implementation files:
- `src/__Libraries/StellaOps.Doctor.Plugins.Attestation/`
- `src/__Libraries/StellaOps.Doctor.Plugins.Verification/`
- `docs/doctor/README.md` (updated with new checks)