Add receipt input JSON and SHA256 hash for CVSS policy scoring tests

- Introduced a new JSON fixture `receipt-input.json` containing base, environmental, and threat metrics for CVSS scoring.
- Added corresponding SHA256 hash file `receipt-input.sha256` to ensure integrity of the JSON fixture.
This commit is contained in:
StellaOps Bot
2025-12-04 07:30:42 +02:00
parent 2d079d61ed
commit e1262eb916
91 changed files with 19493 additions and 187 deletions

View File

@@ -6,7 +6,7 @@
| EXCITOR-OPS-0001 | DONE (2025-11-07) | Ops Guild | Runbooks/observability checklist added (`mirrors.md`). |
| EXCITOR-ENG-0001 | DONE (2025-11-07) | Module Team | Implementation plan alignment with SPRINT_200 updates. |
| EXCITITOR-DOCS-0001 | BLOCKED (2025-11-19) | Docs Guild | Await chunk API CI validation + OpenAPI freeze before finalizing docs. |
| EXCITITOR-ENG-0001 | TODO | Module Team | Update engineering notes once chunk API/OpenAPI unblock. |
| EXCITITOR-OPS-0001 | TODO | Ops Guild | Sync observability/runbook updates after OpenAPI freeze. |
| EXCITITOR-ENG-0001 | BLOCKED (2025-12-03) | Module Team | Blocked by EXCITITOR-DOCS-0001 (chunk API CI/OpenAPI freeze). |
| EXCITITOR-OPS-0001 | BLOCKED (2025-12-03) | Ops Guild | Blocked by EXCITITOR-DOCS-0001; update runbooks once OpenAPI freezes. |
> Keep this table in lockstep with `docs/implplan/SPRINT_0333_0001_0001_docs_modules_excititor.md` (TODO/DOING/DONE/BLOCKED updates go to both files).

View File

@@ -8,7 +8,16 @@ Source advisory: `docs/product-advisories/25-Nov-2025 - Add CVSSv4.0 Score Re
- Numbers: fixed 4-decimal precision; invariant culture; no exponent.
- Time: UTC ISO-8601 `Z`; strip milliseconds unless non-zero.
- Hash: SHA-256 of canonical JSON; store as `inputsHash` and DSSE subject.
- Test vectors: `tests/Policy/StellaOps.Policy.Scoring.Tests/Fixtures/hashing/`.
- Test vectors: `tests/Policy/StellaOps.Policy.Scoring.Tests/Fixtures/hashing/` (`receipt-input.json` + `receipt-input.sha256`).
- Recompute locally:
```bash
python - <<'PY'
import json, hashlib, pathlib
data=json.loads(pathlib.Path('tests/Policy/StellaOps.Policy.Scoring.Tests/Fixtures/hashing/receipt-input.json').read_text())
canon=json.dumps(data, sort_keys=True, separators=(',', ':'), ensure_ascii=False)
print(hashlib.sha256(canon.encode()).hexdigest())
PY
```
## Policy replay & backfill (CV1)
- Policies immutable; bump version for any change.
@@ -23,21 +32,26 @@ Source advisory: `docs/product-advisories/25-Nov-2025 - Add CVSSv4.0 Score Re
## Deterministic exports (CV8)
- JSON export: JCS ordering, UTF-8, UTC timestamps, stable severity palette.
- PDF export: embed fonts (Source Sans 3 + Roboto Mono), A4, fixed margins; hash PDF bytes and persist `exportHash`.
- Offline receipt bundle: include JSON, PDF, DSSE envelope, and policy hash; tar with sorted names + fixed mtime.
## v3.1 → v4.0 conversion (CV5)
- Deterministic mapping; tag `source: "converted-v3.1"`, set `conversionMethod` + `confidence`; retain vendor vector.
- Record `conversionHash` of the original v3.1 vector (JCS + SHA-256) and store in receipt history for audit.
## Evidence provenance (CV6)
- Evidence items use CAS URIs + DSSE refs, include `retentionClass`, `redactionStatus`, `verifiedAt`, `hashMismatch`.
- Receipt schema enforces evidence array; DSSE subject hash must match `inputsHash`.
## Immutability & monitoring (CV7, CV10)
- Receipts append-only; amendments create new IDs + DSSE.
- Alerts: DSSE verify failures, policy hash drift, hash mismatch, engine version skew. Prometheus counters: `cvss_receipt_dsse_failures_total`, `cvss_policy_drift_total`, `cvss_hash_mismatch_total`.
- Receipt history includes `supersedesReceiptId` and `amendsReceiptId`; policy backfill job must set `supersedesReceiptId` when replaying.
- Dashboard SLO: DSSE failure rate <0.1% per 24h; policy drift alerts page security on-call.
## Golden fixtures & locations
- Hashing vectors: `src/Policy/__Tests/StellaOps.Policy.Scoring.Tests/Fixtures/hashing/example-receipt-input.json` with expected hash `example-receipt-input.sha256`.
- Receipts/exports under `tests/Policy/StellaOps.Policy.Scoring.Tests/Fixtures/` (expand as features land).
- Sample PDFs in `Fixtures/exports/` once generated.
- Hashing vectors: `tests/Policy/StellaOps.Policy.Scoring.Tests/Fixtures/hashing/receipt-input.json` with expected hash `receipt-input.sha256`.
- Receipt DSSE/PDF examples to live under `tests/Policy/StellaOps.Policy.Scoring.Tests/Fixtures/receipts/` as exports land.
- Sample PDFs in `Fixtures/exports/` once generated; hash each to `*.pdf.sha256`.
## Implementation checklist
- Wire `ReceiptCanonicalizer` to JCS rules above.

