Skip to content

Verifying a release

The customer-local bundle includes a signed manifest. Verify it before you extract the archive or log in to the image registry. The open source server is a public repository that you clone and build; it has no release manifest to verify.

Four files, published together in a per-version directory under /releases/, where every published version is listed.

File What it is
metergraph-customer-local-<version>.tar.gz The bundle: bin/, docker-compose.yml, .env.example. No images, no data, no credential
metergraph-byoc-release.json The manifest. It records the bundle’s SHA-256, both image repositories and their exact digests, and the platforms published for this release
metergraph-byoc-release.json.sig The detached signature over the manifest
metergraph-byoc-release.json.pem The certificate the signature was made with

No account or credential is needed to fetch these files. The images are private, but the files that identify and verify them are public.

  1. Sigstore’s installation guide covers every platform. On macOS:

    brew install cosign
  2. base=https://www.metergraph.dev/releases/<version>
    curl -fsSLO "$base/metergraph-customer-local-<version>.tar.gz"
    for f in metergraph-byoc-release.json{,.sig,.pem}; do curl -fsSLO "$base/$f"; done

    If curl reports a 404, this site does not have that version. Use a version listed on the releases page, which lists a new release only once its files are published here.

  3. cosign verify-blob \
    --certificate metergraph-byoc-release.json.pem \
    --signature metergraph-byoc-release.json.sig \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    --certificate-identity-regexp '^https://github\.com/PioneerSquareLabs/metergraph-internal/\.github/workflows/byoc-release\.yml@refs/(heads/main|tags/v.+)$' \
    metergraph-byoc-release.json

    The signature uses keyless signing. The verification pins the repository, the workflow file byoc-release.yml, and GitHub’s OIDC issuer. The git ref is matched loosely because a published release runs the workflow on its tag while the same workflow can run from the default branch.

    A signature made by any other workflow, in any other repository, fails here.

  4. Check the bundle against the verified manifest

    Section titled “Check the bundle against the verified manifest”

    The manifest records the bundle’s own checksum, so verifying the manifest also authenticates the archive. Read the expected value out of the manifest rather than off a web page, so the two cannot disagree:

    python3 - <<'EOF'
    import hashlib, json, sys
    manifest = json.load(open("metergraph-byoc-release.json"))
    name = manifest["local_bundle"]
    actual = hashlib.sha256(open(name, "rb").read()).hexdigest()
    if actual != manifest["local_bundle_sha256"]:
    sys.exit(f"{name} does not match the signed manifest. Do not run it.")
    print(f"{name} matches the signed manifest.")
    EOF

    Releases cut before the manifest carried local_bundle_sha256 have no bundle checksum to check. Their release page omits this step rather than describing a check the manifest cannot support.

  5. Extract, and move the manifest in beside it

    Section titled “Extract, and move the manifest in beside it”
    tar xzf metergraph-customer-local-<version>.tar.gz
    mv metergraph-byoc-release.json* local/
    cd local

    The three metergraph-byoc-release.json* files must end up inside local/, next to bin/start. If they do not, bin/start stops with error: metergraph-byoc-release.json not found.

From here, follow the customer-local bundle: registry login, .env, ./bin/start.

The manual check above proves the archive. bin/start then repeats and extends the proof each time it runs, using the same trust anchor.

  1. All three manifest files are present, or it exits before doing anything.
  2. cosign verify-blob over the manifest, with the same issuer and identity pattern you used by hand.
  3. Your host architecture is one of the manifest’s local_platforms, so a release that was never published for this machine fails clearly instead of pulling something that cannot run.
  4. Both image references are resolved from the manifest, and a reference is refused unless the digest matches sha256: plus 64 hex characters. A tag-shaped reference is a hard error. There is no fall back to a mutable tag, ever.
  5. cosign verify on each resolved image, against that same identity.

Only then are the digests written to .images.env and handed to Compose, which reads that file last so a stray METERGRAPH_APP_IMAGE in your .env cannot override a verified digest.

Verification tells you exactly which images you are about to run. Pulling them still needs the registry user and token that came with your invitation. Ask your Metergraph contact if you do not have them.

Everything needed to verify a release is public. Only the artifact itself is private.