Skip to content

Policy Model, Attestors và Deployment Decision Logic

Tại sao quan trọng trong production

Binary Authorization không đơn giản là "cho phép" hay "chặn" image. Hệ thống vận hành theo một mô hình phân cấp: một project có đúng một policy singleton, policy đó chứa nhiều rules, mỗi rule có evaluation mode và enforcement mode riêng. Hiểu sai cấu trúc này — ví dụ không biết rằng defaultAdmissionRule áp dụng cho mọi cluster không có rule riêng, hoặc nhầm lẫn giữa "evaluation mode" và "enforcement mode" — dẫn đến policy không hoạt động như kỳ vọng mà không có error message rõ ràng.

Theo Binary Authorization documentation, hệ thống dựa trên spec Kritis, một phần của dự án Grafeas open source. Mental model cốt lõi: policy là một tập hợp constraints mà image phải thỏa mãn trước khi được deploy, và attestors là các "trusted authority" chứng nhận rằng image đã thỏa mãn một constraint cụ thể.


Internal Model: Cấu Trúc Policy và Evaluation Engine

Policy là Project-Singleton Resource

Binary Authorization policy là project-singleton — mỗi GCP project có đúng một policy. Policy này kiểm soát tất cả các deployment trên GKE clusters (và Cloud Run, Google Distributed Cloud) trong project đó.

Policy được lưu trữ trong Binary Authorization API backend và được phục vụ như một resource có URI dạng:

projects/{PROJECT_ID}/policy

Đây là điểm quan trọng đầu tiên: policy sống ở tầng GCP project, không phải tầng Kubernetes cluster. Một GKE cluster có thể nhìn sang policy của project chứa nó. Trong multi-project setup (khuyến nghị cho production), cluster project, attestor project, và attestation project có thể tách biệt nhau.

Cấu Trúc YAML Của Policy

Khi export policy bằng gcloud, format YAML phản ánh internal structure của policy:

