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
7.2 KiB
7.2 KiB
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
inputsHashand DSSE subject. - Test vectors:
tests/Policy/StellaOps.Policy.Scoring.Tests/Fixtures/hashing/(receipt-input.json+receipt-input.sha256). - Recompute locally:
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
supersedesReceiptIdand 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", setconversionMethod+confidence; retain vendor vector. - Record
conversionHashof 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
supersedesReceiptIdandamendsReceiptId; policy backfill job must setsupersedesReceiptIdwhen 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.jsonwith expected hashreceipt-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
ReceiptCanonicalizerto 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, optionalthreatMetricsandenvironmentalMetrics, optionalsupplementalMetrics. - Computed outputs:
scores(base/threat/environmental/full pluseffectiveScoreandeffectiveScoreType),vectorString,severity. - Policy link:
policyRef { policyId, version, hash, activatedAt }plusinputHash(JCS + SHA-256) and optionalexportHash. - 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.runfor create/amend;findings.readfor 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 whensigningKeyis provided.GET /api/cvss/receipts/{id}/history– Return ordered history entries for the receipt.GET /api/cvss/policies– List availableCvssPolicydocuments (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)
{
"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 ...viasrc/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 reusesCvssV4Enginelocally for vector parsing.
- Console (
src/Web/StellaOps.Web):- Route
/cvss/receipts/:receiptIdrenders 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.
- Route