CKS attestation admission enforced block versus dry-run audit
A prefix check asks where the image came from. An attestor asks whether this digest was signed.
<!-- hal:authoritative:yaml -->
A prefix check asks where the image came from. An attestor asks whether someone signed this digest. Dry-run changes the action, not the question.
§I. Frame
CKS day, odd counter. Recent CNCF lessons already took HPA (09-30), upgrade skew plus drain and eviction (09-27), StorageClass/PVC/PV (09-24), and ServiceAccount hardening with EKS Pod Identity (09-21). PSA restricted enforce was 09-12. AppArmor and seccomp on the node were 08-31.
Supply chain was 08-07: smaller base images, vulnerability scan, SBOM, and an ImagePolicyWebhook. The vault sample for that webhook still does one thing. Its README says the program allows only images that start with gcr.io/. That is a string prefix. It is not a signature.
The claim for today: admission can instead require a verified attestation on the image digest. GKE Binary Authorization is the managed form used in the Ops lesson. The CKS skill is the split between the check and the action, and the difference between a prefix webhook and an attestor.
§II. Two fields, not one knob
The policy YAML reference names the default rule defaultAdmissionRule.
evaluationMode is the check:
ALWAYS_ALLOWadmits every image this rule sees.ALWAYS_DENYrejects every image this rule sees.REQUIRE_ATTESTATIONadmits an image only when every attestor listed inrequireAttestationsBycan verify an attestation. The list must be non-empty in this mode, and empty in the other two.
enforcementMode is the action when the check fails:
ENFORCED_BLOCK_AND_AUDIT_LOGblocks the Pod and writes the violation to Cloud Audit Logs.DRYRUN_AUDIT_LOG_ONLYallows the Pod and writes the violation anyway.
Dry-run is how you watch a new attestor before it blocks deploys. It is not a second, weaker attestor. The attestor list stays the same.
A cluster-specific rule lives under clusterAdmissionRules, keyed LOCATION.CLUSTER_NAME (the Terraform docs use us-central1-a.prod-cluster). If the cluster has no key, the default rule is the one that runs.
§III. What the attestor is checking
Attestors sign image digests, not floating tags. A Pod that says app:1.4.2 can still pass if, at admission, that tag resolves to a digest the attestor has already signed. The same tag can fail tomorrow because it moved. A spec that already contains @sha256: names the digest the attestor must have signed. The Rust census in the Dev lesson only detects that shape. Passing the census is not a CKS "allowed" answer.
requireAttestationsBy entries are attestor resource ids, projects/PROJECT/attestors/NAME. The attestor has to exist before the policy references it. Creating the note and the key is a separate admin step. The exam-shaped question is which rule field lists them, not how to mint a KMS key.
§IV. What is allowed without your signature
Two exemption mechanisms show up in the same policy file. Do not merge them.
globalPolicyEvaluationMode: ENABLE tells Binary Authorization to use Google's own system-image evaluation. GKE-managed images then do not need your attestor. Leave it off, and a policy of REQUIRE_ATTESTATION can reject the images the control plane is trying to run.
admissionWhitelistPatterns is a list of namePattern strings you write. A pattern such as us-central1-docker.pkg.dev/payments-prod/break-glass/* skips the rule for matching names. That is the break-glass door. It is also the door an attacker uses if the pattern is *.
Neither mechanism is a namespace label. pod-security.kubernetes.io/enforce=restricted is PSA. It does not turn attestation on or off. ImagePolicyWebhook, the 08-07 control, is also not this list. That webhook is a Kubernetes admission plugin with its own backend. The study-guide backend hard-codes a registry prefix. Binary Authorization's whitelist is a field on the project policy, evaluated by GKE's enforcer, and it still is not a signature check.
§V. Drill
Answer from the field, not from the product nickname.
- The Pod is created, and Cloud Audit Logs still show an attestation miss. Which value is set?
enforcementMode: DRYRUN_AUDIT_LOG_ONLYwith a failingevaluationMode. Blocked Pods meanENFORCED_BLOCK_AND_AUDIT_LOG. - You want every non-exempt image to need the build attestor, and one cluster to deny all images. Default rule
REQUIRE_ATTESTATIONplus that attestor. The special cluster getsclusterAdmissionRuleswithALWAYS_DENY. - A webhook that allows only
gcr.io/would still admit an unsigned image from that registry. An attestor rule would not, unless the name is whitelisted or the mode is dry-run. - Putting
requireAttestationsByon anALWAYS_ALLOWrule is invalid. The list is required only forREQUIRE_ATTESTATION, and it must be empty otherwise.
§VI. Close
CKS supply chain already covered scan, SBOM, and a prefix webhook. This lesson adds the attestor question and the enforce-versus-dry-run action. GKE expresses both as evaluationMode and enforcementMode on one admission rule, with system images and name patterns as the only exemptions in that policy.
Paired Ops declares the cluster flag and the project policy in Terraform, then censuses image strings. Paired Dev matches those strings. Neither pair proves the signature. The policy does, at admission time.
Related
- Tome: CKS study guide ch06 image-validation webhook README (prefix
gcr.io/) (grounded-in as the control this lesson does not repeat) - Gap: the vault has no Binary Authorization chapter. Rule fields are from the policy YAML reference.
- Prior Cert: ImagePolicyWebhook 08-07, PSA 09-12, HPA 09-30, skew/drain 09-27, PVC 09-24, ServiceAccount 09-21
- Web: policy YAML reference, gcloud policy config, ImagePolicyWebhook admission docs