Break-glass, Policy Exceptions và Anti-patterns
Tại sao quan trọng trong production
Binary Authorization, khi được cấu hình đúng, blocks deployments không có attestation hợp lệ. Nhưng trong production thực tế, luôn có tình huống cần deploy nhanh mà không có time để đi qua toàn bộ attestation workflow — critical security patch lúc 3 giờ sáng, incident response, hoặc CI pipeline bị broken. Break-glass là tính năng được thiết kế cho những tình huống này.
Vấn đề: break-glass là cơ chế bypass bảo mật. Nếu không được kiểm soát chặt chẽ, nó trở thành backdoor thường xuyên được dùng thay vì exception. Hiểu đúng cơ chế — đặc biệt là audit trail — là điều kiện để thiết kế governance đúng đắn.
Song song đó, allowlist exceptions (admissionWhitelistPatterns) cũng là nguồn gốc của nhiều security gaps. Mỗi entry trong allowlist là một hole trong policy. Hiểu khi nào dùng allowlist và khi nào không là kỹ năng quan trọng.
Break-glass: Emergency Bypass Mechanism
Cơ Chế Bên Trong
Break-glass không phải là một policy mode hay cluster configuration — nó là một Kubernetes annotation được thêm vào Pod spec tại thời điểm deployment:
apiVersion: v1
kind: Pod
metadata:
name: emergency-fix
namespace: production
annotations:
alpha.image-policy.k8s.io/break-glass: "true" # annotation magic
spec:
containers:
- name: app
image: gcr.io/my-project/app@sha256:abc123Khi Binary Authorization webhook thấy annotation này:
- Bỏ qua tất cả policy evaluation: Không check attestors, không check
REQUIRE_ATTESTATION, không check evaluation mode — image được allow bất kể - Ghi mandatory audit log: Dù image được allow, một log entry đặc biệt được ghi vào Cloud Audit Logs với severity cao hơn normal enforcement events
- Không thể disable audit: Audit logging cho break-glass events là mandatory — không có cách nào bypass annotation mà không tạo audit record
Điều này có nghĩa: break-glass không phải "deploy silently without BinAuthz". Nó là "deploy with explicit bypass và mandatory disclosure".
Annotation Format Và Scope
# Format đúng
annotations:
alpha.image-policy.k8s.io/break-glass: "true"
# Không hoạt động (sai annotation name)
annotations:
binary-authorization/break-glass: "true"Annotation phải ở level Pod (không phải Deployment, không phải namespace). Khi dùng với Deployment:
# Annotation phải ở trong spec.template.metadata (Pod template)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
metadata:
annotations:
alpha.image-policy.k8s.io/break-glass: "true" # Đây, không phải ở Deployment metadata
spec:
containers:
- name: app
image: gcr.io/my-project/app@sha256:abc123Scope của break-glass: Annotation áp dụng cho tất cả containers trong Pod — không thể break-glass cho một container cụ thể trong Pod.
Audit Log Cho Break-glass Events
Khi break-glass được dùng, Cloud Audit Log entry có structure đặc biệt:
{
"logName": "projects/my-project/logs/cloudaudit.googleapis.com%2Factivity",
"severity": "WARNING",
"protoPayload": {
"methodName": "io.k8s.core.v1.pods.create",
"authorizationInfo": [
{
"permission": "container.pods.create",
"granted": true,
"resourceAttributes": {
"namespace": "production",
"name": "emergency-fix"
}
}
],
"metadata": {
"binaryAuthorization": {
"policyRef": "projects/my-project/policy",
"containerChecks": [
{
"containerName": "app",
"image": "gcr.io/my-project/app@sha256:abc123",
"verdict": "VERDICT_ALLOWED_BY_BREAKGLASS", // key field
"checkResults": []
}
]
}
},
"requestMetadata": {
"callerIp": "203.0.113.X", // IP của người dùng gcloud/kubectl
"callerSuppliedUserAgent": "kubectl/v1.28.0"
}
}
}Trường then chốt: verdict: "VERDICT_ALLOWED_BY_BREAKGLASS" — cho phép filter log entries để tìm tất cả break-glass events.
Monitoring Break-glass Abuse
Thiết lập alerting ngay khi bật Binary Authorization:
# Tạo log-based metric cho break-glass events
gcloud logging metrics create breakglass_events \
--description="Binary Authorization break-glass bypass events" \
--log-filter='resource.type="k8s_cluster"
AND protoPayload.metadata.binaryAuthorization.containerChecks.verdict="VERDICT_ALLOWED_BY_BREAKGLASS"'# breakglass-alert.yaml
displayName: "URGENT: Binary Authorization Break-glass Used"
combiner: OR
conditions:
- displayName: "Break-glass event detected"
conditionThreshold:
filter: metric.type="logging.googleapis.com/user/breakglass_events"
comparison: COMPARISON_GT
thresholdValue: 0
duration: 0s # alert ngay lập tức, không đợi
alertStrategy:
autoClose: 300s # auto-close sau 5 phút
notificationChannels:
- "projects/my-project/notificationChannels/security-team-pagerduty"
- "projects/my-project/notificationChannels/security-slack"Query để audit break-glass history:
# Tất cả break-glass events trong 30 ngày qua
gcloud logging read \
'resource.type="k8s_cluster"
AND protoPayload.metadata.binaryAuthorization.containerChecks.verdict="VERDICT_ALLOWED_BY_BREAKGLASS"' \
--project=${PROJECT_ID} \
--freshness=30d \
--format='table(
timestamp,
resource.labels.cluster_name,
resource.labels.namespace_name,
protoPayload.authorizationInfo[0].resourceAttributes.name,
protoPayload.requestMetadata.callerIp,
protoPayload.authenticationInfo.principalEmail
)'IAM Kiểm Soát Ai Có Thể Dùng Break-glass
Break-glass không có IAM control riêng — bất kỳ ai có quyền container.pods.create (tức là có thể deploy Pod) đều có thể dùng annotation break-glass. Không có permission riêng để "enable break-glass".
Implication: Nếu muốn restrict break-glass chỉ cho một nhóm nhất định, phải restrict container.pods.create permission cho namespace production. Mọi người có quyền deploy đều có quyền break-glass trong context đó.
Phương án alternative: Dùng policy + automation để detect break-glass trong CI/CD pipeline và require approval trước khi annotation được thêm vào (ví dụ: require 2 approvals trong GitHub để merge PR có break-glass annotation).
Lifecycle Sau Break-glass
Break-glass là stopgap — deployment khẩn cấp cho đến khi proper attestation được tạo. Cần process để "heal" sau break-glass:
1. Emergency: Deploy với break-glass annotation
2. Alert fired → security team notified
3. Root cause analysis: Tại sao cần break-glass?
- CI pipeline broken? → Fix CI
- Attestation key issue? → Fix key management
- New image source not in policy? → Update policy properly
4. Create proper attestation cho image đã deploy
5. Redeploy image với digest (loại bỏ break-glass annotation)
6. Verify: break-glass annotation không còn trong any running PodPost-incident requirement: Sau khi dùng break-glass, phải tạo attestation và redeploy không có annotation. Để lại break-glass annotation vĩnh viễn là anti-pattern nghiêm trọng.
Allowlist Exceptions: Policy Carve-outs
admissionWhitelistPatterns: Cơ Chế
Allowlist cho phép một số images bypass tất cả policy evaluation:
admissionWhitelistPatterns:
- namePattern: gcr.io/google_containers/*
- namePattern: k8s.gcr.io/**
- namePattern: registry.k8s.io/**
- namePattern: gcr.io/gke-release/**Matching semantics:
*: Match bất kỳ ký tự nào ngoại trừ/— tức là match một path segment**: Match bất kỳ ký tự nào bao gồm/— tức là match nhiều path segments
Ví dụ:
gcr.io/my-project/* → match: gcr.io/my-project/app
→ KHÔNG match: gcr.io/my-project/team/app
gcr.io/my-project/** → match: gcr.io/my-project/app
→ match: gcr.io/my-project/team/appAllowlist check xảy ra trước attestation lookup — nếu image match bất kỳ pattern nào, attestation không được check.
globalPolicyEvaluationMode: System Images Exemption
globalPolicyEvaluationMode: ENABLEKhi enable, Binary Authorization tự động exempt một danh sách system images được Google quản lý. Danh sách này bao gồm:
- GKE node agent images
- Kubernetes system component images
- GKE addons images
# Xem danh sách system images được exempt
gcloud alpha container binauthz policy export-system-policyĐây là necessary exemption cho GKE hoạt động đúng. Nếu không enable, các system components sẽ không deploy được và cluster không khởi động đúng.
Khi Nào Dùng Allowlist Hợp Lệ
Hợp lệ:
- GKE system images và Kubernetes system components
- Third-party sidecar images không thể tạo attestation (ví dụ: Istio proxy từ official registry, khi attestation workflow không cover images external)
- Images trong environment không thể thay đổi dễ dàng (legacy, vendor-provided)
Không hợp lệ:
- Team images để tránh phải setup attestation pipeline — đây là lazy exemption, không phải legitimate use case
- Wildcard patterns quá rộng:
**hoặcgcr.io/**— exempts tất cả images từ một registry - Tag-based patterns thay vì digest-based khi có thể
Best practice cho allowlist:
# KHÔNG tốt: quá rộng
admissionWhitelistPatterns:
- namePattern: gcr.io/my-project/** # mọi image trong project đều exempt
# TỐT HƠN: specific với digest
admissionWhitelistPatterns:
- namePattern: gcr.io/my-project/legacy-app@sha256:KNOWN_DIGEST # pin exact digest
# TỐT NHẤT: không dùng allowlist, tạo attestation cho mọi image
# Chỉ exempt system images qua globalPolicyEvaluationModeAnti-patterns Phổ Biến
Anti-pattern 1: DRYRUN_AUDIT_LOG_ONLY Mãi Không Chuyển Sang Enforce
Mô tả: Team enable Binary Authorization với enforcementMode: DRYRUN_AUDIT_LOG_ONLY để "test trước" nhưng không bao giờ chuyển sang ENFORCED_BLOCK_AND_AUDIT_LOG.
Vì sao xảy ra: Dry-run mode tiện lợi — không block deployments, chỉ log. Team luôn có lý do để trì hoãn: "pipeline chưa ổn định", "cần thêm time để test", "đang trong freeze period". Dry-run trở thành permanent state.
Vấn đề cốt lõi: Dry-run mode không cung cấp bảo vệ gì. Binary Authorization bật nhưng không enforce nghĩa là không có supply chain security. Log violations nhưng không block là false sense of security — bạn biết có violations nhưng không làm gì.
Cách phòng: Set deadline rõ ràng khi bắt đầu dry-run. Ví dụ: "dry-run 2 tuần, sau đó switch to enforce". Track số violations giảm dần theo thời gian là indicator thành công. Nếu sau 4 tuần vẫn còn violations, có vấn đề với attestation pipeline, không phải với policy.
Anti-pattern 2: Allowlist Quá Rộng
Mô tả: Để tránh "ảnh hưởng deployment", team add allowlist entries rộng:
# Anti-pattern
admissionWhitelistPatterns:
- namePattern: us.gcr.io/** # mọi image từ US GCR
- namePattern: gcr.io/my-company/** # mọi image từ company GCR
- namePattern: docker.io/** # Docker Hub — mọi image publicVì sao nguy hiểm: Allowlist entries rộng có nghĩa là policy không có tác dụng gì với những images đó. Nếu gcr.io/my-company/** trong allowlist, attacker chỉ cần push malicious image vào project nào đó trong company để bypass BinAuthz.
Vấn đề cốt lõi: Allowlist không phải "we trust these images". Allowlist là "we skip attestation check for these images". Trust phải đến từ attestation, không phải location.
Cách phòng:
- Allowlist chỉ dùng cho images không thể có attestation (system images, legacy images với plan to migrate)
- Prefer digest-pinned patterns:
gcr.io/my-project/specific-image@sha256:DIGEST - Regular audit allowlist entries: xóa entries không còn cần thiết
- Document lý do tại sao mỗi entry tồn tại
Anti-pattern 3: Một Attestor Cho Tất Cả
Mô tả: Team dùng một attestor duy nhất (built-by-ci) cho mọi image. Một signing key, một note, tất cả images được sign bởi cùng một service account.
Vấn đề cốt lõi: Attestor đại diện cho "loại approval". Một attestor duy nhất nghĩa là một gate — không có defense in depth. Nếu CI service account bị compromise, tất cả attestations không còn đáng tin.
Multi-stage approval — attestors riêng cho "passed security scan", "passed QA", "approved for production" — tạo ra multiple independent gates mà attacker phải compromise cả cụm.
Cách phòng:
# Tốt hơn: multiple attestors cho defense in depth
requireAttestationsBy:
- projects/my-project/attestors/security-scan # CVE scan CI tool
- projects/my-project/attestors/qa-approved # QA team approval
- projects/my-project/attestors/built-by-cloud-build # origin verificationVới setup này, compromise CI credentials chỉ compromise built-by-cloud-build attestor — attacker vẫn cần compromise qa-approved (controlled bởi QA team với separate credentials).
Anti-pattern 4: Không Monitor Break-glass
Mô tả: Break-glass annotation được document trong runbook nhưng không có alerting. Audit logs có nhưng không ai xem.
Vấn đề cốt lõi: Nếu break-glass được dùng và không ai biết ngay, có thể có window lớn khi cluster chạy với unattested image. Tệ hơn: nếu break-glass annotation bị "quên" trong Deployment manifest, cluster chạy permanently với bypass active.
Anti-pattern thực tế: Developer dùng break-glass cho emergency fix, quên xóa annotation khỏi Deployment manifest, commit vào git. Sau đó mọi deployment của Deployment đó đều có break-glass — không ai để ý vì "nó vẫn deploy được".
Cách phòng:
- Alerting ngay khi có break-glass event (xem phần monitoring trên)
- CI gate: scan Kubernetes manifests cho
alpha.image-policy.k8s.io/break-glass: "true"annotation — fail CI nếu tìm thấy trong non-emergency branch - Regular audit:
kubectl get pods --all-namespaces -o json | jq '.items[] | select(.metadata.annotations["alpha.image-policy.k8s.io/break-glass"] == "true") | .metadata.name'
Anti-pattern 5: Tag Thay Vì Digest Trong Manifest
Mô tả: Mặc dù attestation được tạo đúng với digest, deployment manifest vẫn dùng tag:
# Anti-pattern trong Deployment manifest
containers:
- name: app
image: gcr.io/my-project/app:v1.2.3 # tag, không phải digestVấn đề cốt lõi: Đã được mô tả chi tiết trong file 03. Tag là mutable pointer — Binary Authorization phải resolve tag sang digest khi kiểm tra, và digest có thể đã thay đổi so với digest được sign trong CI.
Cách phòng: Enforce digest-only trong CI/CD. Khi tạo attestation, lưu full image reference với digest và dùng nó trong deploy step. Dùng admission webhook tùy chỉnh hoặc CI gate để reject Kubernetes manifests có image reference dùng tag (không có @sha256:).
# Kiểm tra trong CI
if kubectl get pod my-pod -o json | jq -r '.spec.containers[].image' | grep -v '@sha256:'; then
echo "ERROR: Found images without digest pinning"
exit 1
fiAnti-pattern 6: Default Rule ALWAYS_ALLOW Cho Production
Mô tả: Team set ALWAYS_ALLOW cho defaultAdmissionRule và chỉ configure REQUIRE_ATTESTATION cho specific clusters. Khi cluster mới được tạo, nó tự động fall vào defaultAdmissionRule với ALWAYS_ALLOW.
# Nguy hiểm
defaultAdmissionRule:
evaluationMode: ALWAYS_ALLOW # Tất cả clusters mới sẽ không có enforcement
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOGVấn đề cốt lõi: Policy mở theo mặc định (allow-first) thay vì đóng (deny-first). Cluster staging mới, cluster experimental — nếu không có cluster-specific rule, tất cả đều bị exempt. New cluster creation không trigger bất kỳ security review nào.
Cách phòng: Set defaultAdmissionRule với REQUIRE_ATTESTATION (hoặc ít nhất ALWAYS_DENY). Chỉ relax cho specific clusters khi cần, không phải relax cho "everything else".
# Đúng: deny-first default
defaultAdmissionRule:
evaluationMode: REQUIRE_ATTESTATION # Enforce cho tất cả clusters không có rule riêng
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/my-project/attestors/security-scan
# Relax cho dev clusters explicitly
clusterAdmissionRules:
us-central1-a.dev-cluster:
evaluationMode: ALWAYS_ALLOW
enforcementMode: DRYRUN_AUDIT_LOG_ONLYGovernance Pattern: Vận Hành Break-glass An Toàn
Để dùng break-glass an toàn trong tổ chức, cần process rõ ràng:
Trước khi dùng break-glass:
- Escalate to on-call security engineer (nếu có thể)
- Document lý do trong incident ticket
- Thử alternative: là CI pipeline có thể được fix nhanh không? Attestation có thể được tạo thủ công không?
Khi dùng break-glass:
- Thêm annotation vào manifest
- Deploy
- Verify alert fired → security team notified
- Ghi lại incident ticket ID trong annotation comment nếu có thể
Sau khi dùng break-glass:
- Tạo proper attestation cho image (bước này không thể skip)
- Redeploy không có break-glass annotation
- Verify annotation đã được xóa khỏi tất cả running Pods
- Post-incident review: làm gì để tránh break-glass lần sau
# Verify không còn break-glass annotations đang active
kubectl get pods --all-namespaces -o json | \
jq -r '.items[] | select(.metadata.annotations["alpha.image-policy.k8s.io/break-glass"] == "true") |
"\(.metadata.namespace)/\(.metadata.name)"'
# Output kỳ vọng: empty (không có Pod nào)Tài liệu tham khảo
- Using breakglass — cơ chế break-glass chính thức
- Binary Authorization audit logging — hiểu audit trail
- admissionWhitelistPatterns — pattern syntax
- globalPolicyEvaluationMode — system images exemption
- Binary Authorization best practices — production recommendations
- NIST SP 800-218: SSDF — secure software development framework