View File

@@ -16,6 +16,8 @@ This directory contains deep technical designs for current and upcoming analyzer
## OS ecosystem designs
- `macos-analyzer.md` — Homebrew, pkgutil, `.app` bundle plan.
- `windows-analyzer.md` — MSI, WinSxS, Chocolatey, registry collectors.
- `cdx17-cbom-contract.md` — deterministic CycloneDX 1.7 + CBOM export profile (ordering, hashes, downgrade rules).
- `slsa-source-track.md` — deterministic SLSA Source Track capture (repo/ref/commit, tree hash, invocation hash, provenance DSSE, CAS paths).
## Demand & dashboards
- `../../benchmarks/scanner/windows-macos-demand.md` — demand tracker.

View File

@@ -0,0 +1,47 @@
# CycloneDX 1.7 + CBOM Export Contract (SC2)
Scope: Defines the deterministic export profile for CycloneDX 1.7 BOMs enriched with Cloud BOM (CBOM) signals that Scanner emits and Replay consumes. Covers ordering, required fields, CBOM properties, hash/DSSE anchoring, and downgrade rules to 1.6.
## Profile
- `bomFormat: CycloneDX`, `specVersion: 1.7`, `version: 1`, `serialNumber: urn:uuid:` (v4, lower-case, fixed length).
- Canonicalization: JSON with lexicographic object keys, stable array ordering, UTF-8, no insignificant whitespace when hashing. Use BLAKE3-256 primary hash and SHA-256 secondary.
- Timestamps: UTC ISO-8601 `Z`; strip milliseconds unless non-zero.
- Hash fields: `metadata.component.hashes[*]`, component hashes; attach `properties` `evidence:hash` for CAS subject; include DSSE envelope digest in `metadata.properties` (`provenance.dsse`).
## Required sections
- **metadata.component**: root application/service with `type`, `name`, `version`, `purl`, hashes, and `evidence.properties` (`evidence:source`, `evidence:hash`).
- **metadata.properties** (CBOM + provenance):
- `source.repo`, `source.ref`, `build.id`, `build.invocation.hash`, `provenance.dsse`.
- **metadata.tools**: at least one entry with `vendor`, `name`, `version`; include `properties` for deterministic seeds if applicable.
- **services[]**: CBOM ingress/egress per service using `properties` namespaced `cbom:*` (e.g., `cbom:ingress`, `cbom:egress`, `cbom:data.classification`).
- **components[]**: libraries/artifacts with `type`, `name`, `version`, `purl`, `hashes`. Optional CBOM properties allowed (`cbom:region`, `cbom:provider`).
- **vulnerabilities[]**: must carry both CVSS v4 (`method: CVSSv4`) and v3.1 ratings when available; include `properties` `evidence:source`, `evidence:proof-id`, `evidence:hash`.
## Ordering rules
1. Top-level keys: `bomFormat`, `specVersion`, `serialNumber`, `version`, `metadata`, `services`, `components`, `vulnerabilities`.
2. Arrays sorted by `name` then `purl` (components/services) and by `id` for vulnerabilities.
3. Hash lists sorted by `alg`; properties sorted by `name`.
4. Ratings sorted by `method` (CVSSv4 first, then CVSSv3.1, then others).
## Deterministic hashing
- Compute `bomHash` = BLAKE3-256 over canonical JSON; record in DSSE subject.
- For downgrade tests, also compute SHA-256 and record in `hashes.txt` (see fixtures).
## Downgrade to 1.6
- Remove CBOM namespaced properties; preserve non-CBOM properties.
- Drop CVSS v4 ratings; keep v3.1 and mark `x-stellaops:cvss4-dropped: true` in `vulnerabilities[].properties` for audit.
- Preserve component/service ordering; recompute hashes; record downgrade hash alongside 1.7 hash (`hashes.txt`).
## Evidence linkage
- Every `evidence:hash` must reference a CAS object (BLAKE3 URI or sha256) present in replay bundle manifests.
- `provenance.dsse` must point to DSSE envelope hash for the build/provenance statement; verifier should fail closed when missing.
## CI expectations
- Validate against CycloneDX 1.7 JSON schema.
- Determinism check: render BOM twice → identical hashes and ordering.
- Verify fixture hashes in `docs/modules/scanner/fixtures/cdx17-cbom/hashes.txt`.
## Fixtures
- 1.7 reference: `docs/modules/scanner/fixtures/cdx17-cbom/sample-cdx17-cbom.json`.
- 1.6 downgrade: `docs/modules/scanner/fixtures/cdx17-cbom/sample-cdx16.json`.
- Hashes: `docs/modules/scanner/fixtures/cdx17-cbom/hashes.txt` (BLAKE3, SHA256 for both).

