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

509 lines
18 KiB
Markdown

# 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:
```bash
stellaops scan myapp:v1.2.4 \
--baseline myapp:v1.2.3 \
--binary-delta \
--attestation
```
API equivalent:
```http
POST /api/v1/scans HTTP/1.1
Content-Type: application/json
```
### 2. Baseline Index Retrieval
Scanner retrieves existing binary index for baseline:
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
{
"_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:
```json
{
"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
```yaml
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
```yaml
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
```typescript
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
```typescript
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` |
## Related Flows
- [SBOM Generation Flow](03-sbom-generation-flow.md) - Component-level tracking
- [CI/CD Gate Flow](10-cicd-gate-flow.md) - Pipeline integration
- [Evidence Bundle Export Flow](13-evidence-bundle-export-flow.md) - Attestation packaging