Section 07

Cloud-Native Security

Cloud-native architectures require security approaches designed for dynamic, distributed, and ephemeral infrastructure. Traditional security tools don't work in environments where resources are created and destroyed in seconds.

Container Security

Image Security

  • • Use minimal base images (distroless, Alpine)
  • • Scan images for vulnerabilities (Trivy, Snyk, Clair)
  • • Sign and verify images (Cosign, Notary)
  • • Use private registries with access controls
  • • Implement image admission policies

Runtime Security

  • • Run as non-root user
  • • Read-only root filesystem
  • • Drop all capabilities, add only needed
  • • Use seccomp and AppArmor profiles
  • • Runtime threat detection (Falco, Sysdig)

Kubernetes Security

  • • Enable RBAC with least privilege
  • • Use Pod Security Standards (restricted)
  • • Network Policies for pod isolation
  • • Secrets management (External Secrets, Vault)
  • • Audit logging enabled

Practical: Hardened Dockerfile

Dockerfile
dockerfile
# Stage 1: Build
FROM golang:1.22-alpine AS builder
RUN apk add --no-cache git ca-certificates
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/server .

# Stage 2: Production — distroless image (no shell, no package manager)
FROM gcr.io/distroless/static-debian12:nonroot

# Copy only the binary and CA certs
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# Run as non-root user (UID 65534)
USER nonroot:nonroot

# Health check via the binary itself (no curl available)
EXPOSE 8080

ENTRYPOINT ["/server"]

# What this achieves:
# ✓ Multi-stage build — no build tools in final image
# ✓ Distroless base — no shell, no package manager, ~2MB
# ✓ Non-root user — container cannot escalate to root
# ✓ Static binary — no libc dependency
# ✓ Stripped binary — smaller attack surface
# Stage 1: Build
FROM golang:1.22-alpine AS builder
RUN apk add --no-cache git ca-certificates
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/server .

# Stage 2: Production — distroless image (no shell, no package manager)
FROM gcr.io/distroless/static-debian12:nonroot

# Copy only the binary and CA certs
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# Run as non-root user (UID 65534)
USER nonroot:nonroot

# Health check via the binary itself (no curl available)
EXPOSE 8080

ENTRYPOINT ["/server"]

# What this achieves:
# ✓ Multi-stage build — no build tools in final image
# ✓ Distroless base — no shell, no package manager, ~2MB
# ✓ Non-root user — container cannot escalate to root
# ✓ Static binary — no libc dependency
# ✓ Stripped binary — smaller attack surface

Practical: Kubernetes Pod Security

pod-security-restricted.yaml
yaml
# Kubernetes Pod Security Standards — Restricted profile
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  namespace: production
spec:
  automountServiceAccountToken: false  # Don't mount SA token
  securityContext:
    runAsNonRoot: true
    runAsUser: 65534
    runAsGroup: 65534
    fsGroup: 65534
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: registry.example.com/app:v1.2.3@sha256:abc123...
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
        # No privileged, no hostNetwork, no hostPID, no hostIPC
      resources:
        limits:
          cpu: "500m"
          memory: "256Mi"
          ephemeral-storage: "100Mi"
        requests:
          cpu: "100m"
          memory: "128Mi"
      volumeMounts:
        - name: tmp
          mountPath: /tmp
  volumes:
    - name: tmp
      emptyDir:
        sizeLimit: "50Mi"
# Kubernetes Pod Security Standards — Restricted profile
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  namespace: production
spec:
  automountServiceAccountToken: false  # Don't mount SA token
  securityContext:
    runAsNonRoot: true
    runAsUser: 65534
    runAsGroup: 65534
    fsGroup: 65534
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: registry.example.com/app:v1.2.3@sha256:abc123...
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
        # No privileged, no hostNetwork, no hostPID, no hostIPC
      resources:
        limits:
          cpu: "500m"
          memory: "256Mi"
          ephemeral-storage: "100Mi"
        requests:
          cpu: "100m"
          memory: "128Mi"
      volumeMounts:
        - name: tmp
          mountPath: /tmp
  volumes:
    - name: tmp
      emptyDir:
        sizeLimit: "50Mi"

