# Binary Evidence Alignment with SBOM/VEX Outputs (SC6) Status: Draft · Date: 2025-12-04 Scope: Define how binary-level evidence (build-id, symbols, patch oracle) aligns with SBOM/VEX outputs to feed policy engines and VEX decisioning. ## Objectives - Link binary-level evidence to SBOM component identities. - Ensure evidence fields are available for policy/VEX correlation. - Define required joins between binary analysis and vulnerability data. - Enable deterministic evidence chain from binary → SBOM → VEX → policy. ## Evidence Types ### Build Identity Evidence | Evidence Type | Source | SBOM Field | VEX Field | Policy Input | |---------------|--------|------------|-----------|--------------| | Build ID | ELF `.note.gnu.build-id` | `component.properties[evidence:build-id]` | `statement.products[].identifiers.buildId` | `binary.buildId` | | Go Build Info | `runtime.BuildInfo` | `component.properties[evidence:go-build]` | n/a | `binary.goBuildInfo` | | PE Version | PE resource section | `component.properties[evidence:pe-version]` | n/a | `binary.peVersion` | | Mach-O UUID | LC_UUID command | `component.properties[evidence:macho-uuid]` | n/a | `binary.machoUuid` | ### Symbol Evidence | Evidence Type | Source | SBOM Field | VEX Field | Policy Input | |---------------|--------|------------|-----------|--------------| | Exported Symbols | ELF `.dynsym` / PE exports | `component.properties[evidence:symbols-hash]` | n/a | `binary.symbolsHash` | | Debug Symbols | DWARF / PDB | `component.properties[evidence:debug-hash]` | n/a | `binary.debugHash` | | Function Names | Symbol table | `component.properties[evidence:functions]` | `statement.justification.functions` | `binary.functions[]` | ### Patch Oracle Evidence | Evidence Type | Source | SBOM Field | VEX Field | Policy Input | |---------------|--------|------------|-----------|--------------| | Patch Signature | Function hash diff | `component.properties[evidence:patch-sig]` | `statement.justification.patchSignature` | `patch.signature` | | CVE Fix Commit | Commit mapping | `component.properties[evidence:fix-commit]` | `statement.justification.fixCommit` | `patch.fixCommit` | | Binary Diff | objdiff hash | `component.properties[evidence:binary-diff]` | n/a | `patch.binaryDiffHash` | ## Evidence Chain ``` Binary → SBOM Component → VEX Statement → Policy Evaluation │ │ │ │ │ │ │ └── policy://input/component/{purl} │ │ └── vex://statement/{cve}/{product} │ └── sbom://component/{purl} └── binary://evidence/{hash} ``` ### Join Keys | Source | Target | Join Field | Required | |--------|--------|------------|----------| | Binary | SBOM Component | `evidence:hash` → `component.hashes[]` | Yes | | SBOM Component | VEX Product | `component.purl` → `statement.products[].purl` | Yes | | VEX Statement | Policy Input | `statement.cve` → `policy.advisoryId` | Yes | | Binary Evidence | VEX Justification | `evidence:patch-sig` → `justification.patchSignature` | No | ## Required SBOM Evidence Properties For binary evidence to flow through the pipeline, components MUST include: ```json { "type": "library", "name": "openssl", "version": "3.0.0", "purl": "pkg:generic/openssl@3.0.0", "hashes": [ {"alg": "SHA-256", "content": "..."} ], "properties": [ {"name": "evidence:hash", "value": "b3:..."}, {"name": "evidence:source", "value": "scanner:binary-analyzer:v1.0.0"}, {"name": "evidence:build-id", "value": "abc123..."}, {"name": "evidence:symbols-hash", "value": "b3:..."}, {"name": "evidence:patch-sig", "value": "b3:..."}, {"name": "evidence:confidence", "value": "0.95"} ] } ``` ## VEX Integration VEX statements can reference binary evidence for justification: ```json { "vulnerability": "CVE-2025-0001", "products": [ { "purl": "pkg:generic/openssl@3.0.0", "identifiers": { "buildId": "abc123...", "evidenceHash": "b3:..." } } ], "status": "not_affected", "justification": { "category": "vulnerable_code_not_present", "patchSignature": "b3:...", "fixCommit": "deadbeef...", "functions": ["EVP_EncryptUpdate", "EVP_DecryptUpdate"], "evidenceRef": "cas://evidence/openssl/3.0.0/binary-analysis.json" } } ``` ## Policy Engine Integration Policy rules can reference binary evidence fields: ```rego # policy/scanner/binary-evidence.rego package scanner.binary import rego.v1 # Require build-id for high-severity vulns deny contains msg if { input.vulnerability.severity == "critical" not input.component.properties["evidence:build-id"] msg := sprintf("Critical vuln %s requires build-id evidence", [input.vulnerability.id]) } # Accept patch oracle evidence as mitigation allow contains decision if { input.component.properties["evidence:patch-sig"] input.vex.status == "not_affected" input.vex.justification.patchSignature == input.component.properties["evidence:patch-sig"] decision := { "action": "accept", "reason": "Patch signature verified", "confidence": input.component.properties["evidence:confidence"] } } # Confidence threshold for binary analysis warn contains msg if { conf := to_number(input.component.properties["evidence:confidence"]) conf < 0.8 msg := sprintf("Low confidence (%v) binary evidence for %s", [conf, input.component.purl]) } ``` ## Evidence Fields by Binary Format ### ELF (Linux) | Section | Evidence Extracted | Deterministic | |---------|-------------------|---------------| | `.note.gnu.build-id` | Build ID (SHA1/UUID) | Yes | | `.gnu.hash` | Symbol hash table | Yes | | `.dynsym` | Dynamic symbols | Yes | | `.debug_info` | DWARF debug symbols | Yes | | `.rodata` | String literals | Yes | ### PE (Windows) | Section | Evidence Extracted | Deterministic | |---------|-------------------|---------------| | PE Header | Timestamp, Machine type | Partial* | | Resource | Version info, Product name | Yes | | Export Table | Exported functions | Yes | | Import Table | Dependencies | Yes | | Debug Directory | PDB path, GUID | Yes | *PE timestamp may be zeroed for reproducible builds ### Mach-O (macOS) | Command | Evidence Extracted | Deterministic | |---------|-------------------|---------------| | LC_UUID | Binary UUID | Yes | | LC_VERSION_MIN | Min OS version | Yes | | LC_BUILD_VERSION | Build version | Yes | | LC_CODE_SIGNATURE | Code signature | Yes | | SYMTAB | Symbol table | Yes | ## Determinism Requirements 1. **Stable ordering**: Evidence properties sorted by name 2. **Hash computation**: BLAKE3-256 over canonical JSON 3. **Confidence scores**: 4 decimal places, `MidpointRounding.ToZero` 4. **Function lists**: Sorted lexicographically, deduplicated 5. **Symbol hashes**: Computed over sorted symbol names ## CAS Storage Binary evidence artifacts stored in CAS: ``` cas://evidence/{component}/{version}/ ├── binary-analysis.json # Full analysis result ├── symbols.txt # Extracted symbols (sorted) ├── functions.txt # Extracted functions (sorted) └── patch-signatures.json # Patch oracle signatures ``` ## Links - Sprint: `docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md` (SC6) - Roadmap: `docs/modules/scanner/design/standards-convergence-roadmap.md` (SC1) - Contract: `docs/modules/scanner/design/cdx17-cbom-contract.md` (SC2) - Entropy: `docs/modules/scanner/entropy.md`