GCP for DevOps — Security Automation

2 minute read

Security Automation

Security Automation integrates security checks into the DevOps pipeline (DevSecOps). This includes container vulnerability scanning, automated compliance checks, security policy enforcement, and incident response automation.

DevSecOps Pipeline

DevSecOps Pipeline:
┌──────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────┐
│ Code  │─▶│ Build     │─▶│ Security  │─▶│ Deploy    │─▶│ Run   │
│       │  │           │  │ Scan      │  │           │  │       │
│ Lint  │  │ Container │  │ Vuln scan │  │ Binary    │  │ SCC   │
│ SAST  │  │ Build     │  │ DAST      │  │ Authz     │  │ WAF   │
│ Secret│  │ Test      │  │ License   │  │ Policy    │  │ IDS   │
│ scan  │  │           │  │ check     │  │ check     │  │       │
└──────┘  └──────────┘  └──────────┘  └──────────┘  └──────┘

Container Vulnerability Scanning

Artifact Registry automatically scans pushed images:

# Enable vulnerability scanning
$ gcloud services enable containerscanning.googleapis.com

# Push an image (scan runs automatically)
$ docker push us-central1-docker.pkg.dev/my-project/my-repo/my-app:v1

# List vulnerabilities for an image
$ gcloud artifacts docker images list \
    us-central1-docker.pkg.dev/my-project/my-repo \
    --show-occurrences \
    --occurrence-filter='kind="VULNERABILITY"'

# Get detailed vulnerability report
$ gcloud artifacts vulnerabilities list \
    us-central1-docker.pkg.dev/my-project/my-repo/my-app:v1

Cloud Build Security Scanning

# cloudbuild.yaml with security steps
steps:
  # Build
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:$COMMIT_SHA', '.']

  # Push (triggers vulnerability scan)
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:$COMMIT_SHA']

  # Wait for scan and check results
  - name: 'gcr.io/cloud-builders/gcloud'
    entrypoint: 'bash'
    args:
      - '-c'
      - |
        echo "Waiting for vulnerability scan..."
        sleep 30
        VULNS=$(gcloud artifacts vulnerabilities list \
          us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:$COMMIT_SHA \
          --format="value(vulnerability.effectiveSeverity)" 2>/dev/null | grep -c "CRITICAL" || true)
        if [ "$VULNS" -gt "0" ]; then
          echo "CRITICAL vulnerabilities found! Blocking deployment."
          exit 1
        fi
        echo "No critical vulnerabilities. Proceeding."

  # Create attestation (if scan passes)
  - name: 'gcr.io/cloud-builders/gcloud'
    args:
      - 'container'
      - 'binauthz'
      - 'attestations'
      - 'sign-and-create'
      - '--artifact-url=us-central1-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:$COMMIT_SHA'
      - '--attestor=build-attestor'
      - '--attestor-project=$PROJECT_ID'

Secret Scanning in CI/CD

# Scan for secrets in source code (Cloud Build)
steps:
  - name: 'gcr.io/cloud-builders/git'
    entrypoint: 'bash'
    args:
      - '-c'
      - |
        # Install truffleHog for secret scanning
        pip install truffleHog
        trufflehog --regex --entropy=False .
        if [ $? -ne 0 ]; then
          echo "Secrets detected in source code!"
          exit 1
        fi

Automated SCC Remediation

Use Cloud Functions to automatically fix SCC findings:

# Auto-remediate public bucket findings
import functions_framework
from google.cloud import storage

@functions_framework.cloud_event
def remediate_public_bucket(cloud_event):
    finding = cloud_event.data.get("finding", {})

    if finding.get("category") != "PUBLIC_BUCKET_ACL":
        return

    bucket_name = finding.get("resourceName", "").split("/")[-1]

    client = storage.Client()
    bucket = client.get_bucket(bucket_name)

    # Remove public access
    bucket.iam_configuration.uniform_bucket_level_access_enabled = True
    bucket.patch()

    # Remove allUsers and allAuthenticatedUsers
    policy = bucket.get_iam_policy(requested_policy_version=3)
    for binding in policy.bindings[:]:
        binding["members"] = [
            m for m in binding["members"]
            if m not in ("allUsers", "allAuthenticatedUsers")
        ]
    bucket.set_iam_policy(policy)

    print(f"Remediated public access on bucket: {bucket_name}")

Organization Policy Automation

# Enforce no external IPs on all VMs
$ cat > disable-external-ip.yaml << 'EOF'
name: organizations/123456789/policies/compute.vmExternalIpAccess
spec:
  rules:
    - enforce: true
EOF

$ gcloud org-policies set-policy disable-external-ip.yaml

# Prevent service account key creation
$ cat > no-sa-keys.yaml << 'EOF'
name: organizations/123456789/policies/iam.disableServiceAccountKeyCreation
spec:
  rules:
    - enforce: true
EOF

$ gcloud org-policies set-policy no-sa-keys.yaml

Common Mistakes

Mistake Why It’s Wrong Fix
No vulnerability scanning Deploying images with CVEs Enable container scanning
Scan but don’t block Vulnerabilities still deployed Fail pipeline on CRITICAL
No secret scanning Keys in source code Add pre-commit and CI scanning
Manual remediation only Slow response to findings Automate common remediations
Security as last step Late discovery, costly fixes Shift security left in pipeline

Quick Reference

Tool Purpose
Container Analysis Image vulnerability scanning
Binary Authorization Deploy-time verification
Cloud Build security steps CI/CD security gates
SCC + Cloud Functions Automated remediation
Organization Policies Guardrails at org level

Next → Practice Exercises

Updated: