diff --git a/README.md b/README.md index fa54aeb..bf1a1b9 100644 --- a/README.md +++ b/README.md @@ -335,6 +335,40 @@ Dependencies are declared in `packages/core/package.json` and `packages/stdio/pa - [OSV Scanner](https://github.com/google/osv-scanner) and [Trivy](https://github.com/aquasecurity/trivy) scan for known CVEs in both npm dependencies and the Docker image on every build - The Docker runtime image runs `apk upgrade --no-cache` at build time to apply the latest Alpine OS package patches regardless of the pinned base image digest +## Verifying releases + +Every Docker image published to GHCR has a [SLSA Level 2 provenance attestation](https://slsa.dev/) generated by GitHub Actions. You can verify that an image was built from this repository's official pipeline using the GitHub CLI: + +```bash +gh attestation verify \ + oci://ghcr.io/paradoxbound/bookstack-mcp:2.6.0 \ + --owner paradoxbound +``` + +A successful verification confirms: +- The image was built by a GitHub Actions workflow in this repository +- The exact source commit that produced it +- It has not been tampered with after publication + +To verify a specific digest rather than a tag: + +```bash +# Get the digest first +docker pull ghcr.io/paradoxbound/bookstack-mcp:2.6.0 +docker inspect ghcr.io/paradoxbound/bookstack-mcp:2.6.0 --format '{{index .RepoDigests 0}}' + +# Verify by digest +gh attestation verify \ + oci://ghcr.io/paradoxbound/bookstack-mcp@sha256: \ + --owner paradoxbound +``` + +Source releases are signed git tags — you can verify the tag signature with: + +```bash +git tag --verify v2.6.0 +``` + ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on making changes, running tests, and the DCO sign-off requirement.