This guide explains how to verify container image attestations and SBOMs for Midnight images.
Quick Start: Use the included verification script for simple verification:
./scripts/verify-image.sh ghcr.io/midnight-ntwrk/midnight-node:TAG
./scripts/verify-image.sh --sbom ghcr.io/midnight-ntwrk/midnight-node:TAG # Also verify SBOMFor manual verification or advanced use cases, continue reading.
Install the GitHub CLI:
# macOS
brew install gh
# Linux (Debian/Ubuntu)
sudo apt install gh
# Linux (Fedora)
sudo dnf install ghFor SBOM inspection, you'll also need jq:
# macOS
brew install jq
# Ubuntu/Debian
apt-get install jqVerify that an image was built by Midnight's CI/CD pipeline:
# GHCR
gh attestation verify oci://ghcr.io/midnight-ntwrk/midnight-node:TAG \
--owner midnightntwrk
# Docker Hub
gh attestation verify oci://midnightntwrk/midnight-node:TAG \
--owner midnightntwrkReplace TAG with the specific version (e.g., 1.0.0, latest-main).
Successful verification:
Loaded digest sha256:abc123... for oci://ghcr.io/midnight-ntwrk/midnight-node:1.0.0
Loaded 1 attestation from GitHub API
✓ Verification succeeded!
sha256:abc123... was attested by a trusted GitHub Actions workflow
Failed verification (unattested image):
✗ Loading attestations from GitHub API failed
no attestations found for subject
Verify that an SBOM attestation exists:
gh attestation verify oci://ghcr.io/midnight-ntwrk/midnight-node:TAG \
--owner midnightntwrk \
--predicate-type https://spdx.dev/DocumentExtract and view the SBOM content:
# Download the SBOM attestation
gh attestation download oci://ghcr.io/midnight-ntwrk/midnight-node:TAG \
--owner midnightntwrk \
--predicate-type https://spdx.dev/Document \
-d /tmp/sbom
# Decode and view the SBOM
cat /tmp/sbom/*.jsonl | jq '.dsseEnvelope.payload' | base64 -d | jq '.predicate' > sbom.spdx.json
cat sbom.spdx.jsonList all packages in the SBOM:
# List package names and versions
cat sbom.spdx.json | jq -r '.packages[] | "\(.name) \(.versionInfo)"'
# Count packages by type
cat sbom.spdx.json | jq -r '.packages[].externalRefs[]? | select(.referenceCategory == "PACKAGE-MANAGER") | .referenceType' | sort | uniq -cFor multi-architecture images, you can verify specific platform variants:
# Get the manifest list
docker manifest inspect ghcr.io/midnight-ntwrk/midnight-node:TAG
# Verify a specific architecture by digest
gh attestation verify oci://ghcr.io/midnight-ntwrk/midnight-node@sha256:DIGEST \
--owner midnightntwrkVerify any of these images using the commands above:
| Image | GHCR | Docker Hub |
|---|---|---|
| Midnight Node | ghcr.io/midnight-ntwrk/midnight-node |
midnightntwrk/midnight-node |
| Midnight Toolkit | ghcr.io/midnight-ntwrk/midnight-node-toolkit |
midnightntwrk/midnight-node-toolkit |
Note: The GitHub org is
midnightntwrk(no hyphen), while GHCR usesmidnight-ntwrk(with hyphen). Keep this in mind when constructing image references.
The image may not be attested. This can occur if:
- The image predates the attestation implementation
- The image is from a fork PR (attestations are skipped)
- There was an attestation failure during the build
The attestation doesn't match the image. Check:
- The image is from the official Midnight repository
- You're using the correct
--ownervalue (midnightntwrk)
If you get errors connecting to GitHub's attestation API:
- Check internet connectivity
- Check GitHub status: https://www.githubstatus.com/
- Ensure
ghis authenticated:gh auth status
- Image Signing Overview - Architecture and implementation details
- Signing Runbook - Operational procedures