Cloud Native Security Model
In March 2023, Dero cryptocurrency miners hijacked thousands of Kubernetes clusters by exploiting a single misconfiguration: anonymous authentication enabled on the API server. The attackers didn't need to break container isolation or exploit application vulnerabilities. They walked straight through an open door at the cluster layer.
This attack illustrates a principle that experienced security professionals understand intuitively: security is only as strong as your weakest layer. You can run the most secure containerized application in the world, but if your cluster accepts anonymous requests, none of that container security matters.
Kubernetes security isn't about deploying a single tool or enabling a single feature. It's about understanding that your application exists within layers—each layer providing distinct protections, each layer depending on the layers surrounding it.
The 4C Model: Concentric Circles of Protection
The Cloud Native Computing Foundation (CNCF) formalizes Kubernetes security as four concentric layers, each wrapping the previous:
┌─────────────────────────────────────────────────────────────┐
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────────────────┐ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ CODE │ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └─────────────────────────┘ │ │ │
│ │ │ CONTAINER │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ CLUSTER │ │
│ └─────────────────────────────────────────────────┘ │
│ CLOUD │
└─────────────────────────────────────────────────────────────┘
Think of these layers like the walls of a castle:
| Layer | Castle Analogy | What It Protects |
|---|---|---|
| Cloud | The surrounding terrain—moats, walls, watchtowers | Infrastructure access, network perimeter, encryption keys |
| Cluster | The inner fortress—gates, guards, patrol routes | API server, node access, pod-to-pod communication |
| Container | Individual rooms with their own locks | Image integrity, runtime isolation, resource limits |
| Code | The valuables in each room—safes, sealed documents | Application logic, input validation, secrets handling |
The key principle: Outer layers must be secure before inner layers matter. A perfectly secure container means nothing if the cluster allows anonymous API access.
Layer 1: Cloud — The Infrastructure Foundation
The outermost layer is your cloud infrastructure. For Docker Desktop Kubernetes, this layer is minimal because you control the physical machine. In production cloud environments (AWS, Azure, GCP), this layer includes:
| Control | Purpose | Example |
|---|---|---|
| IAM policies | Who can access cloud resources | AWS IAM roles limiting EKS admin access |
| Network isolation | VPC boundaries and firewall rules | Separate VPCs for production and development |
| Encryption at rest | Protect stored data | AWS KMS encrypting etcd storage |
| Provider hardening | Secure cloud account configuration | Enable MFA, disable root account access |
Task API Example (Cloud Layer):
Your Task API runs on Docker Desktop Kubernetes for development. In production, you would:
- Deploy to a private subnet (not internet-facing)
- Use cloud IAM roles for Kubernetes access (not static credentials)
- Enable encryption for persistent volumes (SQLite data)
Why It Matters: If your cloud account is compromised, attackers control everything—they can delete clusters, exfiltrate data, or spin up cryptocurrency miners on your bill.
Layer 2: Cluster — The Kubernetes Control Plane
The cluster layer secures Kubernetes itself: the API server, nodes, and communication between pods.
| Control | Purpose | What It Prevents |
|---|---|---|
| RBAC | Limit who can do what | Developers can't delete production deployments |
| NetworkPolicies | Limit pod-to-pod traffic | Compromised pod can't reach database |
| API server hardening | Secure control plane | No anonymous authentication |
| Audit logging | Record all API calls | Detect suspicious activity |
| Node security | Protect worker machines | Attackers can't pivot to host |
Task API Example (Cluster Layer):
Your Task API needs cluster-layer security:
# RBAC: Task API can only read ConfigMaps (not Secrets, not Deployments)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: task-api-role
namespace: task-api
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"] # No wildcards, no create/delete
# NetworkPolicy: Only accept traffic from gateway
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: task-api-ingress
namespace: task-api
spec:
podSelector:
matchLabels:
app: task-api
ingress:
- from:
- namespaceSelector:
matchLabels:
app: envoy-gateway
ports:
- port: 8000
Why It Matters: The Dero mining attack exploited cluster-layer weaknesses. RBAC and NetworkPolicies would have stopped it.
Layer 3: Container — Runtime Isolation
The container layer protects your running application through image security and runtime constraints.
| Control | Purpose | What It Prevents |
|---|---|---|
| Image scanning | Detect vulnerabilities before deployment | Known CVEs in base images |
| Non-root execution | Limit process privileges | Container escape to host |
| Read-only rootfs | Prevent filesystem modification | Attackers can't install tools |
| Drop capabilities | Remove kernel permissions | Can't load kernel modules |
| Resource limits | Constrain CPU/memory | Denial of service attacks |
Task API Example (Container Layer):
Your Task API Deployment should include:
spec:
containers:
- name: task-api
image: ghcr.io/org/task-api:v1.0.0@sha256:abc... # Pinned digest
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
resources:
limits:
memory: "256Mi"
cpu: "500m"
Why It Matters: Container escapes are real. The runAsNonRoot and capabilities: drop: ["ALL"] settings significantly reduce attack surface.
Layer 4: Code — Your Application
The innermost layer is your application code—the logic you write and the dependencies you include.
| Control | Purpose | What It Prevents |
|---|---|---|
| Input validation | Sanitize user input | SQL injection, XSS |
| Dependency scanning | Check libraries for CVEs | Exploited vulnerabilities in packages |
| Secrets handling | Never hardcode credentials | Leaked API keys in source code |
| Error handling | Don't expose internals | Stack traces revealing system paths |
| Logging practices | Audit without leaking | Sensitive data in logs |
Task API Example (Code Layer):
Your FastAPI application should:
# Input validation using Pydantic
class TaskCreate(BaseModel):
title: str = Field(..., min_length=1, max_length=200)
description: str = Field(default="", max_length=2000)
@field_validator('title')
def sanitize_title(cls, v):
return bleach.clean(v) # Prevent XSS
# Secrets from environment (mounted from K8s Secret)
DATABASE_URL = os.environ.get("DATABASE_URL")
if not DATABASE_URL:
raise RuntimeError("DATABASE_URL not configured")
# Never log sensitive data
logger.info(f"Task created: {task.id}") # OK
# logger.info(f"Auth token: {token}") # NEVER
Why It Matters: Even with perfect infrastructure security, code vulnerabilities let attackers extract data or execute arbitrary commands.
The Leaky Bucket Principle
Imagine pouring water through four stacked buckets. Each bucket has some holes (vulnerabilities). The water (attacks) passes through any hole it finds.
Critical insight: Patching holes in the bottom bucket (Code) doesn't matter if the top bucket (Cloud) is completely missing.
| Attack Scenario | Layer It Exploits | Controls That Would Stop It |
|---|---|---|
| Stolen cloud credentials | Cloud | IAM policies, MFA, credential rotation |
| Anonymous API access | Cluster | Disable anonymous auth, require client certs |
| Vulnerable base image | Container | Image scanning, digest pinning |
| SQL injection | Code | Input validation, parameterized queries |
| Pod-to-pod attack | Cluster | NetworkPolicy default-deny |
| Container escape | Container | Non-root, dropped capabilities, seccomp |
Real-world example: The Dero attack could have been stopped at:
- Cloud: Network security groups blocking external access to API server
- Cluster: Disabling anonymous authentication
- Neither Container nor Code mattered—the attacker never needed to touch them
Applying 4C to Your Task API
Here's a complete security map for the Task API you'll secure throughout this chapter:
| Layer | Control | Status | Lesson |
|---|---|---|---|
| Cloud | Network isolation | Covered in Ch56 (Gateway API) | — |
| Cloud | Encryption at rest | Docker Desktop default | — |
| Cluster | RBAC | To implement | L02 |
| Cluster | NetworkPolicies | To implement | L03 |
| Cluster | Audit logging | Awareness | L08 |
| Container | Non-root execution | To implement | L05 |
| Container | Read-only rootfs | To implement | L05 |
| Container | Image scanning | To implement | L06 |
| Container | Digest pinning | To implement | L06 |
| Code | Input validation | From Ch40 | — |
| Code | Secrets from env | To implement | L04 |
| Code | Dependency scanning | To implement | L06 |
By Lesson 9, every row shows "Implemented" or "Covered."
Security Control Classification Exercise
Test your understanding by classifying these 10 security controls. For each, identify which layer (Cloud, Cluster, Container, or Code) it belongs to:
| # | Security Control | Your Answer |
|---|---|---|
| 1 | Disabling anonymous Kubernetes API authentication | |
| 2 | Running containers as UID 1000 instead of root | |
| 3 | Parameterized SQL queries in your Python code | |
| 4 | VPC firewall rules blocking external traffic to nodes | |
| 5 | Setting readOnlyRootFilesystem: true on pods | |
| 6 | RBAC Role limiting verbs to "get" and "list" | |
| 7 | AWS KMS encryption for EBS volumes | |
| 8 | Trivy scanning images for CVE vulnerabilities | |
| 9 | NetworkPolicy blocking all ingress except from gateway | |
| 10 | Pydantic validation on API request bodies |
Click to reveal answers
| # | Security Control | Layer | Explanation |
|---|---|---|---|
| 1 | Disabling anonymous API authentication | Cluster | API server configuration |
| 2 | Running containers as UID 1000 | Container | Runtime isolation |
| 3 | Parameterized SQL queries | Code | Application logic |
| 4 | VPC firewall rules | Cloud | Infrastructure networking |
| 5 | readOnlyRootFilesystem: true | Container | Pod security context |
| 6 | RBAC Role with limited verbs | Cluster | Kubernetes authorization |
| 7 | AWS KMS for EBS volumes | Cloud | Cloud provider encryption |
| 8 | Trivy scanning | Container | Image security |
| 9 | NetworkPolicy for ingress | Cluster | Pod-to-pod traffic rules |
| 10 | Pydantic validation | Code | Application input handling |
Score yourself: 9-10 correct = Excellent. 7-8 = Good. Below 7 = Review the layer definitions above.
Reflect on Your Skill
In Lesson 0, you created a cloud-security skill. Now evaluate it against the 4C model:
Questions to consider:
- Does your skill understand all four layers, or does it focus only on some?
- When you ask for security recommendations, does it start with outer layers first?
- Does it explain why a control belongs to a specific layer?
Try this test:
Using my cloud-security skill, I need to secure a new
FastAPI application on Kubernetes. What security controls
should I implement at each of the 4C layers?
If your skill:
- Lists controls for all four layers: It understands the 4C model
- Prioritizes Cloud and Cluster before Container and Code: It understands dependency ordering
- Explains why controls belong where they do: It can teach, not just list
What's missing? Make a note. You'll improve your skill throughout this chapter.
Try With AI
Prompt 1: Attack Path Analysis
I run a FastAPI application on Kubernetes with these security controls:
- Image is scanned with Trivy (no HIGH/CRITICAL CVEs)
- Container runs as non-root user
- Application validates all inputs with Pydantic
But I have NOT configured:
- RBAC (using default service account)
- NetworkPolicies (pods can talk to anything)
Help me understand: What attack could succeed despite my Container
and Code security? Walk me through the path an attacker would take.
What you're learning: The dependency between layers—how ignoring Cluster security undermines Container and Code protections.
Prompt 2: Layer Classification Practice
I'm learning the 4C security model. Here are security controls
I'm considering. Help me classify each one and explain your reasoning:
1. Setting memory limits on containers
2. Enabling TLS for API endpoints
3. Rotating service account tokens every 24 hours
4. Using distroless base images
5. Implementing rate limiting in application code
For each, tell me: What layer? Why? What happens if I skip it?
What you're learning: Layer classification isn't always obvious—some controls span layers or could be implemented at multiple layers.
Prompt 3: Task API Security Planning
I'm building a task management API with FastAPI, SQLite for storage,
and Dapr for state management. I will deploy it on Docker Desktop
Kubernetes for development and AWS EKS for production.
Using the 4C model, help me create a security checklist. For each
layer, tell me: What's the biggest risk? What control addresses it?
What's the minimum viable security for development vs production?
What you're learning: Practical application of 4C to your specific context—balancing security rigor with development velocity.
The 4C model is a framework for understanding, not a guarantee of security. Implementing controls at every layer is necessary but not sufficient. Security requires ongoing monitoring, patching, and threat modeling. Start with the outer layers (Cloud, Cluster) before investing in inner layers (Container, Code).