Binary Authorization: Only Deploying Container Images You Can Prove Are Safe
A container registry with push access is, functionally, a way for anyone or anything holding that access to get code running in production โ and in most setups, thatโs a much larger group of people and systems (CI pipelines, individual engineers with docker push credentials, third-party base images) than the group actually authorized to decide what runs in production. Binary Authorization closes that gap: itโs a deploy-time enforcement control for GKE and Cloud Run that only allows a container image to run if it carries cryptographic proof โ an attestation โ that it passed whatever checks your policy requires, no matter who or what tried to push it to the registry.
The mental shift this requires is important: Binary Authorization doesnโt ask โis this image safeโ at scan time โ it asks โcan I prove, right now, at deploy time, that this exact image passed the checks I requireโ and refuses to run anything that canโt answer yes.
The Core Mechanism: Attestations
An attestation is a cryptographically signed statement that a specific container image digest satisfied a specific condition โ โthis image passed vulnerability scanning,โ โthis image was built by our CI pipeline, not pushed manually,โ โthis image passed security team review.โ Binary Authorization doesnโt inspect the image itself; it checks whether the required attestations exist and are validly signed.
Build pipeline builds image โ โผImage pushed to Artifact Registry (assigned a content-addressable digest) โ โผCI pipeline runs vulnerability scan โโโบ Passes โโโบ Sign attestation with Cloud KMS key โ โผDeploy request to GKE / Cloud Run โ โผBinary Authorization admission controller checks: does this image digest have a valid attestation for every required attestor in the policy? โ โโโโโโดโโโโโ Yes No โ โ โผ โผ Deploy Deployment allowed blockedBecause attestations are tied to the imageโs content digest, not its tag, you canโt defeat the check by re-pushing a different image under the same tag โ the digest changes, and the attestation no longer applies. This is a meaningful security property tags alone donโt provide, since tags are mutable pointers that can be silently repointed.
Setting Up an Attestor and Policy
# Create a Cloud KMS key to sign attestationsgcloud kms keys create binauthz-attestor-key \ --location=us-central1 \ --keyring=security-keys \ --purpose=asymmetric-signing \ --default-algorithm=ec-sign-p256-sha256
# Create the attestorgcloud container binauthz attestors create vuln-scan-passed \ --attestation-authority-note=projects/my-project/notes/vuln-scan-note \ --attestation-authority-note-project=my-project
# Sign an attestation for a specific image digest after it passes scanninggcloud container binauthz attestations sign-and-create \ --artifact-url="us-docker.pkg.dev/my-project/repo/app@sha256:abc123..." \ --attestor=vuln-scan-passed \ --attestor-project=my-project \ --keyversion-key=binauthz-attestor-key \ --keyversion-location=us-central1 \ --keyversion-keyring=security-keys \ --keyversion=1The policy itself, applied at the project or cluster level, defines which attestors are required before any deployment is allowed:
defaultAdmissionRule: requireAttestationsBy: - projects/my-project/attestors/vuln-scan-passed - projects/my-project/attestors/built-by-ci enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOGRequiring multiple attestors composed together โ โpassed vulnerability scanningโ AND โbuilt by the trusted CI pipeline, not pushed manuallyโ โ is a materially stronger guarantee than either check alone, since it closes both the โvulnerable imageโ gap and the โunauthorized image sourceโ gap simultaneously.
Walking Through an Attack This Actually Prevents
The abstract description of Binary Authorization is easy to nod along to and hard to viscerally appreciate without a concrete scenario. Hereโs the failure mode itโs specifically designed to stop.
Notice what this scenario assumes: the attacker has legitimate push access to the registry (a compromised CI token, a leaked credential โ a realistic scenario, not a contrived edge case) but does not have access to the attestor signing key, because that key is scoped far more narrowly. Registry push access and attestation-signing access are deliberately different privilege levels, and that separation is what makes the control meaningful โ if the same credential could do both, Binary Authorization would only be adding friction, not real security.
Binary Authorization vs Vulnerability Scanning Alone
Itโs worth being precise about what problem this solves that scanning alone doesnโt, since the two are often conflated.
โโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Approach โ What it actually guarantees โโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโคโ Vulnerability scanning โ This image was scanned and the โโ alone (no enforcement) โ result is visible in a dashboard โ โโ โ nothing stops a vulnerable image โโ โ from being deployed anyway โโ Binary Authorization โ This exact image digest cannot run โโ (with scan-based attestor) โ unless the scan attestation exists โโ โ and is validly signed โ enforcement, โโ โ not just visibility โโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโA lot of organizations run vulnerability scanning and assume theyโre covered, without realizing scanning alone is purely informational unless something actually blocks deployment based on the result. Binary Authorization is the piece that turns โwe scan our imagesโ into โwe cannot deploy an image that failed scanning,โ which is a meaningfully different and stronger guarantee โ the gap between having a smoke detector and having a fire suppression system that actually activates.
Dry-Run Mode: Rolling Out Without Breaking Deploys
Enabling Binary Authorization in full enforcement mode against an existing deployment pipeline that has no attestation infrastructure yet is a guaranteed outage. DRYRUN_AUDIT_LOG_ONLY mode exists specifically to avoid that:
defaultAdmissionRule: requireAttestationsBy: - projects/my-project/attestors/vuln-scan-passed enforcementMode: DRYRUN_AUDIT_LOG_ONLYIn this mode, deployments that would have been blocked are logged, not actually blocked โ giving the team a real window to build out the attestation-signing steps in CI, verify every legitimate deployment path is covered, and only flip to enforcement once the audit logs show zero unexpected blocks. Skipping this step is the single most common reason teams have a bad first experience with Binary Authorization.
Real-World Use Case: Enforcing โNo Manual Deploys to Productionโ
A common and genuinely high-value policy: production deployments must be built and attested exclusively by the CI pipeline, never pushed manually by an engineer running docker push and kubectl apply from their laptop, even in an emergency. This isnโt about distrusting engineers โ itโs about guaranteeing that every production image has a traceable build provenance (which commit, which pipeline run, what tests passed) rather than relying on process discipline alone, which breaks down under exactly the kind of time pressure an incident creates. The attestor requiring โbuilt by CIโ makes this a technical guarantee instead of a policy document nobody reads during a 2 AM outage.
Best Practices
- Always roll out new attestor requirements in dry-run mode first, reviewing audit logs for at least one full deployment cycle before enforcing.
- Compose multiple attestors for layered guarantees rather than relying on a single broad check โ vulnerability scan, build provenance, and manual security review (for particularly sensitive services) are each catching a different failure mode.
- Scope attestor signing keys tightly in IAM. The whole security model collapses if the key used to sign attestations is broadly accessible โ treat it with the same care as a production credential, because functionally, thatโs exactly what it is.
- Include a documented, audited break-glass exception path. Emergencies happen; the answer isnโt disabling Binary Authorization entirely under pressure, but having a pre-approved, logged exception process for genuinely urgent situations.
- Apply stricter policies to production than to lower environments. Development and staging clusters often benefit from faster iteration without full attestation overhead, while production is exactly where the enforcement guarantee matters most โ a tiered policy reflects that difference deliberately rather than applying one blanket rule everywhere.
Common Mistakes
Enabling enforcement mode without dry-run validation first. This reliably blocks legitimate deployments the moment enforcement flips on, usually during a deploy someone didnโt expect to be affected.
Treating โpassed vulnerability scanโ as the only attestation worth requiring. A scan-only policy still allows anyone with registry push access to deploy a scanned-but-unauthorized image โ build provenance attestation closes a different, equally real gap.
Not rotating or protecting the attestor signing key with the same rigor as other production secrets. A compromised signing key defeats the entire attestation model, since an attacker with that key can sign attestations for malicious images.
Forgetting to update attestation policy when the CI pipeline itself changes. A pipeline migration or a new build tool that changes how images are produced can silently break attestation generation โ treating this as infrastructure that needs monitoring, not a one-time setup, avoids a gap where deploys either fail unexpectedly or, worse, an alternate unattested path quietly emerges.
Frequently Asked Questions
Does Binary Authorization scan images for vulnerabilities itself? No โ it enforces that required attestations exist; the actual scanning (via Artifact Analysis or a third-party scanner) is a separate step in your pipeline that then signs an attestation based on the scan result.
Can Binary Authorization be bypassed by pushing directly to the clusterโs node? No โ enforcement happens at the Kubernetes admission controller level (for GKE) or the Cloud Run deployment API level, intercepting every deployment attempt regardless of how itโs initiated, not just deployments through a specific pipeline.
What happens to already-running workloads when a new policy is enforced? Binary Authorization evaluates at deploy time, not continuously against already-running pods โ existing workloads keep running until their next deployment or restart triggers re-evaluation against the current policy.
Is Binary Authorization required for all GKE clusters? No, itโs an opt-in feature you enable per cluster or project โ many teams run GKE without it, though itโs increasingly considered a baseline control for production clusters handling sensitive workloads.
Does this slow down deployments noticeably? The admission check itself is fast โ a lookup against existing attestations, not a live scan โ so it adds negligible latency to the deploy process itself. The real time cost is upfront: building out the CI steps that generate attestations in the first place.
Can different clusters or namespaces have different Binary Authorization policies? Yes โ policies can be scoped per project, and cluster-specific rules can override the project default, which is useful for applying stricter requirements to production clusters than to development or staging environments where faster iteration matters more than deploy-time enforcement.
What happens if the attestorโs signing key is deleted or destroyed? Existing signed attestations remain valid for verification (theyโre independently stored records), but new attestations can no longer be signed with that key โ losing a signing key without a recovery plan means the CI pipeline can no longer produce new deployable images until a replacement attestor and key are provisioned and wired into the pipeline.
Summary
Binary Authorization converts โwe trust our deployment processโ from an assumption into something you can technically enforce and prove โ every production image either carries valid, current attestations from your required checks, or it simply doesnโt run, regardless of who tried to deploy it or how. The rollout discipline matters as much as the feature itself: dry-run first, compose multiple attestors for layered coverage, and protect the signing keys as carefully as any other production credential, since theyโre the actual root of trust the whole system rests on โ and a systemโs guarantees are never stronger than the weakest-protected key underneath them, no matter how sound and well-reasoned the rest of the design otherwise is.