| name | implementing-gcp-binary-authorization |
| description | 实施 GCP Binary Authorization,强制执行部署时安全控制,确保只有受信任且经过认证的容器镜像才能部署到 Google Kubernetes Engine 和 Cloud Run。 |
| domain | cybersecurity |
| subdomain | cloud-security |
| tags | ["gcp","binary-authorization","container-security","supply-chain","gke","cloud-run","attestation","software-integrity"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
实施 GCP Binary Authorization
概述
Binary Authorization(二进制授权)是 Google Cloud 的部署时安全控制,确保只有受信任的容器镜像才能部署到 GKE 或 Cloud Run。它采用基于策略的模型,镜像必须持有加密认证,证明已通过预定义要求,如漏洞扫描、代码审查或构建流水线验证。持续验证(CV)会监控正在运行的 Pod 是否符合策略,并记录违规情况。
前置条件
- 已启用 Binary Authorization API 的 GCP 项目
- GKE 集群或 Cloud Run 服务
- 已启用 Container Analysis API
- 用于认证签名的 KMS 密钥
- Cloud Build 或外部 CI/CD 流水线
启用 Binary Authorization
gcloud services enable binaryauthorization.googleapis.com
gcloud services enable containeranalysis.googleapis.com
gcloud services enable container.googleapis.com
gcloud container clusters update CLUSTER_NAME \
--enable-binauthz \
--zone us-central1-a
创建认证者(Attestor)
创建用于签名的 KMS 密钥
gcloud kms keyrings create binauthz-keyring \
--location global
gcloud kms keys create attestor-key \
--keyring binauthz-keyring \
--location global \
--algorithm ec-sign-p256-sha256 \
--purpose asymmetric-signing
创建 Container Analysis 备注
cat > /tmp/note.json << 'EOF'
{
"attestation": {
"hint": {
"humanReadableName": "Production Build Attestor"
}
}
}
EOF
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/PROJECT_ID/notes/?noteId=prod-build-note" \
-d @/tmp/note.json
创建认证者
gcloud container binauthz attestors create prod-build-attestor \
--attestation-authority-note=prod-build-note \
--attestation-authority-note-project=PROJECT_ID
gcloud container binauthz attestors public-keys add \
--attestor=prod-build-attestor \
--keyversion-project=PROJECT_ID \
--keyversion-location=global \
--keyversion-keyring=binauthz-keyring \
--keyversion-key=attestor-key \
--keyversion=1
配置策略
默认拒绝所有策略
admissionWhitelistPatterns:
- namePattern: "gcr.io/google_containers/*"
- namePattern: "gcr.io/google-containers/*"
- namePattern: "k8s.gcr.io/**"
- namePattern: "gke.gcr.io/**"
- namePattern: "gcr.io/stackdriver-agents/*"
defaultAdmissionRule:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/PROJECT_ID/attestors/prod-build-attestor
globalPolicyEvaluationMode: ENABLE
gcloud container binauthz policy import binauthz-policy.yaml
按集群配置规则
admissionWhitelistPatterns:
- namePattern: "gcr.io/google_containers/*"
clusterAdmissionRules:
us-central1-a.production-cluster:
evaluationMode: REQUIRE_ATTESTATION
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
requireAttestationsBy:
- projects/PROJECT_ID/attestors/prod-build-attestor
us-central1-a.staging-cluster:
evaluationMode: ALWAYS_ALLOW
enforcementMode: DRYRUN_AUDIT_LOG_ONLY
defaultAdmissionRule:
evaluationMode: ALWAYS_DENY
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
创建认证
构建成功后对镜像进行认证
IMAGE_DIGEST=$(gcloud container images describe \
gcr.io/PROJECT_ID/my-app:latest \
--format='get(image_summary.digest)')
gcloud container binauthz attestations sign-and-create \
--artifact-url="gcr.io/PROJECT_ID/my-app@${IMAGE_DIGEST}" \
--attestor="prod-build-attestor" \
--attestor-project="PROJECT_ID" \
--keyversion-project="PROJECT_ID" \
--keyversion-location="global" \
--keyversion-keyring="binauthz-keyring" \
--keyversion-key="attestor-key" \
--keyversion="1"
Cloud Build 集成
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-app:$SHORT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/my-app:$SHORT_SHA']
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
gcloud artifacts docker images scan \
gcr.io/$PROJECT_ID/my-app:$SHORT_SHA \
--format='value(response.scan)'
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
IMAGE_DIGEST=$(gcloud container images describe \
gcr.io/$PROJECT_ID/my-app:$SHORT_SHA \
--format='get(image_summary.digest)')
gcloud container binauthz attestations sign-and-create \
--artifact-url="gcr.io/$PROJECT_ID/my-app@$${IMAGE_DIGEST}" \
--attestor="prod-build-attestor" \
--attestor-project="$PROJECT_ID" \
--keyversion-project="$PROJECT_ID" \
--keyversion-location="global" \
--keyversion-keyring="binauthz-keyring" \
--keyversion-key="attestor-key" \
--keyversion="1"
持续验证
gcloud container clusters update CLUSTER_NAME \
--enable-binauthz-monitoring \
--zone us-central1-a
在 Cloud Logging 中监控持续验证违规
resource.type="k8s_cluster"
logName="projects/PROJECT_ID/logs/binaryauthorization.googleapis.com%2Fcontinuous_validation"
验证与测试
测试未经认证镜像的部署
kubectl run test-unapproved \
--image=docker.io/library/nginx:latest
kubectl get events --field-selector reason=FailedCreate
验证认证是否存在
gcloud container binauthz attestations list \
--attestor=prod-build-attestor \
--attestor-project=PROJECT_ID
紧急覆盖(Break-Glass)
用于紧急部署时绕过 Binary Authorization:
apiVersion: v1
kind: Pod
metadata:
name: emergency-pod
labels:
image-policy.k8s.io/break-glass: "true"
annotations:
alpha.image-policy.k8s.io/break-glass: "Emergency deployment - ticket INC-12345"
spec:
containers:
- name: emergency
image: gcr.io/PROJECT_ID/emergency-fix:latest
参考资料