Files
git.stella-ops.org/docs/modules/scanner/design/binary-evidence-alignment.md
StellaOps Bot 8768c27f30
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Signals DSSE Sign & Evidence Locker / sign-signals-artifacts (push) Has been cancelled
Signals DSSE Sign & Evidence Locker / verify-signatures (push) Has been cancelled
Add signal contracts for reachability, exploitability, trust, and unknown symbols
- Introduced `ReachabilityState`, `RuntimeHit`, `ExploitabilitySignal`, `ReachabilitySignal`, `SignalEnvelope`, `SignalType`, `TrustSignal`, and `UnknownSymbolSignal` records to define various signal types and their properties.
- Implemented JSON serialization attributes for proper data interchange.
- Created project files for the new signal contracts library and corresponding test projects.
- Added deterministic test fixtures for micro-interaction testing.
- Included cryptographic keys for secure operations with cosign.
2025-12-05 00:27:00 +02:00

208 lines
7.4 KiB
Markdown

# 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`