View File

@@ -0,0 +1,60 @@
# SLSA Source Track Capture (SC3)
Status: Draft · Date: 2025-12-03
Scope: Define deterministic capture of SLSA Source Track data for replay bundles and CycloneDX 1.7 + CBOM exports. Aligns Scanner record/replay with provenance signals (build-id, repo/ref, provenance DSSE).
## Objectives
- Persist source provenance required by SLSA 1.2 Source Track: repo URI, resolved ref, digest of checked-out tree, invocation hash, builder ID, and reproducible build inputs.
- Make data replayable offline: no network fetch; hashes + DSSE envelope paths must resolve locally.
- Keep ordering/hashes deterministic: canonical JSON (sorted keys), BLAKE3-256 primary hash, SHA-256 secondary.
## Minimal fields (per build)
- `source.repo`: canonical URI (https, ssh); normalized to lower-case host; trailing slash stripped.
- `source.ref`: fully qualified ref (`refs/heads/main`, tag, or immutable commit).
- `source.commit`: 40-hex commit digest.
- `source.treeHash`: BLAKE3-256 of source tree snapshot (stable archive); optional SHA-256 mirror.
- `build.invocation.hash`: BLAKE3-256 of normalized invocation (args/env/tool versions); also store `build.invocation.dsse` hash when signed.
- `builder.id`: URI for builder identity (SLSA-style).
- `provenance.dsse`: SHA-256 of DSSE envelope for provenance statement (e.g., in-toto SLSA provenance v1.0). Optionally include BLAKE3 and CAS URI.
## JSON shape (suggested)
```json
{
"source": {
"repo": "https://example.invalid/demo",
"ref": "refs/tags/v1.0.0",
"commit": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"treeHash": "b3:1111...",
"builderId": "https://builder.stellaops.local/scanner",
"invocationHash": "b3:2222...",
"invocationDsse": "sha256:3333...",
"provenance": {
"dsse": "sha256:4444...",
"cas": "cas://provenance/demo/v1.0.0.dsse"
}
}
}
```
## Where to store
- CycloneDX 1.7 + CBOM: encode under `metadata.properties` using namespaced keys:
- `source.repo`, `source.ref`, `source.commit`, `source.tree.hash`, `builder.id`, `build.invocation.hash`, `build.invocation.dsse`, `provenance.dsse`, `provenance.cas`.
- Replay manifest: add `source` block mirroring the JSON shape above; include hashes in manifest subject list.
- CAS: store provenance DSSE envelope under `cas://provenance/{component}/{version}.dsse`; store tree snapshot tarball under `cas://source/{commit}.tar.gz`.
## Determinism rules
- Canonical JSON (lexicographic keys, UTF-8, no pretty-print) before hashing.
- Timestamps in provenance statements must be UTC `Z`; strip milliseconds unless non-zero.
- All hashes recorded with algorithm prefix (`b3:` for BLAKE3-256, `sha256:` for SHA-256).
## Verification
- Verifier MUST: (1) schema-check fields are present; (2) recompute `treeHash` from tree tarball; (3) recompute `build.invocation.hash` from normalized invocation file; (4) verify DSSE envelope hash matches `provenance.dsse` and signature keys; (5) ensure repo/ref/commit are consistent (ref→commit mapping known or provided in bundle).
- Fail closed on any mismatch; never fetch network.
## Fixtures
- `docs/modules/scanner/fixtures/cdx17-cbom/source-track.sample.json` — deterministic example with placeholder hashes.
- Future: add CAS tarball + invocation file under `tests/reachability/fixtures/source-track/` with recomputation script.
## TODO (outside this doc)
- Implement `scripts/scanner/verify_source_track.py` to validate source-track blocks and CAS payloads offline.
- Extend replay manifest schema to include `source` block; add determinism tests in Scanner replay suite once manifest contract lands.

