Files
git.stella-ops.org/docs/onboarding/dev-quickstart.md
StellaOps Bot 579236bfce
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Add MongoDB storage library and update acceptance tests with deterministic stubs
- Created StellaOps.Notify.Storage.Mongo project with initial configuration.
- Added expected output files for acceptance tests (at1.txt to at10.txt).
- Added fixture input files for acceptance tests (at1 to at10).
- Created input and signature files for test cases fc1 to fc5.
2025-12-05 22:56:01 +02:00

360 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# StellaOps Developer Quickstart
> **Audience:** Mid-level .NET developers
> **Goal:** Get you productive on StellaOps in 12 days, with special focus on determinism, cryptographic attestations, and the canonical data model.
---
This quickstart mirrors the 29-Nov-2025 Developer Onboarding advisory (`docs/product-advisories/29-Nov-2025 - StellaOps Mid-Level .NET Onboarding (Quick Start).md`) and keeps the determinism-first guidance in sync with that release note.
## 1. What Youre Building (Context)
StellaOps is a sovereign, air-gap-friendly platform that turns **SBOMs → VEX** with a fully **replayable, deterministic trust graph**.
Core concepts:
- **Deterministic scans:** Same inputs → same graph, hashes, and verdicts.
- **Cryptographic attestations:** DSSE/in-toto envelopes, optional PQC.
- **Trust lattice:** Merges vendor VEX, runtime signals, configs, etc. into a single deterministic verdict.
- **Audit trail:** Every decision is reproducible from stored inputs and proofs.
**Offline/determinism essentials (read first):**
- Install from the curated offline kit (no network); pin SDK + tool versions in `inputs.lock`.
- Use DSSE-signed configs and keep signing keys in offline `~/.stellaops/keys` with short-lived tokens.
- Run `dotnet format` / `dotnet test` with `--blame-crash --blame-hang` using fixed seeds (`Random(1337)`) to avoid flakiness.
- Capture DB/queue matrix upfront: MongoDB (pinned version), optional Postgres slices, and local cache paths; set `TZ=UTC` for all runs.
If you think “content-addressed trust pipeline for SBOMs + VEX,” youre in the right mental model.
---
## 2. Repository & Docs Map
Start by opening these projects **in order**:
1. `src/StellaOps.Scanner.WebService/`
Scanning endpoints, rule plumbing, and calls into the trust lattice.
2. `src/StellaOps.Vexer/` (a.k.a. *Excititor*)
VEX verdict engine and trust-merge logic.
3. `src/StellaOps.Sbomer/`
SBOM ingest / normalize (CycloneDX, SPDX).
4. `src/StellaOps.Authority/`
Key management, DSSE/in-toto attestations, license tokens, Rekor integration.
5. `src/StellaOps.Scheduler/`
Batch processing, replay orchestration.
6. `src/StellaOps.Shared/CanonicalModel/`
Canonical entities & graph IDs. **Read this carefully** it underpins determinism.
Starter issues to grab on day 1 (all offline-friendly):
- Add DSSE verification to a small CLI path (`stella verify --local-only`).
- Extend `inputs.lock` examples with a pinned scanner/DB matrix.
- Write a deterministic unit test for canonical ID ordering.
- Improve `docs/` cross-links (Developer Quickstart ↔ platform architecture) and ensure `docs:` trailer appears in commits.
UI note: Console remains in flux; focus on backend determinism first, then follow UI sprints 0209/0215 for micro-interactions and proof-linked VEX updates.
## 3. Environment & DB matrix
- MongoDB: 6.0.12 (pin in `inputs.lock`).
- Optional Postgres slices: see sprint 340x series; keep read-only in dev until instructed.
- Offline feeds: `offline-cache-2025-11-30` (scanner, advisories, VEX).
- Timezone: `TZ=UTC` for all tests and tooling.
## 4. Secrets & signing
- Store short-lived signing keys in `~/.stellaops/keys` (gitignored); never commit secrets.
- Use DSSE for pack manifests and fixtures; include signer IDs.
- For Rekor: use mirrored bundle (no live log writes); verify receipts offline.
## 5. Contribution checklist
See `docs/onboarding/contribution-checklist.md` for the minimal gates (docs trailer, seeds, inputs.lock, DSSE, secrets).
Helpful docs:
- `docs/modules/platform/*` protocols (DSSE envelopes, lattice terms, trust receipts).
- `docs/architecture/*` high-level diagrams and flows.
---
## 3. Local Dev Setup
### 3.1 Prerequisites
- **.NET 10 SDK** (preview as specified in repo).
- **Docker** (for DB, queues, object storage).
- **Node.js** (for Angular UI, if youre touching the frontend).
- **WSL2** (optional but convenient on Windows).
### 3.2 Bring Up Infra
From the repo root:
```bash
# Bring up core infra for offline / air-gap friendly dev
docker compose -f compose/offline-kit.yml up -d
```
This usually includes:
- MongoDB or Postgres (configurable).
- RabbitMQ (or equivalent queue).
- MinIO / object storage (depending on profile).
### 3.3 Configure Environment
```bash
cp env/example.local.env .env
```
Key settings:
- `STELLAOPS_DB=Mongo` or `Postgres`.
- `AUTHORITY_*` key material and config (see comments in `example.local.env`).
- Optional: `AUTHORITY_PQC=on` to enable post-quantum keys (Dilithium).
### 3.4 Build & Run Backend
```bash
# Restore & build everything
dotnet restore
dotnet build -c Debug
# Run a focused slice for development
dotnet run --project src/StellaOps.Authority/StellaOps.Authority.csproj
dotnet run --project src/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj
```
Health checks (adjust ports if needed):
```bash
curl -s http://localhost:5080/health # Authority
curl -s http://localhost:5081/health # Scanner
```
---
## 4. Deterministic Sanity Tests
These tests prove your local environment is configured correctly for **determinism**. If any of these fail due to snapshot mismatch, fix your environment before writing new features.
### 4.1 SBOM → VEX “Not Affected” (Reachability False)
```bash
dotnet test tests/Determinism/Det_SbomToVex_NotAffected.csproj
```
**What it checks:**
- Two consecutive runs with the same SBOM produce identical `GraphRevisionID` and DSSE payload hashes.
If they differ, inspect:
- JSON canonicalization.
- Locale / culture.
- Line endings.
### 4.2 In-toto Chain: Source → Build → Image Attestation
```bash
dotnet test tests/Attestations/Att_InToto_Chain.csproj
```
**What it checks:**
- DSSE envelope canonicalization is stable.
- Signature over CBOR-canonical JSON matches the stored hash.
- Full in-toto chain can be replayed deterministically.
### 4.3 Lattice Merge: Vendor VEX + Runtime Signal
```bash
dotnet test tests/Lattice/Lattice_VendorPlusRuntime.csproj
```
**What it checks:**
- Merge verdict is stable regardless of input set order.
- Resulting `TrustReceipt` is byte-for-byte identical between runs.
If any “golden” snapshots differ, you likely have:
- Non-canonical JSON.
- Unstable enumeration (e.g., iterating `Dictionary<>` directly).
- Locale or newline drift.
---
## 5. Coding Conventions (Determinism & Crypto)
These are **non-negotiable** in code that affects trust graphs, proofs, or attestations.
### 5.1 JSON & Canonicalization
- Use the **`CanonicalJson`** helper whenever a payload is hashed, signed, or used for IDs.
- Rules: UTF-8, sorted keys, no insignificant whitespace, `\n` line endings.
### 5.2 DSSE Envelopes
- `payloadType` must always be `application/vnd.stellaops.trust+json`.
- Sign over the canonicalized bytes.
```csharp
var payload = CanonicalJson.Serialize(trustDoc);
var env = DsseEnvelope.Create("application/vnd.stellaops.trust+json", payload);
var signed = await keyRing.SignAsync(env.CanonicalizeBytes());
await rekor.SubmitAsync(signed, RekorMode.OfflineMirrorIfAirgapped);
```
### 5.3 Hashing
- **BLAKE3** for internal content addressing.
- **SHA-256** where interop demands it.
- Never mix algorithms within the same ID type.
### 5.4 Keys & Algorithms
- Default signatures: **Ed25519** via `Authority.KeyRing`.
- Optional PQC: **Dilithium** when `AUTHORITY_PQC=on`.
- Always go through the keyring abstraction; never manage raw keys manually.
### 5.5 Time & Clocks
- Use `Instant`/`DateTimeOffset` (UTC), truncated to milliseconds.
- Never use `DateTime.Now` or local clocks in canonical data.
### 5.6 IDs & Graph Nodes
- Canonical/public IDs derive from hashes of canonical bytes.
- DB primary keys are implementation details.
- Do not depend on DB auto-increment or implicit sort order when hashing.
### 5.7 VEX Verdicts
Every VEX verdict must:
- Carry `proofs[]` (reachability, config guards, runtime paths).
- Emit a `receipt` signed by Authority, covering verdict, proof hashes, and context.
---
## 6. Daily Workflow
1. Pick a focused issue (see starter tasks below).
2. Write tests first, especially determinism scenarios.
3. Implement changes with canonicalization boundaries explicit and signing centralized.
4. Run `dotnet test --filter Category=Determinism`.
5. Commit with the appropriate prefix (`feat(scanner):`, `feat(vexer):`, `feat(authority):`) and mention the affected `GraphRevisionID` if your change alters the trust graph.
---
## 7. Suggested Starter Tasks
These introduce the canonical data model and determinism mindset.
### 7.1 Normalize CycloneDX Components → Canonical Packages
**Area:** `StellaOps.Sbomer`
**Tests:** `tests/Determinism/Det_SbomMapping`
**Definition of done:**
- Equivalent SBOMs (even if fields shuffle) yield identical package sets and canonical IDs.
- `CanonicalPackageSet.hash` is stable.
- Edge cases covered: missing `purl`, duplicate components, case variation.
### 7.2 Implement “Not-Affected by Configuration” Proof
**Area:** `StellaOps.Vexer/Proofs/ConfigSwitchProof.cs`
**Definition of done:**
- With `FeatureX=false`, CVE-1234 reports `status = not_affected` and the proof records `configPath` + `observed=false`.
- Proof hash is deterministic and included in the DSSE receipt.
- Lattice merge flips the verdict to `not_affected` when the runtime/config proof weight crosses the threshold, even if the vendor says `affected`.
### 7.3 Authority Offline Rekor Mirror Submitter
**Area:** `StellaOps.Authority/Rekor/RekorMirrorClient.cs`
**Definition of done:**
- `RekorMode.OfflineMirrorIfAirgapped` records canonical entries (JSON + hash path) locally.
- `rekor sync` replays entries in order, preserving entry IDs.
- Golden test ensures the same input sequence → same mirror tree hash.
---
## 8. Database Notes (Mongo ↔ Postgres)
- Use `StellaOps.Shared.Persistence` repository interfaces.
- Canonical/public IDs are hash-derived; DB keys are internal details.
- Never rely on DB sort order for anything that affects hashes or verdicts; re-canonicalize before hashing and apply deterministic ordering afterwards.
---
## 9. Common Pitfalls
1. Non-canonical JSON (unsorted keys, extra whitespace, mixed `\r\n`).
2. Local time creeping into proofs (`DateTime.Now`).
3. Unstable GUIDs in tests or canonical entities.
4. Unordered collections (`Dictionary<>` iterations, LINQ without `OrderBy`) while hashing or serializing.
5. Platform drift (Windows vs Linux newline/culture differences) always use invariant culture and `\n` in canonical data.
---
## 10. Useful Commands
### 10.1 Determinism Pack
```bash
# Run determinism-tagged fixtures
dotnet test --filter Category=Determinism
```
Update golden snapshots deliberately:
```bash
dotnet test --filter Category=Determinism -- \
TestRunParameters.Parameter(name="UpdateSnapshots", value="true")
```
### 10.2 Quick API Smoke
```bash
curl -s http://localhost:5080/health
curl -s -X POST \
http://localhost:5081/scan \
-H "Content-Type: application/json" \
-d @samples/nginx.sbom.json
```
### 10.3 Verify DSSE Signature Locally
```bash
dotnet run --project tools/StellaOps.Tools.Verify -- file trust.receipt.json
```
---
## 11. Glossary (Ask-Once)
- **SBOM** Software Bill of Materials (CycloneDX/SPDX).
- **VEX** Vulnerability Exploitability eXchange: verdicts include `affected`, `not_affected`, `under_investigation`.
- **DSSE** Dead Simple Signing Envelope; we sign canonical bytes.
- **In-toto** Supply-chain attestation framework for source → build → artifact chains.
- **Lattice** Rule system merging multiple verdicts/proofs into deterministic outcomes.
- **GraphRevisionID** Hash of the canonical trust graph; acts like a build number for audits.
Welcome aboard. Your best “map” is:
1. Read the CanonicalModel types.
2. Run the determinism tests.
3. Ship one of the starter tasks with deterministic, test-covered changes.
Keep everything **canonical, hashable, and replayable** and youll fit right in.