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

7.4 KiB

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:hashcomponent.hashes[] Yes
SBOM Component VEX Product component.purlstatement.products[].purl Yes
VEX Statement Policy Input statement.cvepolicy.advisoryId Yes
Binary Evidence VEX Justification evidence:patch-sigjustification.patchSignature No

Required SBOM Evidence Properties

For binary evidence to flow through the pipeline, components MUST include:

{
  "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:

{
  "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:

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