Everything DBSheriff ships can be verified by you, on your own machine, against public infrastructure that Sun AI and Data LLC does not control. Nothing below needs an account with us. Read this once before the first install; on a connected host the installer runs most of the same checks automatically (section 5 says exactly which, and which it does not).
| Artifact | Guarantee | Verified by |
|---|---|---|
| The six DBSheriff container images | Built by our release workflow (Sigstore records which workflow at which tag signed it), from the tagged commit, with the base images pinned by digest; not modified since | cosign signature (keyless, Sigstore) |
| Each image's build record (SLSA v1 provenance format) | What the release workflow reports about the build: the commit, the workflow run, the build arguments it records and the base images. The workflow writes this record itself and signs it with the same identity as the image, so it is a statement by that workflow, not independent proof; no SLSA build level is claimed | slsaprovenance1 attestation, signed by the same identity |
| Each image's SBOM | Every package inside the image, with versions (SPDX 2.3, produced by syft) | spdxjson attestation, signed by the same identity |
| The seven third-party images (Kafka, ZooKeeper, Redis, PostgreSQL, Grafana, Kafka UI, Ollama) | Exactly the upstream digest pinned in deploy/common/images.lock at release time; a moved upstream tag cannot change what runs |
pulled by digest, checked by the installer; listed with digests in IMAGES-v1.4.0.txt |
| The Python packages inside the images | Installed from hash-locked files: every package at one version, every file's sha256 checked at build time | the SBOM lists every package with its version |
| The install packages | Unchanged since the release built them | SHA256SUMS + its Sigstore signature |
| The air-gap bundle | Unchanged since the release built it; contains exactly the images listed | signed .sha256 and signed IMAGES-v1.4.0.txt |
| What we shipped | Every DBSheriff file under /app in each of the five Python images, compiled or plain (packages and operating-system files are in the SBOM) |
SHIPPED_FILES-v1.4.0.txt |
| Known vulnerabilities | The complete scan of every image at release time, and the accepted findings with their reason, owner and expiry date | cve-<image>-v1.4.0.json, cve-thirdparty-v1.4.0.txt, trivyignore-v1.4.0.txt |
The signatures are keyless: there is no private key at Sun AI and Data LLC that could leak or be misused. Each signature is made by GitHub's OpenID identity of the release workflow, for a few minutes, and recorded in the public Rekor transparency log. A signature therefore proves which workflow at which tag signed the artifact, and anyone can look the entry up. It does not prove that the workflow itself was free of a compromise: the build record above is written by that same workflow.
The identity to expect, for release v1.4.0:
ID=https://github.com/dbsheriffai/dbsheriff/.github/workflows/release.yml@refs/tags/v1.4.0
ISS=https://token.actions.githubusercontent.com
Releases up to v1.2.2 were published before the repository moved to its current
GitHub organization, so their signatures carry the earlier account name in the
identity. For those, take the identity printed in that release's NOTES.md
(it is downloaded with the release and lists the exact ID=); it differs from
the one above only in the account name. The bootstrap installer chooses the
right one for the --version you ask for.
cosign (a single binary),
sha256sum and jq (for the attestation commands in section 2). Docker is
needed to inspect images. All commands below are
read-only.
cosign verify-blob --bundle SHA256SUMS.sigstore.json --certificate-identity "$ID" --certificate-oidc-issuer "$ISS" SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS
# air-gap bundle
cosign verify-blob --bundle dbsheriff-v1.4.0-images.tar.gz.sha256.sigstore.json --certificate-identity "$ID" --certificate-oidc-issuer "$ISS" dbsheriff-v1.4.0-images.tar.gz.sha256
sha256sum -c dbsheriff-v1.4.0-images.tar.gz.sha256
cosign verify-blob --bundle IMAGES-v1.4.0.txt.sigstore.json --certificate-identity "$ID" --certificate-oidc-issuer "$ISS" IMAGES-v1.4.0.txt
IMAGES-v1.4.0.txt lists every image in the bundle with its registry digest
and its image id. The bundle is a gzip tar of one docker save archive per
image (images/NN-<image>.tar.gz, tar -tzf lists them), so a single image
can be loaded or inspected on its own. After docker load, docker image
inspect --format '{{.Id}}' <image> must equal the listed id; the installer
checks all thirteen.
For each DBSheriff image (the digests are in the release notes and in
IMAGES-v1.4.0.txt):
IMG=ghcr.io/dbsheriffai/dbsheriff-producer@sha256:<digest>
cosign verify --certificate-identity "$ID" --certificate-oidc-issuer "$ISS" "$IMG"
cosign verify-attestation --type slsaprovenance1 --certificate-identity "$ID" --certificate-oidc-issuer "$ISS" "$IMG" \
| jq -r '.payload | @base64d | fromjson | .predicate'
cosign verify-attestation --type spdxjson --certificate-identity "$ID" --certificate-oidc-issuer "$ISS" "$IMG" \
| jq -r '.payload | @base64d | fromjson | .predicate' > sbom-producer.spdx.json
cosign verify fails if the digest was not signed by that exact workflow and
tag. The build record shows the source commit, the workflow run URL, the build
arguments it records and the base image digests as the workflow reported them
(the commit, the run and the workflow file are in our private repository: the
record names them, but you cannot open them); the SBOM is the same document attached to
the release as sbom-<image>-v1.4.0.spdx.json and can be fed to your own
scanner (trivy sbom sbom-producer.spdx.json, grype sbom:sbom-producer.spdx.json).
Private images need registry credentials for cosign to fetch the signature:
docker login ghcr.io first with the read-only token from your release e-mail.
Every signature above has an entry in the Sigstore transparency log. cosign
verify prints the log index; you can view the entry at
https://search.sigstore.dev/?logIndex=<index> and see the certificate with the
workflow identity and the time of signing. The log is append-only and run by
the Linux Foundation, not by us.
SHIPPED_FILES-v1.4.0.txt: every file under /app in each image. Modules
from the release's compile manifest ship compiled (.so); everything else is
readable Python you can audit on the host.cve-<image>-v1.4.0.json: trivy's complete report per image at release
time, every severity, whether or not a fix exists. The release is refused if
any DBSheriff image has a CRITICAL vulnerability with a fix available that
trivyignore-v1.4.0.txt does not accept; that file lists each accepted
finding with its reason, an owner and an expiry date.cve-thirdparty-v1.4.0.txt: HIGH and CRITICAL findings in the pinned
third-party images we redistribute unchanged. The release is refused on a
fixable CRITICAL there too (accepted only through the same file); we bump a
pin when upstream ships a fix.On a connected host, before any container starts, deploy/common/host/verify_images.sh
runs the signature and both attestation checks on every DBSheriff image pulled from
the official registry, and compares every third-party image's digest with
images.lock; a failure stops the install. Two cases are not covered by it, so do
them by hand with sections 1 and 2:
--airgap checks the
bundle's checksum; when you run deploy/onprem/install.sh --airgap yourself,
check the bundle first with section 1. Either way the installer checks every
loaded image's id against the signed IMAGES-v1.4.0.txt, which has to be next
to the bundle (without it the install stops before anything is loaded); it does
not repeat the image signature check.DBSHERIFF_IMAGE_REGISTRY: set it in the installer's
environment on every run, sudo env DBSHERIFF_IMAGE_REGISTRY=<your mirror>/ bash install-v1.4.0.sh ...;
an edit of IMAGE_REGISTRY in .env is reset by the next installer run). The installer verifies signatures only for images under the official
registry prefix; an image from a mirror is neither one of ours nor pinned in
images.lock, so it is reported as NOT VERIFIED and the install stops, unless you
accept it on purpose with DBSHERIFF_ALLOW_UNVERIFIED_IMAGES=true. cosign verify
works on a mirror if it carries the signature tags: copy the image with a tool
that keeps them, verify it by hand, then accept it.The bootstrap installer verifies the signature of SHA256SUMS (and, with
--airgap, of the bundle's checksum and the image manifest) before it trusts a
checksum, and stops if a signature is missing or does not verify. It uses the
host's cosign, or else the cosign image pinned by digest through Docker, and
with neither it refuses; --skip-signature goes on without the check and says
so. The installer script itself is the one thing you verify before you run it:
verify the installer.
A finding to report: security@dbsheriff.ai (see SECURITY.md in the package).
Other questions: support@dbsheriff.ai.