Skip to main content
Early accessElevarq Analyzer is not yet generally available — this manual documents the current build.Request an evaluation →
Elevarq Analyzer docs · Verify the image

How-to guide

Verify the image and SBOM

Confirm the Workbench container image you pulled is the one Elevarq published, before you run it. Verification uses public inputs only — no Elevarq-issued credentials are needed. Do this once per release tag you deploy.

This page covers how to verify the Workbench container image you pulled is the one Elevarq published, and how to retrieve its Software Bill of Materials. Verification uses public inputs only — no Elevarq-issued credentials are needed. Anyone who can pull the image can complete every step here; no access to the (private) Workbench source repository is required.

Tools

  • cosign v2.4+ or v3.x — install per the sigstore project's installation guide.
  • jq — required, both to extract the SBOM from its attestation and to inspect it.
  • docker (or any OCI client) to resolve the image tag to a digest.

Verify the image signature

Every release-tagged image is signed by the Workbench release workflow using Cosign keyless OIDC. The signing identity is the workflow itself, recorded in the public Rekor transparency log.

Resolve the image digest, then verify:

TAG=v0.3.0
DIGEST=$(docker buildx imagetools inspect \
  "ghcr.io/elevarq/workbench:${TAG}" \
  --format '{{json .}}' | jq -r '.manifest.digest')

cosign verify "ghcr.io/elevarq/workbench@${DIGEST}" \
  --certificate-identity-regexp '^https://github.com/Elevarq/Workbench/\.github/workflows/release\.yml@.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com'

A successful verification prints:

Verification for ghcr.io/elevarq/workbench@sha256:...
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The code-signing certificate was verified using trusted certificate authority certificates

A failure aborts with a non-zero exit. Do not run an image whose signature does not verify.

What verification proves

  • The image was built and signed by the published Workbench release workflow running on Elevarq/Workbench at the named tag.
  • The signing event was recorded in the public Rekor transparency log at the timestamp the certificate shows.

What verification does NOT prove

  • That the image is free of bugs or security defects. Combine signature verification with the SBOM and your own scanning.
  • That a particular license artefact loaded into Workbench is authentic — license verification is a separate path, performed by Workbench itself at activation time against the embedded public key ring.
  • That the host running Workbench is hardened. Host-OS posture is your responsibility.

Retrieve and inspect the SBOM

The image's SPDX Software Bill of Materials is published as a Cosign attestation on the image itself (predicate type spdxjson), signed by the same keyless release identity as the image signature and recorded in the public Rekor transparency log.

It is not a GitHub release asset, and it is not the deprecated Cosign SBOM attachment — so cosign download sbom does not retrieve it. Use cosign verify-attestation and extract the predicate:

DIGEST=...  # the sha256:... resolved above

cosign verify-attestation \
  --type spdxjson \
  --certificate-identity-regexp '^https://github.com/Elevarq/Workbench/\.github/workflows/release\.yml@.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  "ghcr.io/elevarq/workbench@${DIGEST}" \
  | jq -r 'if type=="array" then .[0] else . end
             | .payload | @base64d | fromjson | .predicate' \
  > workbench.spdx.json

verify-attestation exits non-zero unless the attestation was signed by the Elevarq release workflow and its transparency-log entry checks out — so a successful extraction is itself the integrity guarantee. There is no separate hash to download and compare.

Two portability details are already folded into the command:

  • cosign's output shape differs by version — cosign v2 prints a JSON array, cosign v3 prints a single JSON object. if type=="array" then .[0] else . end handles both.
  • @base64d decodes inside jq — so you do not depend on the non-portable base64 decode flag (GNU -d / --decode vs. BSD/macOS -D).

Inspect the extracted SBOM:

# Count packages.
jq '.packages | length' workbench.spdx.json

# List Go modules.
jq -r '.packages[] | select(.SPDXID | startswith("SPDXRef-Package-go-module-")) | .name + "@" + .versionInfo' \
  workbench.spdx.json

# List Node.js packages.
jq -r '.packages[] | select(.SPDXID | startswith("SPDXRef-Package-npm-")) | .name + "@" + .versionInfo' \
  workbench.spdx.json

The SBOM is produced from the registry image (not the source tree) by syft, and enumerates every package in the released image — base OS packages, Go modules, Node.js packages.

Air-gapped or offline verification

The attestation is an OCI referrer of the image, not part of the image itself. A normal docker pull or docker save does not necessarily include it. Offline verification is possible, but only when the image, its signature, its SBOM attestation, and the trust material cosign needs (the Fulcio root and Rekor public key, or an equivalent offline bundle) are deliberately mirrored or exported together — for example with cosign save / cosign load, or by copying the referrers with an OCI tool that preserves them. Once all of those are present in the offline registry or bundle, the same verify-attestation command runs with no outbound network.

End-to-end verification script

A complete verification flow for a release digest:

#!/usr/bin/env bash
set -euo pipefail
TAG="${1:-v0.3.0}"
REPO="ghcr.io/elevarq/workbench"
ID_RE='^https://github.com/Elevarq/Workbench/\.github/workflows/release\.yml@.*'
ISSUER='https://token.actions.githubusercontent.com'

# 1. Resolve the tag to a digest.
DIGEST=$(docker buildx imagetools inspect "${REPO}:${TAG}" \
  --format '{{json .}}' | jq -r '.manifest.digest')
echo "image: ${REPO}@${DIGEST}"

# 2. Verify the image signature.
cosign verify "${REPO}@${DIGEST}" \
  --certificate-identity-regexp "${ID_RE}" \
  --certificate-oidc-issuer "${ISSUER}" > /dev/null
echo "signature: verified"

# 3. Verify the SBOM attestation and extract it to a file.
cosign verify-attestation --type spdxjson "${REPO}@${DIGEST}" \
  --certificate-identity-regexp "${ID_RE}" \
  --certificate-oidc-issuer "${ISSUER}" \
  | jq -r 'if type=="array" then .[0] else . end | .payload | @base64d | fromjson | .predicate' \
  > "workbench-${TAG}.spdx.json"
jq -e '.spdxVersion and (.packages | type == "array")' "workbench-${TAG}.spdx.json" > /dev/null
echo "sbom: workbench-${TAG}.spdx.json ($(jq '.packages | length' "workbench-${TAG}.spdx.json") packages)"

Run that against a release digest before promoting an image to production.

Next

Run Workbench

docker pull ghcr.io/elevarq/workbench:v0.1.0

Pin a digest in production — verify the image.