Skip to main content

Overview

Implement defense-in-depth security for MCP Server on GKE with 67 security controls achieving CIS GKE Benchmark compliance and SOC 2 readiness.

Security Controls

67 controls across 7 layers

Compliance

CIS, SOC 2, HIPAA-ready

Zero Trust

Network policies, mTLS, Workload Identity

Automated Scanning

Daily compliance checks

7-Layer Security Architecture

1

Layer 1: Infrastructure

  • VPC isolation
  • IAM boundaries
  • GKE Security Posture Dashboard
  • Audit logging
2

Layer 2: Compute (Shielded Nodes)

  • Secure Boot (verify boot integrity)
  • vTPM (hardware-based key storage)
  • Integrity monitoring (detect tampering)
Automatic in GKE Autopilot
3

Layer 3: Network

  • Private nodes (no public IPs)
  • VPC-native networking
  • Network policies (zero-trust)
  • Cloud Armor (DDoS protection)
4

Layer 4: Data

  • Encryption at rest (Google-managed or CMEK)
  • Encryption in transit (TLS required)
  • Secret Manager (no secrets in Git)
5

Layer 5: Identity

  • Workload Identity (no SA keys)
  • IAM least privilege
  • Master authorized networks
6

Layer 6: Application

  • Binary Authorization (image signing)
  • Container vulnerability scanning
  • Pod Security Standards (restricted)
7

Layer 7: Compliance

  • Audit logging
  • Policy enforcement (OPA/Gatekeeper)
  • Automated compliance scanning

Quick Security Setup

1. Enable Binary Authorization

1

Run Setup Script

./deployments/security/binary-authorization/setup-binary-auth.sh PROJECT_ID production
2

Sign Images

./deployments/security/binary-authorization/sign-image.sh \
  PROJECT_ID production IMAGE_URL
3

Enable in Cluster

# terraform.tfvars
enable_binary_authorization = true
terraform apply

2. Configure Private Cluster

  • Private Nodes Only
  • Fully Private
enable_private_nodes = true     # ✅ Already configured
enable_private_endpoint = false # Public control plane access
Use case: Production with external access needed

3. Restrict Control Plane Access

enable_master_authorized_networks = true
master_authorized_networks_cidrs = [
  {
    cidr_block   = "10.0.0.0/8"
    display_name = "Internal VPC"
  },
  {
    cidr_block   = "203.0.113.0/24"
    display_name = "Office Network"
  }
]

4. Enable Security Posture Dashboard

enable_security_posture             = true
security_posture_mode               = "ENTERPRISE"
security_posture_vulnerability_mode = "VULNERABILITY_ENTERPRISE"
View Dashboard:
## Console: Kubernetes → Security
## https://console.cloud.google.com/kubernetes/security?project=PROJECT_ID

Security Checklist

Infrastructure ✅

  • GKE Security Posture enabled
  • Audit logging enabled
  • Shielded nodes (automatic in Autopilot)
  • Workload Identity enabled
  • VPC Service Controls (optional, high-security)

Network ✅

  • Private nodes (no public IPs)
  • VPC-native networking
  • Network policies enforced
  • Cloud NAT for egress
  • Private endpoint (optional)
  • Cloud Armor (enable via variable)

Application ✅

  • Binary Authorization ready
  • Container scanning (Trivy in CI/CD)
  • Pod security standards (restricted)
  • Non-root containers
  • Read-only root filesystem
  • Capabilities dropped (ALL)

Data ✅

  • Encryption at rest (Google-managed)
  • CMEK (optional, compliance)
  • Encryption in transit (TLS)
  • Secrets in Secret Manager
  • No secrets in Git/ConfigMaps
  • No service account keys

Identity ✅

  • Workload Identity (no SA keys)
  • IAM least privilege
  • Per-workload service accounts
  • RBAC policies
  • SA key creation disabled (org policy)

Security Testing

Automated Scans

Run daily compliance scans:
## Trigger manually
gh workflow run gcp-compliance-scan.yaml

## View results
gh run list --workflow=gcp-compliance-scan.yaml
Scans include:
  • Terraform security (Trivy, tfsec, Checkov)
  • Kubernetes manifests (Trivy, kube-score)
  • CIS GKE Benchmark (kube-bench)
  • Secret scanning (Gitleaks, TruffleHog)

Manual Security Review

kubectl get pods -A -o json \
  | jq '[.items[] | select(.spec.containers[].securityContext.privileged==true)] | length'
Should return: 0
kubectl get networkpolicies -n production-mcp-server-langgraph
At least 2 policies should exist
kubectl get sa -A -o json \
  | jq '.items[] | select(.metadata.annotations["iam.gke.io/gcp-service-account"]) | {namespace: .metadata.namespace, name: .metadata.name, gcp_sa: .metadata.annotations["iam.gke.io/gcp-service-account"]}'
gcloud projects get-iam-policy PROJECT_ID \
  --flatten="bindings[].members" \
  --filter="bindings.members:serviceAccount"

Compliance Frameworks

CIS GKE Benchmark

GKE Autopilot is pre-configured to meet CIS Benchmark requirements.
Key controls (auto-compliant):
  • ✅ 4.1.1 Workload Identity enabled
  • ✅ 4.2.1 Network Policy enabled
  • ✅ 4.3.1 Private cluster enabled
  • ✅ 4.5.1 Audit Logging enabled
Validate with kube-bench:
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job-gke.yaml
kubectl logs job/kube-bench

SOC 2 Type II

Required controls (all implemented):
  • ✅ Access control (Workload Identity + RBAC)
  • ✅ Encryption (at rest + in transit)
  • ✅ Audit logging (all access logged)
  • ✅ Change management (Terraform + GitOps)
  • ✅ Monitoring & alerting (Cloud Operations)
  • ✅ Incident response (runbooks documented)

HIPAA Compliance

Requirements:
  • ✅ Encryption at rest (enable CMEK recommended)
  • ✅ Encryption in transit (TLS required)
  • ✅ Audit logs (configure 6+ year retention)
  • ✅ Access controls (IAM + RBAC)
  • ✅ Business Associate Agreement (sign with Google)
Additional steps:
## Enable CMEK
kms_key_name = "projects/PROJECT/locations/REGION/keyRings/RING/cryptoKeys/KEY"

## Extended audit log retention
## Configure via Cloud Console: Logging → Log Router → Sinks

Security Monitoring

Critical Metrics

  • Unauthorized Access
  • Binary Auth Denials
  • Privileged Pods
  • Network Policy Violations
gcloud logging read \
  'protoPayload.status.code!=0 AND protoPayload.authenticationInfo.principalEmail!=""' \
  --limit=50

Incident Response

Security Incident Runbook

1

Detection

  • Security alert fires
  • Unusual activity in audit logs
  • Binary Authorization denial surge
2

Containment

# Isolate affected pods
kubectl label pod SUSPICIOUS_POD quarantine=true -n production-mcp-server-langgraph

# Network policy to isolate
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: isolate-suspicious-pod
  namespace: production-mcp-server-langgraph
spec:
  podSelector:
    matchLabels:
      quarantine: "true"
  policyTypes:
  - Ingress
  - Egress
EOF
3

Investigation

# Export logs
kubectl logs POD_NAME -n production-mcp-server-langgraph --all-containers > incident-logs.txt

# Audit trail
gcloud logging read \
  'resource.type="k8s_cluster" AND protoPayload.resourceName=~"pods/SUSPICIOUS_POD"' \
  --format=json > audit-trail.json
4

Remediation

  • Delete compromised pods
  • Rotate all secrets
  • Review and tighten IAM policies
  • Deploy patched version