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:
@@ -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).
|
||||
|
||||
@@ -8,7 +8,16 @@ Source advisory: `docs/product-advisories/25-Nov-2025 - Add CVSS v4.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 CVSS v4.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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
47
docs/modules/scanner/design/cdx17-cbom-contract.md
Normal file
47
docs/modules/scanner/design/cdx17-cbom-contract.md
Normal 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).
|
||||
60
docs/modules/scanner/design/slsa-source-track.md
Normal file
60
docs/modules/scanner/design/slsa-source-track.md
Normal 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.
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
@@ -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,""
|
||||
|
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user