View File

@@ -2,3 +2,7 @@
- Location for mapping CSVs converting CVSS v4→v3.1, CDX 1.7→1.6, SLSA 1.2→1.0.
- Each CSV must include BLAKE3 and SHA256 hash recorded in accompanying `hashes.txt`.
- Adapters are pure (no network); determinism enforced in CI.
- Files added:
- `mapping-cvss4-to-cvss3.csv`
- `mapping-slsa12-to-slsa10.csv`
- `mapping-cdx17-to-cdx16.csv` (placeholder empty; fill once downgrade rules freeze).

View File

@@ -1 +1,3 @@
mapping-cdx17-to-cdx16.csv: BLAKE3=<TBD> SHA256=<TBD>
mapping-cvss4-to-cvss3.csv blake3-256=fa600b266e696fd84070d2efd8678633366edcff62c4e75e0ffeaac98816c873 sha256=072b66befac9556bc84d81e522938a222c88691db9564af6f220389562f22b0d
mapping-slsa12-to-slsa10.csv blake3-256=b833034769f1ece239a03fb0797bab160ef02d78bb781e7d48b05552d0d27015 sha256=4a3dd0a9c4ed9d5061b8c862b35ba8147da725bf0d2968164c52298a6e1451fd
mapping-cdx17-to-cdx16.csv blake3-256=69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9 sha256=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

View File

@@ -0,0 +1,14 @@
source_field,target_field,rule,notes
AV,AV,"Network->N, Adjacent->A, Local->L, Physical->P","Preserve mapping; CVSS 4 AT handled separately"
AC,AC,"Low->L, High->H",""
PR,PR,"None->N, Low->L, High->H",""
UI,UI,"None->N, Passive->P, Active->A","CVSS3 has R (Required) approximate with A"
VC,C,"High->H, Low->L, None->N","Impact mapping: VC→Confidentiality"
VI,I,"High->H, Low->L, None->N",""
VA,A,"High->H, Low->L, None->N",""
SC,S,"High->C, Low->C, None->U","Scoped impact collapses to Scope Changed/Unchanged; default Changed when SC>None"
SI,S,"High->C, Low->C, None->U","Same as SC"
SA,S,"High->C, Low->C, None->U","Same as SC"
AT,N/A,"drop","Attack requirements not represented in CVSS3"
Threat,Temporal,"map to E: NotDefined","Threat metrics not supported; set Temporal NotDefined"
Environmental,Environmental,"map CR/IR/AR to CR/IR/AR; map MV* to unchanged"
Can't render this file because it has a wrong number of fields in line 14.

View File

@@ -0,0 +1,10 @@
source_field,target_field,rule,notes
builder.id,builder.id,copy,""
builder.version,builder.version,copy,""
invocation.configSource.uri,configSource.uri,copy,""
invocation.configSource.digest,configSource.digest,copy,""
materials[],materials[],copy,"Keep materials but drop integrity fields unsupported in 1.0"
subject[],subject[],copy,""
provenance.dsse,metadata.buildInvocationID,copy,"Use DSSE hash as buildInvocationID placeholder"
metadata.startedOn,metadata.buildStartedOn,copy,""
metadata.finishedOn,metadata.buildFinishedOn,copy,""
1 source_field target_field rule notes
2 builder.id builder.id copy
3 builder.version builder.version copy
4 invocation.configSource.uri configSource.uri copy
5 invocation.configSource.digest configSource.digest copy
6 materials[] materials[] copy Keep materials but drop integrity fields unsupported in 1.0
7 subject[] subject[] copy
8 provenance.dsse metadata.buildInvocationID copy Use DSSE hash as buildInvocationID placeholder
9 metadata.startedOn metadata.buildStartedOn copy
10 metadata.finishedOn metadata.buildFinishedOn copy

View File

@@ -0,0 +1,15 @@
{
"source": {
"repo": "https://example.invalid/demo",
"ref": "refs/tags/v1.0.0",
"commit": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"treeHash": "b3:1111111111111111111111111111111111111111111111111111111111111111",
"builderId": "https://builder.stellaops.local/scanner",
"invocationHash": "b3:2222222222222222222222222222222222222222222222222222222222222222",
"invocationDsse": "sha256:3333333333333333333333333333333333333333333333333333333333333333",
"provenance": {
"dsse": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
"cas": "cas://provenance/demo/v1.0.0.dsse"
}
}
}