
Starting with v117, every Vary release is signed with [Sigstore](https://www.sigstore.dev/) keyless signing. [Varyup](/docs/varyup/) verifies the signature automatically when you install or upgrade. You can also verify manually with cosign if you prefer.

## What ships with each release

Every Vary release on GitHub includes these files alongside the platform archives:

| File | What it is |
|------|-----------|
| `SHA256SUMS` | SHA-256 hashes of every release artifact |
| `SHA256SUMS.bundle` | Sigstore bundle (certificate + signature + transparency log entry) |
| `SHA256SUMS.sig` | Detached signature (legacy, kept for compatibility) |
| `*.spdx.json` | SPDX 2.3 SBOM for each platform archive |
| `release-attestation.json` | Build provenance (commit, workflow run, timestamps, hashes) |

The bundle is the important one. It contains everything cosign needs to verify that the `SHA256SUMS` file was signed by the official CI pipeline.

## Varyup checks signatures automatically

Starting with v117, varyup verifies the Sigstore bundle every time you install or upgrade. The install flow runs in this order.

| Step | Action |
|---|---|
| 1 | Download the platform archive |
| 2 | Download `SHA256SUMS` and `SHA256SUMS.bundle` |
| 3 | Verify the bundle against `SHA256SUMS` using Sigstore's trust root |
| 4 | Verify the archive's checksum against `SHA256SUMS` |
| 5 | Extract and install |

If the bundle is missing (older releases), varyup prints a warning and skips signature verification. If the bundle is present but verification fails, the install stops.

Varyup checks two things: that the signature is valid, and that the signing certificate was issued to a GitHub Actions workflow in the Vary repository. A valid signature from a different repository or a personal cosign key is rejected.

If you are running an older varyup binary, upgrade it before installing v117. Older binaries do not know about the bundle format and will skip verification silently.

## Manual verification with cosign

You do not need varyup to verify a release. Install [cosign](https://docs.sigstore.dev/cosign/system_config/installation/) and run two commands.

### Install cosign

```bash
# macOS
brew install cosign

# Linux
go install github.com/sigstore/cosign/v2/cmd/cosign@latest
```

### Step 1: verify the signature

```bash
cosign verify-blob \
  --bundle SHA256SUMS.bundle \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp "https://github.com/ccollicutt/vary" \
  SHA256SUMS
```

If the signature is valid, cosign prints `Verified OK`. This confirms that the `SHA256SUMS` file was produced by a GitHub Actions workflow in the Vary repository and has not been modified since.

The `--certificate-oidc-issuer` flag checks that the signing certificate came from GitHub Actions (not a personal key or a different CI system). The `--certificate-identity-regexp` flag checks that the workflow ran in the correct repository.

### Step 2: verify the checksums

```bash
sha256sum -c SHA256SUMS
```

This checks each downloaded file against its hash in `SHA256SUMS`. If you only downloaded one platform archive, pass `--ignore-missing` to skip the others:

```bash
sha256sum -c --ignore-missing SHA256SUMS
```

A match means the file on your disk is byte-identical to the file produced during the CI build. A mismatch means something changed in transit.

## What each step proves

Step 1 alone proves the checksums are authentic but says nothing about the files on your disk. Step 2 alone proves the files match some checksums but says nothing about who wrote them. Together they confirm: the file you have is the file the CI pipeline produced.

Neither step proves the source code is correct, or that the build process is free of bugs. What they do prove is provenance: this binary came from this repository's CI, and nothing tampered with it afterward.

## How the signing works

During a release, the CI pipeline runs `sign-checksum.sh`, which calls cosign in keyless OIDC mode.

| Step | Action |
|---|---|
| 1 | GitHub Actions mints an OIDC token identifying the workflow |
| 2 | Cosign exchanges the token for a short-lived signing certificate from Sigstore's Fulcio CA |
| 3 | Cosign signs `SHA256SUMS` and records the signature in Sigstore's Rekor transparency log |
| 4 | The certificate, signature, and log entry are saved as `SHA256SUMS.bundle` |

The signing certificate expires in minutes. It cannot be reused. The transparency log entry is permanent and publicly auditable: anyone can look up the signing event and confirm it happened.