Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
131 lines
7.2 KiB
Markdown
131 lines
7.2 KiB
Markdown
# CVSS v4.0 Receipts – Hardening Guide
|
||
|
||
Source advisory: `docs/product-advisories/25-Nov-2025 - Add CVSS v4.0 Score Receipts for Transparency.md` (CV1–CV10). This guide turns the gaps into implementable rules for Sprint 0190.
|
||
|
||
## Canonical hashing (CV2)
|
||
- Serializer: JSON Canonicalization Scheme (JCS).
|
||
- Ordering: lexicographic keys; arrays keep order; drop nulls.
|
||
- 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/` (`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.
|
||
- On change, emit new receipts with `supersedesReceiptId` and retain old ones.
|
||
- Backfill job: re-score under new policy, append history, re-sign DSSE.
|
||
|
||
## Tenant segregation & RBAC (CV4, CV9)
|
||
- Storage keys include `tenantId`; hashes/DSSE annotate tenant.
|
||
- Roles: Security Engineer (Base), SOC Analyst (Threat), Customer Admin (Env), Viewer (read-only).
|
||
- Enforce at API/repo layer and in canonical hash.
|
||
|
||
## 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: `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.
|
||
- Add backfill job + history persistence.
|
||
- Enforce tenant/RBAC and annotate hashes/DSSE.
|
||
- Implement deterministic PDF export and record `exportHash`.
|
||
- Store conversion metadata for v3.1 sources.
|
||
- Verify evidence CAS/DSSE on ingest; fail closed.
|
||
- Expose metrics/alerts listed above.
|
||
|
||
## Receipt model (API shape)
|
||
- `receiptId`, `schemaVersion`, `format`, `vulnerabilityId`, `tenantId`, `createdAt/by`, `modifiedAt/by`.
|
||
- Metric inputs: `baseMetrics`, optional `threatMetrics` and `environmentalMetrics`, optional `supplementalMetrics`.
|
||
- Computed outputs: `scores` (base/threat/environmental/full plus `effectiveScore` and `effectiveScoreType`), `vectorString`, `severity`.
|
||
- Policy link: `policyRef { policyId, version, hash, activatedAt }` plus `inputHash` (JCS + SHA-256) and optional `exportHash`.
|
||
- Evidence: `evidence[]` (type, uri, description, source, collectedAt, dsseRef, isAuthoritative, isRedacted, verifiedAt, retentionClass).
|
||
- Attestation + history: `attestationRefs[]` (DSSE envelopes), `history[]` (field, previousValue, newValue, actor, reason, referenceUri, when), `amendsReceiptId`, `supersedesReceiptId`, `isActive`.
|
||
|
||
## Gateway API (Policy Engine via Gateway)
|
||
- Base path: `/api/cvss` (Policy Gateway). Scopes: `policy.run` for create/amend; `findings.read` for read/history/policies.
|
||
- Endpoints:
|
||
- `POST /api/cvss/receipts` – Create a receipt and optional DSSE envelope.
|
||
- `GET /api/cvss/receipts/{id}` – Fetch the latest receipt with scores, evidence, and hashes.
|
||
- `PUT /api/cvss/receipts/{id}/amend` – Append a history entry (e.g., policy change, evidence fix); re-sign when `signingKey` is provided.
|
||
- `GET /api/cvss/receipts/{id}/history` – Return ordered history entries for the receipt.
|
||
- `GET /api/cvss/policies` – List available `CvssPolicy` documents (id/version/hash/effective window).
|
||
|
||
**Create receipt (minimal example)**
|
||
|
||
```
|
||
POST /api/cvss/receipts
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"vulnerabilityId": "CVE-2025-1234",
|
||
"policy": {
|
||
"policyId": "default",
|
||
"version": "1.0.0",
|
||
"name": "Default CVSS policy",
|
||
"effectiveFrom": "2025-12-01T00:00:00Z",
|
||
"hash": "sha256:..."
|
||
},
|
||
"baseMetrics": { "av": "Network", "ac": "Low", "at": "None", "pr": "None", "ui": "None", "vc": "High", "vi": "High", "va": "High", "sc": "High", "si": "High", "sa": "High" },
|
||
"environmentalMetrics": { "cr": "High", "ir": "High", "ar": "Medium" },
|
||
"signingKey": { "keyId": "cvss-dev", "store": "local" },
|
||
"createdBy": "cli"
|
||
}
|
||
```
|
||
|
||
**Response 200 (abridged)**
|
||
|
||
```json
|
||
{
|
||
"receiptId": "cvss-20251207-01",
|
||
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/CR:H/IR:H/AR:M",
|
||
"scores": { "baseScore": 9.3, "threatScore": 9.3, "environmentalScore": 9.1, "fullScore": 9.1, "effectiveScore": 9.1, "effectiveScoreType": "Environmental" },
|
||
"severity": "Critical",
|
||
"policyRef": { "policyId": "default", "version": "1.0.0", "hash": "sha256:..." },
|
||
"inputHash": "sha256:...",
|
||
"attestationRefs": ["dsse:stella.ops/cvssReceipt@v1/sha256:..."],
|
||
"evidence": [],
|
||
"history": []
|
||
}
|
||
```
|
||
|
||
## CLI and UI usage
|
||
- CLI (`stella cvss ...` via `src/Cli/StellaOps.Cli`):
|
||
- `stella cvss score --vuln CVE-2025-1234 --policy-file cvss-policy.json --vector CVSS:4.0/AV:N/... [--json]`
|
||
- `stella cvss show <receiptId> [--json]`
|
||
- `stella cvss history <receiptId> [--json]`
|
||
- `stella cvss export <receiptId> --format json --out cvss-receipt.json`
|
||
- Uses Policy Gateway `/api/cvss/...` endpoints, enforces tenant scoping via `--tenant`/profile, and reuses `CvssV4Engine` locally for vector parsing.
|
||
- Console (`src/Web/StellaOps.Web`):
|
||
- Route `/cvss/receipts/:receiptId` renders a receipt viewer with score badge, vector summary, and tabs for Base/Threat/Environmental/Evidence/Policy/History.
|
||
- Export and "Recalculate with my env" flows reuse the same receipt payload; UI expects deterministic ordering and stable hashes.
|