What Kubernetes Is Missing

Every major operating system verifies that the software you install is what its developer actually released. Signatures prove both identity and integrity: the binary hasn't been swapped or modified since it left the author's hands. App stores, macOS, Android, and Linux package managers like Apt and Pacman all apply this model at install time.

Kubernetes has no such default. Nothing stops an untrusted or malicious Docker image from running in your cluster, and that risk scales with what the cluster touches. A compromised container sharing a cluster with your email service, for example, could attempt to reach into databases holding your customers' data. For Shopify, preventing that scenario has been a priority since the company's move to Kubernetes.

Binary Authorization brings the code signing model to containers: a metadata service stores signatures and image metadata, an enforcement service blocks images without valid signatures, and a signing service signs new images and records those signatures. Google provides the first two components for Google Kubernetes Engine (GKE) via the open source Grafeas (metadata) and Kritis (enforcer) projects. The missing piece was the signing service, which is where Voucher comes in.

How Code Signing Works

Signing starts with a hash of the application's contents. A hashing algorithm produces a short, reproducible value that represents that exact version, and with modern algorithms it's practically impossible to find two different inputs producing the same hash. A file containing Hello World hashes with sha256 to:

d2a84f4b8b650937ec8f73cd8be2c74add5a911ba64df27458ed8229da804a26

Change one character — Hello World! — and the resulting hash is completely different:

03ba204e50d126e4674c005e04d82e84c21366780af1f43bd54a37816b6ab340

Signing tools handle hashing transparently. The developer creates a public/private key pair, shares the public half, and signs the hash of the application with the private half. Anyone holding the public key can verify the application hasn't been tampered with. With a tool like Minisign, the public key looks like:

RWSs3jHbeTsmYhWlyqpDEufCe5QSGHsb1fFnglZItPwDfJ3wEZzSGyBJ

Users rarely run these steps explicitly — verification happens in the background. You only hear about it when something fails, as when macOS blocks an app with a missing or invalid signature.

Voucher Complements Grafeas and Kritis

Voucher runs as a REST endpoint in Google Cloud Run or Kubernetes. In Shopify's setup, every build pipeline automatically calls Voucher with the path to the image it just built. Voucher reviews the image, signs it if the configured checks pass, and pushes the signature to the metadata service. Kritis then consults that metadata when new resources start: if an image lacks the signatures the cluster policy requires, the image is blocked and its containers never run.

Infrastructure developers use policies to declare which keys, or attestors, must have signed an image before it can run. Because Voucher supports separate security checks with separate signing keys, policies can mix and match requirements per cluster. Teams can layer checks according to their risk tolerance:

  • An is_shopify check verifies that an image came from a Shopify-owned repository
  • A check confirms the image is associated with a Git commit in a GitHub repo you own
  • Signatures can require that changes were approved by multiple people, backed by GitHub approval data (with support for other code hosting services planned)
  • Additional checks verify the identity of the container builder and block images with a high number of vulnerabilities

Voucher is designed to be extensible, so new checks can be added as needs arise. The practical effect: compliance-focused clusters can require approvals and reject vulnerable images, while staging or experimental clusters can run under looser policies — and developers who aren't working on security don't have to manage signing keys themselves.

Voucher Is Now a Google Service

Voucher began as a Shopify project, released as open source in December 2018. Shopify's security team collaborated with Google's Binary Authorization team throughout design and rollout. Voucher has since been accepted into the Grafeas organization and is now offered as a service to GKE users. For Shopify, that move puts the signing component in the same project as the other open source Binary Authorization components and opens the project to a wider community of contributors.