mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-15 07:24:56 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
---
|
||||
name: implementing-gcp-binary-authorization
|
||||
description: Implement GCP Binary Authorization to enforce deploy-time security controls that ensure only trusted, attested container images are deployed to Google Kubernetes Engine and 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: MIT
|
||||
---
|
||||
|
||||
# Implementing GCP Binary Authorization
|
||||
|
||||
## Overview
|
||||
|
||||
Binary Authorization is a Google Cloud deploy-time security control that ensures only trusted container images are deployed on GKE or Cloud Run. It works through a policy-based model where images must have cryptographic attestations confirming they passed predefined requirements such as vulnerability scans, code reviews, or build pipeline verification. Continuous validation (CV) monitors running pods against policies and logs violations.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- GCP project with Binary Authorization API enabled
|
||||
- GKE cluster or Cloud Run service
|
||||
- Container Analysis API enabled
|
||||
- KMS keys for attestation signing
|
||||
- Cloud Build or external CI/CD pipeline
|
||||
|
||||
## Enable Binary Authorization
|
||||
|
||||
```bash
|
||||
# Enable required APIs
|
||||
gcloud services enable binaryauthorization.googleapis.com
|
||||
gcloud services enable containeranalysis.googleapis.com
|
||||
gcloud services enable container.googleapis.com
|
||||
|
||||
# Enable Binary Authorization on GKE cluster
|
||||
gcloud container clusters update CLUSTER_NAME \
|
||||
--enable-binauthz \
|
||||
--zone us-central1-a
|
||||
```
|
||||
|
||||
## Create Attestor
|
||||
|
||||
### Create a KMS key for signing
|
||||
|
||||
```bash
|
||||
# Create keyring
|
||||
gcloud kms keyrings create binauthz-keyring \
|
||||
--location global
|
||||
|
||||
# Create signing key
|
||||
gcloud kms keys create attestor-key \
|
||||
--keyring binauthz-keyring \
|
||||
--location global \
|
||||
--algorithm ec-sign-p256-sha256 \
|
||||
--purpose asymmetric-signing
|
||||
```
|
||||
|
||||
### Create Container Analysis note
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
### Create the attestor
|
||||
|
||||
```bash
|
||||
gcloud container binauthz attestors create prod-build-attestor \
|
||||
--attestation-authority-note=prod-build-note \
|
||||
--attestation-authority-note-project=PROJECT_ID
|
||||
|
||||
# Add KMS key to attestor
|
||||
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
|
||||
```
|
||||
|
||||
## Configure Policy
|
||||
|
||||
### Default deny-all policy
|
||||
|
||||
```yaml
|
||||
# binauthz-policy.yaml
|
||||
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
|
||||
```
|
||||
|
||||
```bash
|
||||
gcloud container binauthz policy import binauthz-policy.yaml
|
||||
```
|
||||
|
||||
### Per-cluster rules
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## Create Attestations
|
||||
|
||||
### Attest an image after successful build
|
||||
|
||||
```bash
|
||||
# Get image digest
|
||||
IMAGE_DIGEST=$(gcloud container images describe \
|
||||
gcr.io/PROJECT_ID/my-app:latest \
|
||||
--format='get(image_summary.digest)')
|
||||
|
||||
# Create attestation
|
||||
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 integration
|
||||
|
||||
```yaml
|
||||
# cloudbuild.yaml
|
||||
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']
|
||||
|
||||
# Vulnerability scanning
|
||||
- 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)'
|
||||
|
||||
# Create attestation after successful 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"
|
||||
```
|
||||
|
||||
## Continuous Validation
|
||||
|
||||
```bash
|
||||
# Enable CV on a GKE cluster
|
||||
gcloud container clusters update CLUSTER_NAME \
|
||||
--enable-binauthz-monitoring \
|
||||
--zone us-central1-a
|
||||
```
|
||||
|
||||
### Monitor CV violations in Cloud Logging
|
||||
|
||||
```
|
||||
resource.type="k8s_cluster"
|
||||
logName="projects/PROJECT_ID/logs/binaryauthorization.googleapis.com%2Fcontinuous_validation"
|
||||
```
|
||||
|
||||
## Verification and Testing
|
||||
|
||||
### Test deployment of unattested image
|
||||
|
||||
```bash
|
||||
# This should be blocked
|
||||
kubectl run test-unapproved \
|
||||
--image=docker.io/library/nginx:latest
|
||||
|
||||
# Verify the pod was denied
|
||||
kubectl get events --field-selector reason=FailedCreate
|
||||
```
|
||||
|
||||
### Verify attestation exists
|
||||
|
||||
```bash
|
||||
gcloud container binauthz attestations list \
|
||||
--attestor=prod-build-attestor \
|
||||
--attestor-project=PROJECT_ID
|
||||
```
|
||||
|
||||
## Break-Glass Override
|
||||
|
||||
For emergency deployments bypassing Binary Authorization:
|
||||
|
||||
```yaml
|
||||
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
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- GCP Binary Authorization: https://cloud.google.com/binary-authorization/docs
|
||||
- SLSA Framework: https://slsa.dev
|
||||
- Sigstore/Cosign for container signing
|
||||
- Google Software Supply Chain Security Best Practices
|
||||
@@ -0,0 +1,25 @@
|
||||
# GCP Binary Authorization Implementation Template
|
||||
|
||||
## Configuration
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| Project ID | |
|
||||
| GKE Cluster | |
|
||||
| Attestor Name | |
|
||||
| KMS Key Location | |
|
||||
| Policy Mode | Enforce / Dry-Run |
|
||||
|
||||
## Attestor Checklist
|
||||
- [ ] KMS keyring and key created
|
||||
- [ ] Container Analysis note created
|
||||
- [ ] Attestor created and linked to note
|
||||
- [ ] Public key added to attestor
|
||||
- [ ] CI/CD pipeline creates attestations
|
||||
- [ ] Break-glass procedure documented
|
||||
|
||||
## Policy Configuration
|
||||
| Rule | Scope | Mode | Attestors Required |
|
||||
|------|-------|------|--------------------|
|
||||
| Default | All clusters | | |
|
||||
| Production | prod-cluster | | |
|
||||
| Staging | staging-cluster | | |
|
||||
@@ -0,0 +1,15 @@
|
||||
# Standards - GCP Binary Authorization
|
||||
|
||||
## SLSA Framework Levels
|
||||
- SLSA 1: Documentation of build process
|
||||
- SLSA 2: Tamper resistance of build service
|
||||
- SLSA 3: Extra resistance to threats
|
||||
- SLSA 4: Highest levels of confidence and trust
|
||||
|
||||
## NIST 800-53
|
||||
- SA-10: Developer Configuration Management
|
||||
- SA-12: Supply Chain Protection
|
||||
- SI-7: Software, Firmware, and Information Integrity
|
||||
|
||||
## CIS GKE Benchmark
|
||||
- 6.10.4: Ensure Binary Authorization is enabled for GKE clusters
|
||||
@@ -0,0 +1,22 @@
|
||||
# Workflows - GCP Binary Authorization
|
||||
|
||||
## Attestation Pipeline
|
||||
```
|
||||
1. Developer pushes code
|
||||
2. Cloud Build triggers container build
|
||||
3. Vulnerability scan runs on built image
|
||||
4. If scan passes → Create cryptographic attestation
|
||||
5. Push attested image to registry
|
||||
6. GKE validates attestation at deploy time
|
||||
7. Continuous validation monitors running pods
|
||||
```
|
||||
|
||||
## Break-Glass Procedure
|
||||
```
|
||||
1. Emergency identified → Create incident ticket
|
||||
2. Apply break-glass annotation to pod spec
|
||||
3. Deploy with override documented
|
||||
4. Alert security team of break-glass usage
|
||||
5. Post-incident: Review and attest emergency image
|
||||
6. Remove break-glass annotation
|
||||
```
|
||||
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GCP Binary Authorization Management Script
|
||||
|
||||
Automates attestor management, policy configuration, and attestation
|
||||
creation for container image supply chain security.
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def run_gcloud(args):
|
||||
"""Execute gcloud command and return parsed output."""
|
||||
cmd = ["gcloud"] + args + ["--format=json"]
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
return None, result.stderr
|
||||
try:
|
||||
return json.loads(result.stdout) if result.stdout.strip() else {}, None
|
||||
except json.JSONDecodeError:
|
||||
return result.stdout, None
|
||||
|
||||
|
||||
def check_binauthz_status(project_id):
|
||||
"""Check Binary Authorization configuration status."""
|
||||
print(f"[*] Checking Binary Authorization status for project: {project_id}")
|
||||
|
||||
policy, err = run_gcloud([
|
||||
"container", "binauthz", "policy", "export",
|
||||
f"--project={project_id}"
|
||||
])
|
||||
|
||||
if err:
|
||||
print(f"[!] Error fetching policy: {err}")
|
||||
return None
|
||||
|
||||
print(f"[+] Current policy retrieved")
|
||||
return policy
|
||||
|
||||
|
||||
def list_attestors(project_id):
|
||||
"""List all configured attestors."""
|
||||
attestors, err = run_gcloud([
|
||||
"container", "binauthz", "attestors", "list",
|
||||
f"--project={project_id}"
|
||||
])
|
||||
|
||||
if err:
|
||||
print(f"[!] Error listing attestors: {err}")
|
||||
return []
|
||||
|
||||
if isinstance(attestors, list):
|
||||
print(f"[+] Found {len(attestors)} attestors:")
|
||||
for a in attestors:
|
||||
print(f" - {a.get('name', 'unknown')}")
|
||||
return attestors or []
|
||||
|
||||
|
||||
def verify_attestation(project_id, image_url, attestor):
|
||||
"""Verify that an image has a valid attestation."""
|
||||
print(f"[*] Verifying attestation for: {image_url}")
|
||||
|
||||
attestations, err = run_gcloud([
|
||||
"container", "binauthz", "attestations", "list",
|
||||
f"--attestor={attestor}",
|
||||
f"--attestor-project={project_id}",
|
||||
f"--artifact-url={image_url}"
|
||||
])
|
||||
|
||||
if err:
|
||||
print(f"[!] Error: {err}")
|
||||
return False
|
||||
|
||||
if isinstance(attestations, list) and len(attestations) > 0:
|
||||
print(f"[+] Image has {len(attestations)} attestation(s)")
|
||||
return True
|
||||
else:
|
||||
print(f"[!] No attestations found for image")
|
||||
return False
|
||||
|
||||
|
||||
def create_attestation(project_id, image_url, attestor, key_info):
|
||||
"""Create an attestation for a container image."""
|
||||
print(f"[*] Creating attestation for: {image_url}")
|
||||
|
||||
_, err = run_gcloud([
|
||||
"container", "binauthz", "attestations", "sign-and-create",
|
||||
f"--artifact-url={image_url}",
|
||||
f"--attestor={attestor}",
|
||||
f"--attestor-project={project_id}",
|
||||
f"--keyversion-project={key_info['project']}",
|
||||
f"--keyversion-location={key_info['location']}",
|
||||
f"--keyversion-keyring={key_info['keyring']}",
|
||||
f"--keyversion-key={key_info['key']}",
|
||||
f"--keyversion={key_info['version']}"
|
||||
])
|
||||
|
||||
if err:
|
||||
print(f"[!] Error creating attestation: {err}")
|
||||
return False
|
||||
|
||||
print(f"[+] Attestation created successfully")
|
||||
return True
|
||||
|
||||
|
||||
def audit_policy_compliance(project_id):
|
||||
"""Audit Binary Authorization policy for security compliance."""
|
||||
policy, err = run_gcloud([
|
||||
"container", "binauthz", "policy", "export",
|
||||
f"--project={project_id}"
|
||||
])
|
||||
|
||||
if not policy:
|
||||
print("[!] Could not retrieve policy")
|
||||
return
|
||||
|
||||
findings = []
|
||||
|
||||
if isinstance(policy, str):
|
||||
import yaml
|
||||
policy = yaml.safe_load(policy)
|
||||
|
||||
default_rule = policy.get("defaultAdmissionRule", {})
|
||||
if default_rule.get("evaluationMode") == "ALWAYS_ALLOW":
|
||||
findings.append({
|
||||
"severity": "HIGH",
|
||||
"finding": "Default admission rule allows all images",
|
||||
"recommendation": "Set to REQUIRE_ATTESTATION or ALWAYS_DENY"
|
||||
})
|
||||
|
||||
if default_rule.get("enforcementMode") == "DRYRUN_AUDIT_LOG_ONLY":
|
||||
findings.append({
|
||||
"severity": "MEDIUM",
|
||||
"finding": "Default rule is in dry-run mode (not enforcing)",
|
||||
"recommendation": "Switch to ENFORCED_BLOCK_AND_AUDIT_LOG"
|
||||
})
|
||||
|
||||
if not policy.get("globalPolicyEvaluationMode") == "ENABLE":
|
||||
findings.append({
|
||||
"severity": "LOW",
|
||||
"finding": "Global policy evaluation not explicitly enabled",
|
||||
"recommendation": "Enable globalPolicyEvaluationMode"
|
||||
})
|
||||
|
||||
whitelist = policy.get("admissionWhitelistPatterns", [])
|
||||
for pattern in whitelist:
|
||||
name = pattern.get("namePattern", "")
|
||||
if name == "*" or name == "**":
|
||||
findings.append({
|
||||
"severity": "CRITICAL",
|
||||
"finding": f"Wildcard whitelist pattern: {name}",
|
||||
"recommendation": "Remove overly broad whitelist patterns"
|
||||
})
|
||||
|
||||
print(f"\n[*] Policy Compliance Audit Results:")
|
||||
if findings:
|
||||
for f in findings:
|
||||
print(f" [{f['severity']}] {f['finding']}")
|
||||
print(f" Recommendation: {f['recommendation']}")
|
||||
else:
|
||||
print(" [OK] No issues found")
|
||||
|
||||
return findings
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="GCP Binary Authorization Management")
|
||||
parser.add_argument("--project", required=True, help="GCP Project ID")
|
||||
parser.add_argument("--status", action="store_true", help="Check policy status")
|
||||
parser.add_argument("--list-attestors", action="store_true", help="List attestors")
|
||||
parser.add_argument("--verify", type=str, help="Verify attestation for image URL")
|
||||
parser.add_argument("--attestor", type=str, help="Attestor name")
|
||||
parser.add_argument("--audit", action="store_true", help="Audit policy compliance")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.status:
|
||||
check_binauthz_status(args.project)
|
||||
if args.list_attestors:
|
||||
list_attestors(args.project)
|
||||
if args.verify and args.attestor:
|
||||
verify_attestation(args.project, args.verify, args.attestor)
|
||||
if args.audit:
|
||||
audit_policy_compliance(args.project)
|
||||
Reference in New Issue
Block a user