Files
git.stella-ops.org/docs/flows/15-binary-delta-attestation-flow.md
StellaOps Bot ca578801fd save progress
2026-01-03 00:49:19 +02:00

18 KiB

Binary Delta Attestation Flow

Overview

The Binary Delta Attestation Flow describes how StellaOps tracks and attests changes at the binary level between image versions. This flow detects modified, added, or removed binaries and generates attestations about what changed, enabling precise supply chain verification.

Business Value: Detect unauthorized modifications, track binary provenance, and ensure only expected changes are deployed between versions.

Actors

Actor Type Role
CI Pipeline System Triggers delta analysis
BinaryIndex Service Extracts binary fingerprints
Scanner Service Coordinates analysis
Attestor Service Generates delta attestations
Signer Service Signs attestations
Symbols Service Resolves debug symbols

Prerequisites

  • Previous image version scanned and indexed
  • Binary analysis enabled for image
  • Build provenance available (optional)

Binary Fingerprinting

StellaOps extracts multiple identifiers from binaries:

Identifier Source Stability
SHA-256 File content Exact match
Build ID ELF .note.gnu.build-id Build-specific
PE Checksum PE header Load-time
Code Hash .text section only Ignores data
Symbol Hash Exported symbols API stability
Debug ID DWARF/PDB reference Debug matching

Flow Diagram

┌─────────────────────────────────────────────────────────────────────────────────┐
│                       Binary Delta Attestation Flow                              │
└─────────────────────────────────────────────────────────────────────────────────┘

┌───────────┐  ┌─────────┐  ┌─────────────┐  ┌─────────┐  ┌─────────┐  ┌────────┐
│    CI     │  │ Scanner │  │ BinaryIndex │  │ Symbols │  │ Attestor│  │ Signer │
└─────┬─────┘  └────┬────┘  └──────┬──────┘  └────┬────┘  └────┬────┘  └───┬────┘
      │             │              │              │            │           │
      │ Scan v1.2.4 │              │              │            │           │
      │ --baseline  │              │              │            │           │
      │ v1.2.3      │              │              │            │           │
      │────────────>│              │              │            │           │
      │             │              │              │            │           │
      │             │ Load v1.2.3  │              │            │           │
      │             │ index        │              │            │           │
      │             │─────────────>│              │            │           │
      │             │              │              │            │           │
      │             │ Baseline     │              │            │           │
      │             │ binaries     │              │            │           │
      │             │<─────────────│              │            │           │
      │             │              │              │            │           │
      │             │ Index v1.2.4 │              │            │           │
      │             │─────────────>│              │            │           │
      │             │              │              │            │           │
      │             │              │ Extract      │            │           │
      │             │              │ binaries     │            │           │
      │             │              │───┐          │            │           │
      │             │              │   │          │            │           │
      │             │              │<──┘          │            │           │
      │             │              │              │            │           │
      │             │              │ Compute      │            │           │
      │             │              │ fingerprints │            │           │
      │             │              │───┐          │            │           │
      │             │              │   │          │            │           │
      │             │              │<──┘          │            │           │
      │             │              │              │            │           │
      │             │ Current      │              │            │           │
      │             │ binaries     │              │            │           │
      │             │<─────────────│              │            │           │
      │             │              │              │            │           │
      │             │ Compute      │              │            │           │
      │             │ delta        │              │            │           │
      │             │───┐          │              │            │           │
      │             │   │          │              │            │           │
      │             │<──┘          │              │            │           │
      │             │              │              │            │           │
      │             │ Resolve      │              │            │           │
      │             │ symbols      │              │            │           │
      │             │──────────────────────────────>           │           │
      │             │              │              │            │           │
      │             │              │              │ Map to     │           │
      │             │              │              │ source     │           │
      │             │              │              │───┐        │           │
      │             │              │              │   │        │           │
      │             │              │              │<──┘        │           │
      │             │              │              │            │           │
      │             │ Symbol       │              │            │           │
      │             │ mappings     │              │            │           │
      │             │<──────────────────────────────           │           │
      │             │              │              │            │           │
      │             │ Generate     │              │            │           │
      │             │ attestation  │              │            │           │
      │             │─────────────────────────────────────────>│           │
      │             │              │              │            │           │
      │             │              │              │            │ Create    │
      │             │              │              │            │ statement │
      │             │              │              │            │───┐       │
      │             │              │              │            │   │       │
      │             │              │              │            │<──┘       │
      │             │              │              │            │           │
      │             │              │              │            │ Sign      │
      │             │              │              │            │──────────>│
      │             │              │              │            │           │
      │             │              │              │            │ DSSE      │
      │             │              │              │            │<──────────│
      │             │              │              │            │           │
      │             │ Attestation  │              │            │           │
      │             │<─────────────────────────────────────────│           │
      │             │              │              │            │           │
      │ Delta       │              │              │            │           │
      │ report      │              │              │            │           │
      │<────────────│              │              │            │           │
      │             │              │              │            │           │

Step-by-Step

1. Delta Scan Request

CI pipeline requests delta analysis:

stellaops scan myapp:v1.2.4 \
  --baseline myapp:v1.2.3 \
  --binary-delta \
  --attestation

API equivalent:

POST /api/v1/scans HTTP/1.1
Content-Type: application/json

{
  "image": "docker.io/myorg/myapp:v1.2.4",
  "options": {
    "binary_delta": {
      "enabled": true,
      "baseline": "docker.io/myorg/myapp:v1.2.3"
    },
    "attestation": true
  }
}

2. Baseline Index Retrieval

Scanner retrieves existing binary index for baseline:

{
  "image": "docker.io/myorg/myapp:v1.2.3",
  "digest": "sha256:baseline123...",
  "indexed_at": "2024-12-28T10:00:00Z",
  "binaries": [
    {
      "path": "/app/myapp",
      "type": "elf-x86_64",
      "sha256": "abc123...",
      "build_id": "7f3a9b2c1234567890abcdef",
      "code_hash": "def456...",
      "symbols": {
        "exported": 234,
        "hash": "ghi789..."
      },
      "size": 15234567
    },
    {
      "path": "/app/lib/libcore.so",
      "type": "elf-x86_64-shared",
      "sha256": "jkl012...",
      "build_id": "abcdef1234567890",
      "size": 2345678
    }
  ]
}

3. Current Image Indexing

BinaryIndex extracts and fingerprints current image binaries:

{
  "image": "docker.io/myorg/myapp:v1.2.4",
  "digest": "sha256:current456...",
  "indexed_at": "2024-12-29T10:00:00Z",
  "binaries": [
    {
      "path": "/app/myapp",
      "type": "elf-x86_64",
      "sha256": "xyz789...",  // Changed
      "build_id": "9f5b7d4e2345678901bcdefg",  // New build
      "code_hash": "uvw012...",  // Code changed
      "symbols": {
        "exported": 238,  // 4 new symbols
        "hash": "rst345..."  // Symbol hash changed
      },
      "size": 15456789  // Size increased
    },
    {
      "path": "/app/lib/libcore.so",
      "type": "elf-x86_64-shared",
      "sha256": "jkl012...",  // Unchanged
      "build_id": "abcdef1234567890",
      "size": 2345678
    },
    {
      "path": "/app/lib/libnew.so",  // New binary
      "type": "elf-x86_64-shared",
      "sha256": "new123...",
      "build_id": "newbuild123456",
      "size": 567890
    }
  ]
}

4. Delta Computation

Scanner computes binary delta:

{
  "delta": {
    "baseline": {
      "image": "docker.io/myorg/myapp:v1.2.3",
      "digest": "sha256:baseline123..."
    },
    "current": {
      "image": "docker.io/myorg/myapp:v1.2.4",
      "digest": "sha256:current456..."
    },
    "summary": {
      "total_binaries_baseline": 2,
      "total_binaries_current": 3,
      "modified": 1,
      "added": 1,
      "removed": 0,
      "unchanged": 1
    },
    "changes": [
      {
        "type": "modified",
        "path": "/app/myapp",
        "baseline": {
          "sha256": "abc123...",
          "build_id": "7f3a9b2c1234567890abcdef",
          "size": 15234567
        },
        "current": {
          "sha256": "xyz789...",
          "build_id": "9f5b7d4e2345678901bcdefg",
          "size": 15456789
        },
        "analysis": {
          "code_changed": true,
          "symbols_added": ["new_feature_init", "new_feature_process", "new_feature_cleanup", "handle_error_v2"],
          "symbols_removed": [],
          "size_delta": "+222222 bytes"
        }
      },
      {
        "type": "added",
        "path": "/app/lib/libnew.so",
        "current": {
          "sha256": "new123...",
          "build_id": "newbuild123456",
          "size": 567890
        }
      }
    ],
    "unchanged": [
      {
        "path": "/app/lib/libcore.so",
        "sha256": "jkl012..."
      }
    ]
  }
}

