Files
git.stella-ops.org/docs/modules/attestor/proof-chain-specification.md
StellaOps Bot b058dbe031 up
2025-12-14 23:20:14 +02:00

319 lines
16 KiB
Markdown

# Proof and Evidence Chain Technical Specification
**Version**: 1.0
**Status**: Implementation Ready
**Source**: `docs/product-advisories/14-Dec-2025 - Proof and Evidence Chain Technical Reference.md`
**Last Updated**: 2025-12-14
---
## Executive Summary
This specification defines the implementation of a cryptographically verifiable proof chain that links SBOM components to VEX verdicts through signed evidence and reasoning statements. The system provides complete traceability from scan results to policy decisions with deterministic, auditable outputs.
## Architecture Overview
```
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ PROOF CHAIN ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Scanner │──►│ Evidence │──►│ Reasoning │──►│ VEX │ │
│ │ SBOM │ │ Statements │ │ Statements │ │ Verdicts │ │
│ │ (CycloneDX) │ │ │ │ │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ CONTENT-ADDRESSED IDs │ │
│ │ SBOMEntryID | EvidenceID | ReasoningID | VEXVerdictID | ProofBundleID │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ PROOF SPINE │ │
│ │ Merkle aggregation: merkle_root(SBOMEntryID, EvidenceID[], ReasoningID, │ │
│ │ VEXVerdictID) = ProofBundleID │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ DSSE ENVELOPES │ │
│ │ - In-toto Statement/v1 format │ │
│ │ - Signed by role-specific keys │ │
│ │ - Predicate types: evidence.stella/v1, reasoning.stella/v1, │ │
│ │ cdx-vex.stella/v1, proofspine.stella/v1 │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ TRUST ANCHORS │ │
│ │ - Per-dependency anchor (PURL pattern matching) │ │
│ │ - Allowed key IDs for verification │ │
│ │ - Key rotation with historical validity │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ REKOR TRANSPARENCY LOG │ │
│ │ - Inclusion proofs for all DSSE envelopes │ │
│ │ - Checkpoint verification │ │
│ │ - Offline verification support │ │
│ └─────────────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘
```
## Content-Addressed Identifier System
### ID Formats
| ID Type | Format | Example |
|---------|--------|---------|
| ArtifactID | `sha256:<64-hex>` | `sha256:a1b2c3d4e5f6...` |
| SBOMEntryID | `<sbomDigest>:<purl>[@<version>]` | `sha256:91f2ab3c:pkg:npm/lodash@4.17.21` |
| EvidenceID | `sha256:<hash(canonical_json)>` | `sha256:7b8c9d0e...` |
| ReasoningID | `sha256:<hash(canonical_json)>` | `sha256:4a5b6c7d...` |
| VEXVerdictID | `sha256:<hash(canonical_json)>` | `sha256:1f2e3d4c...` |
| ProofBundleID | `sha256:<merkle_root>` | `sha256:9e8d7c6b...` |
| GraphRevisionID | `grv_sha256:<hash>` | `grv_sha256:5a4b3c2d...` |
| TrustAnchorID | `UUID v4` | `550e8400-e29b-41d4-a716-446655440000` |
### Canonicalization Rules
1. **UTF-8 encoding** for all strings
2. **Sorted keys** (lexicographic, case-sensitive)
3. **No insignificant whitespace**
4. **No trailing commas**
5. **Numbers in shortest form**
6. **Deterministic array ordering** (by semantic key: bom-ref, purl)
## DSSE Predicate Types
### 1. Evidence Statement (`evidence.stella/v1`)
```json
{
"predicateType": "evidence.stella/v1",
"predicate": {
"source": "scanner/feed name",
"sourceVersion": "tool version",
"collectionTime": "2025-12-14T00:00:00Z",
"sbomEntryId": "<SBOMEntryID>",
"vulnerabilityId": "CVE-XXXX-YYYY",
"rawFinding": "<pointer or data>",
"evidenceId": "<EvidenceID>"
}
}
```
**Signer**: Scanner/Ingestor key
### 2. Reasoning Statement (`reasoning.stella/v1`)
```json
{
"predicateType": "reasoning.stella/v1",
"predicate": {
"sbomEntryId": "<SBOMEntryID>",
"evidenceIds": ["<EvidenceID>", ...],
"policyVersion": "v2.3.1",
"inputs": {
"currentEvaluationTime": "2025-12-14T00:00:00Z",
"severityThresholds": {...},
"latticeRules": {...}
},
"intermediateFindings": {...},
"reasoningId": "<ReasoningID>"
}
}
```
**Signer**: Policy/Authority key
### 3. VEX Verdict Statement (`cdx-vex.stella/v1`)
```json
{
"predicateType": "cdx-vex.stella/v1",
"predicate": {
"sbomEntryId": "<SBOMEntryID>",
"vulnerabilityId": "CVE-XXXX-YYYY",
"status": "not_affected|affected|fixed|under_investigation",
"justification": "vulnerable_code_not_in_execute_path",
"policyVersion": "v2.3.1",
"reasoningId": "<ReasoningID>",
"vexVerdictId": "<VEXVerdictID>"
}
}
```
**Signer**: VEXer/Vendor key
### 4. Proof Spine Statement (`proofspine.stella/v1`)
```json
{
"predicateType": "proofspine.stella/v1",
"predicate": {
"sbomEntryId": "<SBOMEntryID>",
"evidenceIds": ["<ID1>", "<ID2>"],
"reasoningId": "<ID>",
"vexVerdictId": "<ID>",
"policyVersion": "v2.3.1",
"proofBundleId": "<ProofBundleID>"
}
}
```
**Signer**: Authority key
### 5. Verdict Receipt Statement (`verdict.stella/v1`)
```json
{
"predicateType": "verdict.stella/v1",
"predicate": {
"graphRevisionId": "<GraphRevisionID>",
"findingKey": {"sbomEntryId": "<ID>", "vulnerabilityId": "CVE-..."},
"rule": {"id": "POLICY-RULE-123", "version": "v2.3.1"},
"decision": {"status": "block|warn|pass", "reason": "..."},
"inputs": {"sbomDigest": "sha256:...", "feedsDigest": "sha256:...", "policyDigest": "sha256:..."},
"outputs": {"proofBundleId": "<ID>", "reasoningId": "<ID>", "vexVerdictId": "<ID>"},
"createdAt": "2025-12-14T00:00:00Z"
}
}
```
**Signer**: Authority key
### 6. SBOM Linkage Statement (`sbom-linkage/v1`)
```json
{
"predicateType": "https://stella-ops.org/predicates/sbom-linkage/v1",
"predicate": {
"sbom": {"id": "<sbomId>", "format": "CycloneDX", "specVersion": "1.6", ...},
"generator": {"name": "StellaOps.Sbomer", "version": "x.y.z"},
"generatedAt": "2025-12-14T00:00:00Z",
"incompleteSubjects": [],
"tags": {"tenantId": "...", "projectId": "...", "pipelineRunId": "..."}
}
}
```
**Signer**: Generator key
## Database Schema
### Tables
| Table | Purpose |
|-------|---------|
| `proofchain.sbom_entries` | SBOM component entries with content-addressed IDs |
| `proofchain.dsse_envelopes` | Signed DSSE envelopes by predicate type |
| `proofchain.spines` | Proof spine aggregations linking evidence to verdicts |
| `proofchain.trust_anchors` | Trust anchor configurations for verification |
| `proofchain.rekor_entries` | Rekor transparency log entries |
| `proofchain.key_history` | Key lifecycle history for rotation |
| `proofchain.key_audit_log` | Audit log for key operations |
## API Endpoints
| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/proofs/{entry}/spine` | POST | Create proof spine |
| `/proofs/{entry}/receipt` | GET | Get verification receipt |
| `/proofs/{entry}/vex` | GET | Get VEX document |
| `/anchors/{anchor}` | GET/PUT | Trust anchor management |
| `/anchors/{anchor}/keys` | GET/POST | Key management |
| `/anchors/{anchor}/keys/{keyid}/revoke` | POST | Key revocation |
| `/verify` | POST | Artifact verification |
| `/keys/rotation-warnings` | GET | Rotation warnings |
## CLI Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success - no policy violations |
| 1 | Policy violation detected |
| 2 | System/scanner error |
## Verification Pipeline
The 13-step verification algorithm:
1. Resolve SBOMEntryID → TrustAnchorID
2. Fetch spine and trust anchor
3. Verify spine DSSE signature against TrustAnchor.allowedKeyids
4. Verify VEX DSSE signature
5. Verify reasoning DSSE signature
6. Verify evidence DSSE signatures
7. Recompute EvidenceIDs from stored canonical evidence
8. Recompute ReasoningID from reasoning
9. Recompute VEXVerdictID from VEX body
10. Recompute ProofBundleID (merkle root) from above
11. Compare all computed IDs to stored IDs
12. If using Rekor: verify log inclusion proof
13. Emit Receipt
## Key Rotation
### Process
1. Add new key to TrustAnchor.allowedKeyids
2. Transition period: both keys valid
3. Optionally revoke old key (moves to revokedKeys)
4. Publish key material via attestation feed
### Invariants
- Never mutate old DSSE envelopes
- Revoked keys remain valid for proofs signed before revocation
- All key changes are audited
## Implementation Sprints
| Sprint | Focus | Status |
|--------|-------|--------|
| 0501.2 | Content-Addressed IDs & Core Records | TODO |
| 0501.3 | New DSSE Predicate Types | TODO |
| 0501.4 | Proof Spine Assembly | TODO |
| 0501.5 | API Surface & Verification Pipeline | TODO |
| 0501.6 | Database Schema Implementation | TODO |
| 0501.7 | CLI Integration & Exit Codes | TODO |
| 0501.8 | Key Rotation & Trust Anchors | TODO |
## Related Documents
- [Master Sprint Plan](../../implplan/SPRINT_0501_0001_0001_proof_evidence_chain_master.md)
- [Content-Addressed IDs Sprint](../../implplan/SPRINT_0501_0002_0001_proof_chain_content_addressed_ids.md)
- [DSSE Predicates Sprint](../../implplan/SPRINT_0501_0003_0001_proof_chain_dsse_predicates.md)
- [Proof Spine Assembly Sprint](../../implplan/SPRINT_0501_0004_0001_proof_chain_spine_assembly.md)
- [API Surface Sprint](../../implplan/SPRINT_0501_0005_0001_proof_chain_api_surface.md)
- [Database Schema Sprint](../../implplan/SPRINT_0501_0006_0001_proof_chain_database_schema.md)
- [CLI Integration Sprint](../../implplan/SPRINT_0501_0007_0001_proof_chain_cli_integration.md)
- [Key Rotation Sprint](../../implplan/SPRINT_0501_0008_0001_proof_chain_key_rotation.md)
- [Attestor Architecture](./architecture.md)
- [Signer Architecture](../signer/architecture.md)
- [Database Specification](../../db/SPECIFICATION.md)
## Cryptographic Profiles
| Profile | Algorithm | Use Case |
|---------|-----------|----------|
| default | SHA256-ED25519 | General purpose |
| fips | SHA256-ECDSA-P256 | FIPS 140-2/3 compliance |
| gost | GOST R 34.10-2012 | Russian regulatory |
| sm | SM2/SM3 | Chinese standards |
| pqc | SHA256-DILITHIUM3 | Post-quantum |
## Determinism Constraints
### Non-Negotiable Invariants
1. **Immutability**: DSSE envelopes are append-only
2. **Determinism**: Same inputs → same outputs
3. **Traceability**: Every verdict traceable to evidence
4. **Least Trust**: Explicit trust via TrustAnchors only
5. **Backward Compatibility**: New code verifies old proofs
### Temporal Handling
- UTC ISO-8601 only
- No local time
- Timestamps only when semantically required
- Derivation from content preferred over wall-clock time
---
**Document Version**: 1.0
**Target Platform**: .NET 10, PostgreSQL ≥16, Angular v17