{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://stellaops.io/schemas/binarydiff-v1.schema.json", "title": "BinaryDiffV1", "description": "In-toto predicate schema for binary-level diff attestations between container images", "type": "object", "required": ["predicateType", "inputs", "findings", "metadata"], "additionalProperties": false, "properties": { "predicateType": { "const": "stellaops.binarydiff.v1", "description": "Predicate type identifier" }, "inputs": { "$ref": "#/$defs/BinaryDiffInputs", "description": "Base and target image references" }, "findings": { "type": "array", "items": { "$ref": "#/$defs/BinaryDiffFinding" }, "description": "Per-binary diff findings" }, "metadata": { "$ref": "#/$defs/BinaryDiffMetadata", "description": "Analysis metadata" } }, "$defs": { "BinaryDiffInputs": { "type": "object", "required": ["base", "target"], "additionalProperties": false, "properties": { "base": { "$ref": "#/$defs/ImageReference", "description": "Base image reference" }, "target": { "$ref": "#/$defs/ImageReference", "description": "Target image reference" } } }, "ImageReference": { "type": "object", "required": ["digest"], "additionalProperties": false, "properties": { "reference": { "type": "string", "description": "Full image reference (e.g., docker://repo/image:tag)", "examples": ["docker://registry.example.com/app:1.0.0"] }, "digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$", "description": "Image digest in sha256:hex format" }, "manifestDigest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$", "description": "Platform-specific manifest digest" }, "platform": { "$ref": "#/$defs/Platform" } } }, "Platform": { "type": "object", "required": ["os", "architecture"], "additionalProperties": false, "properties": { "os": { "type": "string", "description": "Operating system (e.g., linux, windows)", "examples": ["linux", "windows"] }, "architecture": { "type": "string", "description": "CPU architecture (e.g., amd64, arm64)", "examples": ["amd64", "arm64", "386"] }, "variant": { "type": "string", "description": "Architecture variant (e.g., v8 for arm64)", "examples": ["v7", "v8"] } } }, "BinaryDiffFinding": { "type": "object", "required": ["path", "changeType", "binaryFormat"], "additionalProperties": false, "properties": { "path": { "type": "string", "description": "File path within the container filesystem", "examples": ["/usr/lib/libssl.so.3", "/usr/bin/openssl"] }, "changeType": { "type": "string", "enum": ["added", "removed", "modified", "unchanged"], "description": "Type of change detected" }, "binaryFormat": { "type": "string", "enum": ["elf", "pe", "macho", "unknown"], "description": "Binary format detected" }, "layerDigest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$", "description": "Layer digest that introduced this file/change" }, "baseHashes": { "$ref": "#/$defs/SectionHashSet", "description": "Section hashes from base image binary" }, "targetHashes": { "$ref": "#/$defs/SectionHashSet", "description": "Section hashes from target image binary" }, "sectionDeltas": { "type": "array", "items": { "$ref": "#/$defs/SectionDelta" }, "description": "Per-section comparison results" }, "confidence": { "type": "number", "minimum": 0, "maximum": 1, "description": "Confidence score for verdict (0.0-1.0)" }, "verdict": { "type": "string", "enum": ["patched", "vanilla", "unknown", "incompatible"], "description": "Classification of the binary change" } } }, "SectionHashSet": { "type": "object", "additionalProperties": false, "properties": { "buildId": { "type": "string", "pattern": "^[a-f0-9]+$", "description": "GNU Build-ID from .note.gnu.build-id section" }, "fileHash": { "type": "string", "pattern": "^[a-f0-9]{64}$", "description": "SHA-256 hash of the entire file" }, "extractorVersion": { "type": "string", "description": "Version of the section hash extractor" }, "sections": { "type": "object", "additionalProperties": { "$ref": "#/$defs/SectionInfo" }, "description": "Map of section name to section info" } } }, "SectionInfo": { "type": "object", "required": ["sha256", "size"], "additionalProperties": false, "properties": { "sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$", "description": "SHA-256 hash of section contents" }, "blake3": { "type": "string", "pattern": "^[a-f0-9]{64}$", "description": "Optional BLAKE3-256 hash of section contents" }, "size": { "type": "integer", "minimum": 0, "description": "Section size in bytes" }, "offset": { "type": "integer", "minimum": 0, "description": "Section offset in file" }, "type": { "type": "string", "description": "ELF section type (e.g., SHT_PROGBITS)" }, "flags": { "type": "string", "description": "ELF section flags (e.g., SHF_ALLOC | SHF_EXECINSTR)" } } }, "SectionDelta": { "type": "object", "required": ["section", "status"], "additionalProperties": false, "properties": { "section": { "type": "string", "description": "Section name (e.g., .text, .rodata)", "examples": [".text", ".rodata", ".data", ".symtab", ".dynsym"] }, "status": { "type": "string", "enum": ["identical", "modified", "added", "removed"], "description": "Section comparison status" }, "baseSha256": { "type": "string", "pattern": "^[a-f0-9]{64}$", "description": "SHA-256 of section in base binary" }, "targetSha256": { "type": "string", "pattern": "^[a-f0-9]{64}$", "description": "SHA-256 of section in target binary" }, "sizeDelta": { "type": "integer", "description": "Size difference (target - base) in bytes" } } }, "BinaryDiffMetadata": { "type": "object", "required": ["toolVersion", "analysisTimestamp"], "additionalProperties": false, "properties": { "toolVersion": { "type": "string", "description": "Version of the binary diff tool", "examples": ["1.0.0", "2026.01.0"] }, "analysisTimestamp": { "type": "string", "format": "date-time", "description": "UTC timestamp of analysis (ISO-8601)" }, "configDigest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$", "description": "SHA-256 of analysis configuration for reproducibility" }, "totalBinaries": { "type": "integer", "minimum": 0, "description": "Total number of binaries analyzed" }, "modifiedBinaries": { "type": "integer", "minimum": 0, "description": "Number of binaries with modifications" }, "analyzedSections": { "type": "array", "items": { "type": "string" }, "description": "List of section names analyzed", "examples": [[".text", ".rodata", ".data", ".symtab", ".dynsym"]] }, "hashAlgorithms": { "type": "array", "items": { "type": "string", "enum": ["sha256", "blake3"] }, "description": "Hash algorithms used" } } } }, "examples": [ { "predicateType": "stellaops.binarydiff.v1", "inputs": { "base": { "reference": "docker://registry.example.com/app:1.0.0", "digest": "sha256:abc123def456789012345678901234567890123456789012345678901234abcd", "platform": { "os": "linux", "architecture": "amd64" } }, "target": { "reference": "docker://registry.example.com/app:1.0.1", "digest": "sha256:def456abc789012345678901234567890123456789012345678901234567efgh", "platform": { "os": "linux", "architecture": "amd64" } } }, "findings": [ { "path": "/usr/lib/libssl.so.3", "changeType": "modified", "binaryFormat": "elf", "sectionDeltas": [ { "section": ".text", "status": "modified", "baseSha256": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "targetSha256": "fedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321", "sizeDelta": 256 }, { "section": ".rodata", "status": "identical", "baseSha256": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "targetSha256": "abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890", "sizeDelta": 0 } ], "confidence": 0.95, "verdict": "patched" } ], "metadata": { "toolVersion": "1.0.0", "analysisTimestamp": "2026-01-13T12:00:00Z", "totalBinaries": 156, "modifiedBinaries": 3, "analyzedSections": [".text", ".rodata", ".data", ".symtab", ".dynsym"], "hashAlgorithms": ["sha256"] } } ] }