Files
git.stella-ops.org/docs/modules/attestor/fix-chain-predicate.md
master 7f7eb8b228 Complete batch 012 (golden set diff) and 013 (advisory chat), fix build errors
Sprints completed:
- SPRINT_20260110_012_* (golden set diff layer - 10 sprints)
- SPRINT_20260110_013_* (advisory chat - 4 sprints)

Build fixes applied:
- Fix namespace conflicts with Microsoft.Extensions.Options.Options.Create
- Fix VexDecisionReachabilityIntegrationTests API drift (major rewrite)
- Fix VexSchemaValidationTests FluentAssertions method name
- Fix FixChainGateIntegrationTests ambiguous type references
- Fix AdvisoryAI test files required properties and namespace aliases
- Add stub types for CveMappingController (ICveSymbolMappingService)
- Fix VerdictBuilderService static context issue

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 10:09:07 +02:00

8.8 KiB

FixChain Attestation Predicate

Sprint: SPRINT_20260110_012_005_ATTESTOR Predicate Type: https://stella-ops.org/predicates/fix-chain/v1 Last Updated: 10-Jan-2026

Overview

The FixChain predicate provides cryptographically verifiable proof that a patch eliminates a vulnerable code path. It bridges the gap between vulnerability disclosure and fix verification by encoding evidence from binary analysis into a DSSE-signed attestation.

Why FixChain?

Current State With FixChain
Trust vendor claims Verify with evidence chain
No attestable fix evidence DSSE-signed fix proofs
Version-based assumptions Binary signature comparison
No air-gap verification Offline-verifiable bundles

Predicate Schema

{
  "$id": "https://stella-ops.org/schemas/predicates/fix-chain/v1",
  "type": "object",
  "required": [
    "cveId", "component", "goldenSetRef", "vulnerableBinary",
    "patchedBinary", "sbomRef", "signatureDiff", "reachability",
    "verdict", "analyzer", "analyzedAt"
  ],
  "properties": {
    "cveId": {
      "description": "CVE or GHSA identifier",
      "pattern": "^CVE-\\d{4}-\\d{4,}$|^GHSA-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}$"
    },
    "component": {
      "description": "Component being verified"
    },
    "goldenSetRef": {
      "description": "Content-addressed reference to golden set definition"
    },
    "vulnerableBinary": {
      "description": "Pre-patch binary identity (SHA-256, architecture)"
    },
    "patchedBinary": {
      "description": "Post-patch binary identity (SHA-256, architecture, PURL)"
    },
    "sbomRef": {
      "description": "Reference to SBOM containing the component"
    },
    "signatureDiff": {
      "description": "Summary of signature differences"
    },
    "reachability": {
      "description": "Reachability analysis outcome"
    },
    "verdict": {
      "description": "Final fix determination",
      "properties": {
        "status": { "enum": ["fixed", "partial", "not_fixed", "inconclusive"] },
        "confidence": { "type": "number", "minimum": 0, "maximum": 1 },
        "rationale": { "type": "array", "items": { "type": "string" } }
      }
    },
    "analyzer": {
      "description": "Analyzer metadata for reproducibility"
    },
    "analyzedAt": {
      "description": "ISO 8601 timestamp"
    }
  }
}

Evidence Chain

The FixChain attestation encodes evidence from multiple analysis stages:

Golden Set Definition (CVE signature)
          |
          v
+------------------+     +------------------+
| Vulnerable Binary| --> | Patch Diff Engine|
+------------------+     +------------------+
          |                       |
          v                       v
+------------------+     +------------------+
| Patched Binary   | --> | Signature Diff   |
+------------------+     +------------------+
                                  |
                                  v
                        +------------------+
                        | Reachability     |
                        | Analysis         |
                        +------------------+
                                  |
                                  v
                        +------------------+
                        | FixChain         |
                        | Attestation      |
                        +------------------+

Verdict Calculation

The verdict is calculated based on multiple factors:

Status Values

Status Description Conditions
fixed Vulnerability fully addressed High confidence (>=80%), all paths eliminated
partial Vulnerability partially addressed Medium confidence (50-80%), some paths remain
not_fixed Vulnerability still present Diff shows no fix, paths unchanged
inconclusive Cannot determine Low confidence, insufficient evidence

Confidence Scoring

Confidence = Base + FunctionBonus + EdgeBonus + PathBonus

Base = Diff.Confidence (from analysis)

FunctionBonus:
  - +0.1 per vulnerable function removed
  - +0.05 per vulnerable function modified

EdgeBonus:
  - +0.05 per vulnerable edge eliminated

PathBonus:
  - +0.3 if all paths eliminated
  - +0.1 if paths reduced by >50%

Rationale Generation

The rationale array explains the verdict:

{
  "rationale": [
    "3 vulnerable function(s) removed",
    "5 vulnerable edge(s) eliminated",
    "All paths to vulnerable sink eliminated"
  ]
}

Example Attestation

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [{
    "name": "pkg:deb/debian/openssl@3.1.0",
    "digest": {
      "sha256": "abc123..."
    }
  }],
  "predicateType": "https://stella-ops.org/predicates/fix-chain/v1",
  "predicate": {
    "cveId": "CVE-2024-0727",
    "component": "openssl",
    "goldenSetRef": {
      "digest": "sha256:def456..."
    },
    "vulnerableBinary": {
      "sha256": "111111...",
      "architecture": "x86_64"
    },
    "patchedBinary": {
      "sha256": "222222...",
      "architecture": "x86_64",
      "purl": "pkg:deb/debian/openssl@3.1.0"
    },
    "sbomRef": {
      "digest": "sha256:789abc..."
    },
    "signatureDiff": {
      "vulnerableFunctionsRemoved": 1,
      "vulnerableFunctionsModified": 2,
      "vulnerableEdgesEliminated": 5,
      "sanitizersInserted": 0,
      "details": ["Function X509_VERIFY_PARAM_set_flags rewritten"]
    },
    "reachability": {
      "prePathCount": 3,
      "postPathCount": 0,
      "eliminated": true,
      "reason": "All 3 path(s) to vulnerable sink eliminated"
    },
    "verdict": {
      "status": "fixed",
      "confidence": 0.95,
      "rationale": [
        "1 vulnerable function(s) removed",
        "5 vulnerable edge(s) eliminated",
        "All paths to vulnerable sink eliminated"
      ]
    },
    "analyzer": {
      "name": "StellaOps.BinaryIndex",
      "version": "1.0.0",
      "sourceDigest": "sha256:analyzerxyz..."
    },
    "analyzedAt": "2026-01-10T12:00:00Z"
  }
}

CLI Usage

Create FixChain Attestation

stella attest fixchain \
  --sbom sbom.cdx.json \
  --diff diff-result.json \
  --golden golden-set.yaml \
  --out fixchain.dsse.json \
  --arch x86_64 \
  --purl "pkg:deb/debian/openssl@3.1.0"

Verify FixChain Attestation

stella attest fixchain-verify \
  --attestation fixchain.dsse.json \
  --format summary

Output:

[OK] FixChain attestation is valid
  CVE: CVE-2024-0727
  Component: openssl
  Verdict: fixed (95%)
  Analyzed: 2026-01-10T12:00:00Z

JSON Output

stella attest fixchain-verify \
  --attestation fixchain.dsse.json \
  --format json

API Integration

Service Registration

services.AddFixChainAttestation(opts =>
{
    opts.AnalyzerName = "MyAnalyzer";
    opts.AnalyzerVersion = "1.0.0";
    opts.FixedConfidenceThreshold = 0.80m;
});

Creating Attestation

var request = new FixChainBuildRequest
{
    CveId = "CVE-2024-0727",
    Component = "openssl",
    GoldenSetDigest = goldenSetDigest,
    SbomDigest = sbomDigest,
    VulnerableBinary = new BinaryIdentity { ... },
    PatchedBinary = new BinaryIdentity { ... },
    ComponentPurl = "pkg:deb/debian/openssl@3.1.0",
    DiffResult = diffResult
};

var result = await attestationService.CreateAsync(request);
// result.EnvelopeJson - DSSE envelope
// result.ContentDigest - SHA-256 of statement
// result.Predicate - Parsed predicate

Verifying Attestation

var result = await attestationService.VerifyAsync(envelopeJson);
if (result.IsValid)
{
    var verdict = result.Predicate!.Verdict;
    Console.WriteLine($"Status: {verdict.Status}");
    Console.WriteLine($"Confidence: {verdict.Confidence:P0}");
}

Air-Gap Verification

FixChain attestations support offline verification:

  1. Bundle Export: Export attestation with all referenced artifacts
  2. Signature Verification: Verify DSSE signature with bundled public key
  3. Content Validation: Validate predicate structure and content
  4. Optional Rekor Proof: Include offline Rekor inclusion proof
# Export bundle for air-gap
stella attest bundle export \
  --attestation fixchain.dsse.json \
  --include-artifacts \
  --out fixchain-bundle.tar.gz

# Verify in air-gap
stella attest bundle verify \
  --bundle fixchain-bundle.tar.gz \
  --offline

Configuration

Attestor:
  Predicates:
    FixChain:
      Enabled: true
      AnalyzerName: "StellaOps.BinaryIndex"
      AnalyzerVersion: "1.0.0"
      FixedConfidenceThreshold: 0.80
      PartialConfidenceThreshold: 0.50
      PublishToRekor: true
      Archive: true