yaml
# export: gcloud container binauthz policy export
admissionWhitelistPatterns:
- namePattern: gcr.io/google_containers/*
- namePattern: k8s.gcr.io/**
globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: REQUIRE_ATTESTATION
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
  requireAttestationsBy:
  - projects/my-project/attestors/quality-assurance
clusterAdmissionRules:
  us-central1-a.production-cluster:
    evaluationMode: REQUIRE_ATTESTATION
    enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
    requireAttestationsBy:
    - projects/my-project/attestors/security-scan
    - projects/my-project/attestors/quality-assurance
  us-central1-a.staging-cluster:
    evaluationMode: REQUIRE_ATTESTATION
    enforcementMode: DRYRUN_AUDIT_LOG_ONLY
    requireAttestationsBy:
    - projects/my-project/attestors/security-scan

Các thành phần chính:

admissionWhitelistPatterns: Danh sách glob patterns cho các image được miễn đánh giá policy. Binary Authorization luôn cho phép deploy các image này. Patterns có thể dùng * (match một path segment) hoặc ** (match nhiều segments).

globalPolicyEvaluationMode: Khi set ENABLE, GKE system images (danh sách Google quản lý) được tự động exempt. Bạn có thể xem danh sách bằng gcloud alpha container binauthz policy export-system-policy.

defaultAdmissionRule: Rule mặc định áp dụng cho tất cả deployments không khớp cluster-specific rule. Đây là safety net — nếu một cluster mới được tạo mà chưa có rule riêng, nó bị kiểm soát bởi default rule.

clusterAdmissionRules: Rules cho cluster cụ thể, key là {location}.{cluster-name}.

Evaluation Modes: Ba Trạng Thái Logic

Mỗi rule có một evaluationMode xác định điều kiện cho image:

ALWAYS_ALLOW: Cho phép mọi image. Đây là chế độ mặc định khi mới bật Binary Authorization — không có gì bị chặn. Thường dùng cho môi trường dev hoặc khi chưa sẵn sàng enforce.

ALWAYS_DENY: Chặn mọi image. Hữu ích khi muốn lock down một cluster hoàn toàn và chỉ dùng allowlist.

REQUIRE_ATTESTATION: Yêu cầu image phải có attestation hợp lệ được ký bởi tất cả attestors trong danh sách requireAttestationsBy. Đây là chế độ production chính.

Quan trọng — semantics của REQUIRE_ATTESTATION: Khi một rule liệt kê nhiều attestors, image phải có attestation thỏa mãn mọi attestor (AND logic). Đây là thiết kế có chủ đích để bảo đảm multi-stage approval: ví dụ một attestor cho security scan, một attestor cho QA approval — image phải pass cả hai.

Enforcement Modes: Hai Chế Độ Hành Động

Tách biệt với evaluation mode, enforcementMode xác định hành động khi image không thỏa mãn policy:

ENFORCED_BLOCK_AND_AUDIT_LOG: Block deployment và ghi log vào Cloud Audit Logs. Image bị từ chối, Pod không được tạo. Đây là chế độ production.

DRYRUN_AUDIT_LOG_ONLY: Cho phép deployment nhưng ghi log vi phạm vào Cloud Audit Logs. Image được deploy dù không thỏa mãn policy. Dùng để test policy trong production environment trước khi chuyển sang enforce thực sự.

Sự tách biệt này cho phép pattern gradual rollout: áp DRYRUN_AUDIT_LOG_ONLY cho một cluster production, quan sát log trong vài tuần để đảm bảo không có false positives, sau đó chuyển sang ENFORCED_BLOCK_AND_AUDIT_LOG.


Internal Model: Attestors — Trusted Verifier

Attestor Là Gì (Về Mặt Kỹ Thuật)

Một attestor là một GCP resource với URI:

projects/{PROJECT_ID}/attestors/{ATTESTOR_NAME}

Attestor chứa hai thứ cốt lõi:

  1. Liên kết đến một Artifact Analysis note: Note xác định "loại" attestation mà attestor này xác minh. Mọi attestation thuộc loại này được lưu dưới dạng occurrence của note đó.

  2. Một hoặc nhiều public keys: Key được dùng để verify chữ ký mật mã trong attestation.

Về conceptually, attestor là sự kết hợp của: "Loại kiểm tra này đã được thực hiện" (note) + "Chỉ chữ ký từ những key này là đáng tin" (public keys).

Artifact Analysis Note: Liên Kết Giữa Attestor và Attestation

Artifact Analysis (trước đây là Container Analysis) là service lưu trữ metadata về container images. Nó dùng mô hình note/occurrence:

  • Note: Định nghĩa một loại metadata. Một note attestor có dạng:

    projects/{NOTE_PROJECT}/notes/{NOTE_ID}

    Note này thuộc type ATTESTATION.

  • Occurrence: Instance cụ thể của metadata cho một image. Khi signer tạo attestation cho image X, họ tạo một occurrence của note attestor này, gắn với digest của image X.

Tại sao thiết kế như vậy? Artifact Analysis đã là hệ thống lưu trữ metadata có sẵn (vulnerability findings, SBOM, build provenance). Binary Authorization tận dụng infrastructure này để không cần build lại storage layer riêng. Kết quả là attestations sống trong cùng database với vulnerability data, cho phép cross-referencing.

Query path tại enforcement time:

Signer ký image_digest → tạo Occurrence của Note N
Policy yêu cầu attestor A (trỏ đến Note N)
→ Enforcement query: "image_digest có occurrence của Note N không?"
→ Nếu có: verify signature bằng public keys của Attestor A
→ Nếu verify pass: cho phép deploy

Public Key Types: PKIX và PGP

Binary Authorization hỗ trợ hai loại key:

PKIX (X.509): Là loại khuyến nghị cho production mới. PKIX keys có thể lưu trong:

  • Local (public key PEM file)
  • External HSM
  • Cloud KMS — đây là lựa chọn tốt nhất cho production
bash
# Tạo key pair trong Cloud KMS
gcloud kms keyrings create binauthz-keyring \
  --location us-central1

gcloud kms keys create signing-key \
  --location us-central1 \
  --keyring binauthz-keyring \
  --purpose asymmetric-signing \
  --default-algorithm ec-sign-p256-sha256

PGP: Legacy format, vẫn supported nhưng không còn là lựa chọn ưu tiên. PGP keys không tích hợp với Cloud KMS.

Thuật toán ký số: Binary Authorization hỗ trợ ECDSA (P-256, P-384) và RSA (2048, 3072, 4096 bits). Khuyến nghị: ECDSA_P256_SHA256 — cân bằng giữa security và performance.


Policy Evaluation Algorithm

Tại Admission Time

Khi một Pod được submitted đến GKE:

  1. Kubernetes API Server nhận request → chuyển đến admission controllers

  2. Binary Authorization admission webhook (ValidatingAdmissionWebhook) nhận request

  3. Image lookup: Với mỗi container trong Pod spec, webhook xác định image reference (bao gồm digest)

  4. Rule matching: Webhook gọi Binary Authorization API với cluster identity và image digests. API tìm rule phù hợp theo thứ tự:

    • clusterAdmissionRule cho cluster này không? → Dùng rule đó
    • Không có? → Dùng defaultAdmissionRule
  5. Evaluation mode processing:

    • ALWAYS_ALLOW: Trả về "allow"
    • ALWAYS_DENY: Trả về "deny" (trừ khi image trong allowlist)
    • REQUIRE_ATTESTATION: Tiếp tục sang bước 6
  6. Attestation lookup: Với mỗi attestor trong danh sách, Binary Authorization query Artifact Analysis để tìm occurrences của note tương ứng có image digest khớp

  7. Signature verification: Với mỗi occurrence tìm được, verify signature sử dụng public keys của attestor

  8. Decision: Nếu tất cả attestors có ít nhất một occurrence với valid signature → "allow". Bất kỳ attestor nào fail → "deny" (nếu ENFORCED_BLOCK_AND_AUDIT_LOG) hoặc log và "allow" (nếu DRYRUN_AUDIT_LOG_ONLY)

  9. Allowlist check (song song): Image có khớp admissionWhitelistPatterns không? Nếu có → tự động allow, bỏ qua bước 4-8

Policy Scoping: Multi-Project Setup

Trong production, best practice là tách biệt:

┌─────────────────────┐
│  Deployment Project │  ← GKE cluster chạy ở đây
│  (policy lưu ở đây) │  ← policy tham chiếu attestors từ project khác
└──────────┬──────────┘
           │ requireAttestationsBy

┌─────────────────────┐
│   Attestor Project  │  ← Attestors và public keys sống ở đây
│                     │  ← Security team quản lý project này
└──────────┬──────────┘
           │ Artifact Analysis note

┌─────────────────────┐
│ Attestation Project │  ← Attestation occurrences lưu ở đây
│                     │  ← CI/CD service account viết vào đây
└─────────────────────┘

Tại sao cần tách biệt? Separation of duties: developer team không thể tự ký attestation cho image của mình nếu họ không có quyền tạo occurrences trong attestation project. Security team kiểm soát attestor project và không bị ảnh hưởng bởi thay đổi ở deployment project.

Theo multi-project setup documentation, IAM roles phải được cấu hình cross-project:

  • Binary Authorization service account trong deployment project cần roles/containeranalysis.notes.viewer trong attestor project
  • Signer cần roles/containeranalysis.occurrences.viewer + roles/binaryauthorization.attestorsViewer trong attestor project

Constraints, Trade-offs và Failure Modes

Hạn chế của Policy Model

One policy per project: Không thể có policy khác nhau cho các namespaces trong cùng một GKE cluster qua policy singleton. Nếu cần per-namespace policy, phải dùng clusterAdmissionRules per cluster, hoặc dùng Continuous Validation platform policies (linh hoạt hơn).

AND logic cho multiple attestors: Khi liệt kê nhiều attestors, image phải thỏa mãn tất cả. Không có OR logic trong enforcement policy. Nếu muốn OR (image có thể được ký bởi attestor A hoặc B), phải cấu hình một attestor với nhiều public keys — Binary Authorization sẽ accept nếu bất kỳ key nào verify được.

Eventual consistency của Artifact Analysis: Khi một attestation mới được tạo, có thể mất vài giây đến vài phút để propagate và visible với Binary Authorization API. Nếu CI/CD tạo attestation ngay trước khi trigger deployment, có thể xảy ra race condition — deployment fail vì attestation chưa kịp propagate. Pattern giải quyết: thêm sleep hoặc retry logic trong CI pipeline.

Policy update và running Pods: Khi bạn thay đổi policy (ví dụ thêm yêu cầu attestation mới), chỉ các deployment mới sau thời điểm đó bị ảnh hưởng. Pods đang chạy không bị evict. Đây là lý do cần Continuous Validation (Chương 34.04).

Failure Mode: Admission Webhook Failure

Binary Authorization hoạt động như một ValidatingAdmissionWebhook. Nếu webhook service không available:

  • GKE có built-in fallback mechanism: nếu Binary Authorization API unreachable, GKE có thể configured để fail open (allow) hoặc fail closed (deny).
  • Mặc định trong GKE: fail closed (deny) để maintain security posture khi service down.

Đây là design decision quan trọng: fail-safe mặc định là bảo vệ cluster, không phải maintain availability. Nếu Binary Authorization API có incident, deployments bị chặn cho đến khi service phục hồi (hoặc dùng break-glass — xem Chương 34.05).


GCP-native Implementation Guidance

Tạo Attestor

bash
# 1. Tạo Artifact Analysis note
cat > /tmp/note.json << EOF
{
  "attestation": {
    "hint": {
      "humanReadableName": "QA Approval Attestor"
    }
  }
}
EOF

PROJECT_ID=$(gcloud config get-value project)
NOTE_ID="qa-approval-note"

curl -X POST \
  "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes?noteId=${NOTE_ID}" \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  -d @/tmp/note.json

# 2. Tạo attestor tham chiếu note
ATTESTOR_ID="qa-approval"
NOTE_URI="projects/${PROJECT_ID}/notes/${NOTE_ID}"

gcloud container binauthz attestors create ${ATTESTOR_ID} \
  --attestation-authority-note=${NOTE_URI} \
  --attestation-authority-note-project=${PROJECT_ID}

# 3. Thêm public key vào attestor (dùng Cloud KMS key)
KMS_KEY="projects/${PROJECT_ID}/locations/us-central1/keyRings/binauthz-keyring/cryptoKeys/signing-key/cryptoKeyVersions/1"

gcloud container binauthz attestors public-keys add \
  --attestor=${ATTESTOR_ID} \
  --keyversion=${KMS_KEY}

Cấu Hình Policy

bash
# Export policy hiện tại
gcloud container binauthz policy export > /tmp/policy.yaml

# Sửa policy.yaml để thêm rule
# (thêm defaultAdmissionRule với REQUIRE_ATTESTATION)

# Import policy đã sửa
gcloud container binauthz policy import /tmp/policy.yaml

Verify Policy

bash
# Xem policy hiện tại
gcloud container binauthz policy describe

# Check attestor
gcloud container binauthz attestors describe qa-approval

# List public keys của attestor
gcloud container binauthz attestors public-keys list \
  --attestor=qa-approval

Tài liệu tham khảo