5. Symbol Resolution

Symbols service maps build IDs to source:

{
  "symbol_resolution": {
    "/app/myapp": {
      "build_id": "9f5b7d4e2345678901bcdefg",
      "debug_info_available": true,
      "source_mapping": {
        "repository": "github.com/myorg/myapp",
        "commit": "abc123def456",
        "build_time": "2024-12-29T08:00:00Z",
        "compiler": "gcc 13.2.0",
        "flags": "-O2 -fstack-protector-strong"
      },
      "new_symbols": [
        {
          "name": "new_feature_init",
          "source": "src/features/new_feature.c:45",
          "size": 256
        },
        {
          "name": "new_feature_process",
          "source": "src/features/new_feature.c:89",
          "size": 1024
        }
      ]
    }
  }
}

6. Delta Attestation Generation

Attestor creates in-toto statement for the delta:

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "docker.io/myorg/myapp",
      "digest": {"sha256": "current456..."}
    }
  ],
  "predicateType": "https://stellaops.io/attestation/binary-delta/v1",
  "predicate": {
    "baseline": {
      "name": "docker.io/myorg/myapp",
      "digest": {"sha256": "baseline123..."}
    },
    "delta_summary": {
      "modified": 1,
      "added": 1,
      "removed": 0,
      "unchanged": 1
    },
    "binary_changes": [
      {
        "path": "/app/myapp",
        "change_type": "modified",
        "baseline_hash": "sha256:abc123...",
        "current_hash": "sha256:xyz789...",
        "provenance": {
          "commit": "abc123def456",
          "build_id": "9f5b7d4e2345678901bcdefg"
        }
      },
      {
        "path": "/app/lib/libnew.so",
        "change_type": "added",
        "current_hash": "sha256:new123...",
        "provenance": {
          "commit": "abc123def456",
          "build_id": "newbuild123456"
        }
      }
    ],
    "verification": {
      "all_changes_have_provenance": true,
      "all_binaries_signed": true,
      "no_unexpected_modifications": true
    },
    "timestamp": "2024-12-29T10:30:00Z"
  }
}

7. DSSE Signing

Signer wraps statement in DSSE envelope:

{
  "payloadType": "application/vnd.in-toto+json",
  "payload": "base64:statement-json...",
  "signatures": [
    {
      "keyid": "sha256:binary-attestation-key",
      "sig": "base64:signature...",
      "cert": "base64:x509-certificate..."
    }
  ]
}

Verification Policies

Strict Mode

binary_delta_policy:
  mode: strict
  rules:
    - all_changes_must_have_provenance: true
    - allow_added_binaries: true
    - allow_removed_binaries: false
    - require_signed_builds: true
    - max_modified_binaries: 10

Permissive Mode

binary_delta_policy:
  mode: permissive
  rules:
    - allow_unsigned_binaries: true
    - warn_on_missing_provenance: true
    - block_known_malware_hashes: true

Data Contracts

Binary Delta Request Schema

interface BinaryDeltaRequest {
  image: string;
  options: {
    binary_delta: {
      enabled: boolean;
      baseline: string;  // Image reference or digest
      include_symbols?: boolean;
      include_provenance?: boolean;
    };
    attestation?: boolean;
  };
}

Binary Delta Response Schema

interface BinaryDeltaResponse {
  scan_id: string;
  baseline: ImageReference;
  current: ImageReference;
  summary: {
    total_binaries_baseline: number;
    total_binaries_current: number;
    modified: number;
    added: number;
    removed: number;
    unchanged: number;
  };
  changes: BinaryChange[];
  unchanged: BinaryReference[];
  attestation?: {
    digest: string;
    rekor_log_index?: number;
  };
  policy_verdict?: {
    verdict: 'PASS' | 'WARN' | 'FAIL';
    violations?: string[];
  };
}

Error Handling

Error Recovery
Baseline not found Return error, suggest scanning baseline first
Build ID not found Continue without provenance, reduce confidence
Symbol resolution failed Continue with hash-only comparison
Signing failure Return delta without attestation

Observability

Metrics

Metric Type Labels
binary_delta_scans_total Counter result
binary_delta_changes_total Counter type (modified/added/removed)
binary_delta_duration_seconds Histogram -
binary_index_size_bytes Histogram -

Key Log Events

Event Level Fields
binary.delta.started INFO baseline, current
binary.delta.computed INFO modified, added, removed
binary.provenance.missing WARN path, build_id
binary.delta.attested INFO digest, rekor_index