Practical: Istio mTLS & Authorization

istio-mtls-authz.yaml
yaml
# Enforce strict mTLS mesh-wide
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: strict-mtls
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
---
# Allow only frontend -> api-server communication
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: api-server-policy
  namespace: production
spec:
  selector:
    matchLabels:
      app: api-server
  action: ALLOW
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/frontend"]
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/v1/*"]
# Enforce strict mTLS mesh-wide
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: strict-mtls
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
---
# Allow only frontend -> api-server communication
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: api-server-policy
  namespace: production
spec:
  selector:
    matchLabels:
      app: api-server
  action: ALLOW
  rules:
    - from:
        - source:
            principals: ["cluster.local/ns/production/sa/frontend"]
      to:
        - operation:
            methods: ["GET", "POST"]
            paths: ["/api/v1/*"]

CNAPP Comparison

Platform Strengths Best For
Wiz Agentless scanning, attack path analysis, fast deployment Multi-cloud visibility
Prisma Cloud Full lifecycle (code→cloud), CSPM + CWPP + CIEM Comprehensive platform
Orca Security SideScanning, no agents, risk prioritization Low-effort coverage
Aqua Security Container-focused, runtime protection, vShield K8s-heavy environments
Prowler (OSS) Free, CIS benchmarks, AWS/Azure/GCP support Budget-conscious teams

Serverless Security

Security Benefits

  • ✓ No servers to patch
  • ✓ Ephemeral execution environments
  • ✓ Auto-scaling handles DDoS
  • ✓ Smaller attack surface per function

Security Challenges

  • ⚠ Function permissions often over-privileged
  • ⚠ Dependency vulnerabilities
  • ⚠ Event injection attacks
  • ⚠ Limited observability

Serverless Security Best Practices

  • ☐ Assign minimal IAM permissions per function
  • ☐ Validate and sanitize all event inputs
  • ☐ Use environment variables for non-sensitive config
  • ☐ Secrets from Secrets Manager, not env vars
  • ☐ Set memory and timeout limits
  • ☐ Enable X-Ray or distributed tracing
  • ☐ Use VPC for functions accessing internal resources

Service Mesh Security

A service mesh like Istio, Linkerd, or Consul Connect provides infrastructure-level security for service-to-service communication.

Mutual TLS (mTLS)

Automatic encryption and authentication between all services. No code changes required.

Authorization Policies

Define which services can communicate. Service A can call Service B, but not Service C.

Traffic Policies

Rate limiting, circuit breaking, and retry policies at the infrastructure level.

Observability

Automatic metrics, logs, and traces for all service-to-service calls.

Cloud Security Posture Management (CSPM)

CSPM tools continuously monitor cloud configurations to detect misconfigurations, compliance violations, and security risks.

Common Misconfigurations

  • • Public S3 buckets
  • • Security groups allowing 0.0.0.0/0
  • • Unencrypted databases
  • • Missing MFA on root accounts
  • • Overly permissive IAM policies

CSPM Tools

  • • AWS Security Hub + Config
  • • Azure Defender for Cloud
  • • GCP Security Command Center
  • • Prisma Cloud, Wiz, Orca
  • • Open source: Prowler, ScoutSuite

Infrastructure as Code Security

Shift Left

Scan IaC templates before deployment. Finding a misconfiguration in Terraform is better than finding it in production.

IaC Scanning Tools

Checkov tfsec KICS Terrascan Snyk IaC cfn-lint

Framework Alignment

NIST CSF 2.0: PR.DS (Data Security), PR.IP (Information Protection), PR.PS (Platform Security), DE.CM (Continuous Monitoring)
ISO 27002:2022: A.8.9 (Configuration Management), A.8.25 (Secure Development Lifecycle), A.8.26 (Application Security Requirements)
CIS Controls v8.1: 4 (Secure Configuration), 16 (Application Software Security), 2 (Inventory of Software Assets)
CIS Benchmarks: Docker, Kubernetes, EKS/AKS/GKE, AWS/Azure/GCP Foundations
Related: Security Frameworks → | Reference Architectures →