Edit

Verify a Built Package

Purpose: For security officers and platform engineers, runs the integrity and policy checks that a Zarf package must pass before being moved across the air-gap boundary.

Prerequisites

  • The package file dist/zarf-package-opencenter-airgap-amd64-<version>.tar.zst.

  • Its .sha256 sidecar (always written by the build).

  • Its …-sbom.json SBOM (written by the build when zarf produces the package).

  • The Cosign public key that pairs with the signing key, if the package was signed.

  • sha256sum, jq, and (optionally) cosign on $PATH.

Quick check (one command)

Run the helper script in hack/scripts/:

hack/scripts/verify-package.sh dist/zarf-package-*.tar.zst .secrets/signing-key.pub

Exit codes:

| Code | Meaning | |------|---------| | 0 | All checks passed. | | 1 | Bad invocation. | | 2 | Checksum failed. | | 3 | Cosign signature check failed. | | 4 | SBOM policy violation (mutable tag or HIGH/CRITICAL CVE). |

The script is the canonical workflow. The sections below explain what each step does so you can run them by hand or adapt them to your CI pipeline.

1. Checksum

sha256sum -c dist/zarf-package-*.tar.zst.sha256
# zarf-package-opencenter-airgap-amd64-1.0.0-rc2.tar.zst: OK

Failure means the file was modified or corrupted in transit. Do not deploy.

2. Cosign signature

cosign verify-blob \
  --key .secrets/signing-key.pub \
  --signature dist/zarf-package-*.tar.zst.sig \
  dist/zarf-package-*.tar.zst

Failure means the file was modified after signing or was signed with a different key. Do not deploy.

If you do not have a key yet, generate one with opencenter-airgap keygen. The CLI writes the keypair to .secrets/signing-key.{key,pub}, sets 0600 on the private key, and adds .secrets/ to .gitignore if a git repo is present.

3. SBOM policy

The SBOM lists every artifact the package contains. You should reject the package if it contains mutable image tags or HIGH/CRITICAL CVEs.

SBOM=dist/zarf-package-opencenter-airgap-amd64-1.0.0-rc2-sbom.json

# Reject mutable tags.
jq '[.artifacts[]?
      | select(.type == "image")
      | select(.version == "latest" or .version == null)] | length' "$SBOM"
# expected: 0

# Reject HIGH/CRITICAL CVEs (only present if the build ran a scanner).
jq '[.vulnerabilities[]?
      | select(.severity == "CRITICAL" or .severity == "HIGH")] | length' "$SBOM"
# expected: 0

hack/scripts/verify-package.sh runs both jq queries and exits 4 if either is non-zero.

4. Spot-check the contents (optional)

zarf package inspect dist/zarf-package-*.tar.zst | head -30
zarf package inspect dist/zarf-package-*.tar.zst --sbom-out /tmp/sbom-out

zarf package inspect prints the package metadata and component list. With --sbom-out, Zarf writes the SBOM out to a directory you can compare against your policy.

CLI alternative

opencenter-airgap verify <package> runs the integrity checks built into src/opencenter_build/verifier.py:PackageVerifier (checksum + signature). It does not enforce SBOM policy today, which is why hack/scripts/verify-package.sh exists. Use the CLI when you only need integrity, the script when you need policy gating.

opencenter-airgap verify dist/zarf-package-*.tar.zst \
  --manifest dist/artifact-manifest.json

--manifest cross-checks every artifact in the package against the manifest the build wrote at the same time, and flags missing or extra entries.

Troubleshooting

  • checksum sidecar missing — the .sha256 file did not travel with the package. Re-copy from dist/.

  • signature verification failed — wrong key, corrupted signature, or a re-signed package. Confirm with the publisher; do not deploy.

  • N image(s) use mutable or missing tags — the build picked up an image without a pinned version. Find it by reading the failing line from the script and pin the version in config/components.yaml or config/versions.env.

  • N HIGH/CRITICAL vulnerabilities reported — the SBOM scanner flagged CVEs. Patch the underlying images or pin to a fixed version.

  • ../reference/cli-commands.md#verify[CLI Commands → verify] — flag reference.

  • ../getting-started/first-deployment.md[First Deployment] — where this step fits in the overall workflow.