Delta Attestation Workflow Guide

Audience: CI/CD engineers, release operators, and security auditors.

Purpose: an end-to-end guide for generating, signing, attaching, verifying, and exporting delta-sig attestations with the Stella Ops CLI.

Overview

The delta attestation workflow provides verifiable evidence of binary-level changes between releases. It covers the full lifecycle from generating a delta-sig predicate through to offline bundle verification.

diff → attest → attach → verify → export → offline-verify

Prerequisites

Step 1: Generate Delta-Sig Predicate

Compare two binary builds to produce a delta-sig predicate describing function-level changes:

stella binary delta-sig diff \
  --old /path/to/old-binary \
  --new /path/to/new-binary \
  --output delta-predicate.json \
  --arch linux-amd64

The predicate JSON follows the https://stellaops.dev/delta-sig/v1 schema and includes:

Step 2: Sign and Attest

Sign the predicate with an EC key, producing a DSSE envelope. Optionally submit to a Rekor transparency log:

stella binary delta-sig attest \
  --predicate delta-predicate.json \
  --key signing-key.pem \
  --output signed-envelope.dsse.json \
  --rekor-url https://rekor.sigstore.dev \
  --receipt rekor-receipt.json \
  --verbose

Output:

Without Rekor (air-gapped environments):

stella binary delta-sig attest \
  --predicate delta-predicate.json \
  --key signing-key.pem \
  --output signed-envelope.dsse.json

Step 3: Attach to OCI Image

Attach the signed attestation to the target OCI image via ORAS referrers:

stella attest attach \
  --image registry.example.com/app:v1.2 \
  --attestation signed-envelope.dsse.json \
  --verbose

The attestation is stored as a referrer artifact in the registry, discoverable by image digest.

Step 4: Verify Attestations

Verify that attestations are properly attached and valid:

stella attest verify \
  --image registry.example.com/app:v1.2 \
  --predicate-type "https://stellaops.dev/delta-sig/v1" \
  --require-rekor \
  --verbose

This checks:

Step 5: Export Evidence Bundle

Export all attestation evidence for offline environments:

# Light mode (metadata only, small size)
stella evidence export-bundle \
  --image registry.example.com/app:v1.2 \
  --output evidence-light.tar.gz

# Full mode (includes binary blobs for replay)
stella evidence export-bundle \
  --image registry.example.com/app:v1.2 \
  --output evidence-full.tar.gz \
  --full

Bundle Contents

Light bundle:

bundle/
├── manifest.json           # exportMode: "light"
└── attestations/
    └── delta-sig.dsse.json

Full bundle:

bundle/
├── manifest.json           # exportMode: "full"
├── attestations/
│   └── delta-sig.dsse.json
└── blobs/
    ├── sha256-<hex1>       # Binary patch
    └── sha256-<hex2>       # SBOM fragment

Step 6: Offline Bundle Verification

Verify the exported bundle in air-gapped environments:

# Full bundle: self-contained verification with blob replay
stella bundle verify \
  --bundle evidence-full.tar.gz \
  --offline \
  --trust-root /etc/stellaops/tsa-root.pem \
  --replay \
  --verbose

# Light bundle: provide local blob source for replay
stella bundle verify \
  --bundle evidence-light.tar.gz \
  --offline \
  --replay \
  --blob-source /path/to/cached-blobs/

Verification Steps

StepCheckFailure Behavior
1Manifest checksumFatal
2Blob digestsFatal
3DSSE signaturesFatal
4Rekor proofsFatal (if checkpoint provided)
5RFC 3161 timestampsFatal (in strict mode)
6Payload type expectationsWarning (fatal in strict)
7Blob replayFatal (when --replay enabled)

CI/CD Integration Example

# .gitea/workflows/release.yaml
jobs:
  attest:
    steps:
      - name: Generate delta predicate
        run: |
          stella binary delta-sig diff \
            --old ${{ steps.build.outputs.old_binary }} \
            --new ${{ steps.build.outputs.new_binary }} \
            --output delta-predicate.json

      - name: Sign and submit to Rekor
        run: |
          stella binary delta-sig attest \
            --predicate delta-predicate.json \
            --key ${{ secrets.SIGNING_KEY_PATH }} \
            --output envelope.dsse.json \
            --rekor-url https://rekor.sigstore.dev \
            --receipt rekor-receipt.json

      - name: Attach to image
        run: |
          stella attest attach \
            --image ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ env.TAG }} \
            --attestation envelope.dsse.json

      - name: Export full bundle for auditors
        run: |
          stella evidence export-bundle \
            --image ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ env.TAG }} \
            --output evidence-bundle.tar.gz \
            --full

Troubleshooting

IssueCauseResolution
Blob Replay ✗Missing blobs in light bundleUse --blob-source or export with --full
DSSE signature ✗Key mismatchVerify signing key matches trusted keys
Rekor proof ✗No checkpoint providedAdd --rekor-checkpoint for offline
Exit code 2Invalid predicate JSONCheck required fields: subject, delta, summary, tooling, computedAt

See Also